/*--------------------------------------------------------------------------
  Project:  Manual 2D Library - m2d
  File:     lyt_arcResourceAccessor.cpp

  Copyright (C)2007-2009 Nintendo  All Rights Reserved.

  These coded instructions, statements, and computer programs contain
  proprietary information of Nintendo of America Inc. and/or Nintendo
  Company Ltd., and are protected by Federal copyright law.  They may
  not be disclosed to third parties or copied or duplicated in any form,
  in whole or in part, without the prior written consent of Nintendo.

  $Revision: 1.16 $
 *-------------------------------------------------------------------------*/

#include <nnsys/misc.h>
#include <ntmv/m2d/arcResourceAccessor.h>
#include <cstring>
#include <extras_string.h>

namespace ntmv
{
namespace m2d
{

namespace
{

void
GetResourceTypeString(
    char    buf[],
    ResType resType
)
{
    buf[0] = char(resType >> 24);
    buf[1] = char(resType >> 16);
    buf[2] = char(resType >>  8);
    buf[3] = char(resType >>  0);
    buf[4] = '\0';
}

void
GetLanguageString(
    char    buf[],
    u16     lang
)
{
    buf[0] = char(lang >>  8);
    buf[1] = char(lang >>  0);
    buf[2] = '\0';
}

void*
GetResourceSub(
    char*               pathBuf,
    u32                 pathBufSize,
    const char*         resRootDir,
    ResType             resType,
    const char*         name
)
{
    NNS_ASSERT(resType != 0);   // The resource type cannot be omitted

    char resTypeStr[5];
    GetResourceTypeString(resTypeStr, resType);

    STD_TSNPrintf(pathBuf, pathBufSize, "%s/%s/%s", resRootDir, resTypeStr, name);

    return NNS_FndGetArchiveFileByName(pathBuf);
}

void*
GetLocalizeResourceSub(
    char*               pathBuf,
    u32                 pathBufSize,
    const char*         resRootDir,
    ResType             resType,
    u16                 lang,
    const char*         name
)
{
    NNS_ASSERT(resType != 0);   // The resource type cannot be omitted

    char resTypeStr[5];
    GetResourceTypeString(resTypeStr, resType);

    char langStr[3];
    GetLanguageString(langStr, lang);

    STD_TSNPrintf(pathBuf, pathBufSize, "%s/%s/%s/%s", resRootDir, resTypeStr, langStr, name);

    return NNS_FndGetArchiveFileByName(pathBuf);
}

}   // namespace

/*---------------------------------------------------------------------------*
  Name:         ArcResourceAccessor::ArcResourceAccessor

  Description:  Constructor

  Arguments:    None.

  Returns:      None.
 *---------------------------------------------------------------------------*/
ArcResourceAccessor::ArcResourceAccessor()
:   mLang(0),
    mbAttached(false)
{
}

/*---------------------------------------------------------------------------*
  Name:         ArcResourceAccessor::Attach

  Description:  Registers the archive data.

  Arguments:    archive Start:           Pointer to the archive data.
                resourceRootDirectory:  The name of the directory that is the root for resource searches.

  Returns:      Returns TRUE if registration succeeds; otherwise, returns FALSE.
 *---------------------------------------------------------------------------*/
bool
ArcResourceAccessor::Attach(
    const char*     resourceRootDirectory
)
{
    NNS_ASSERT(! IsAttached());
    NNS_NULL_ASSERT(resourceRootDirectory);

    mbAttached = true;
    // copy the root directory string
    STD_CopyLString(mResRootDir, resourceRootDirectory, ROOTPATH_MAX);

    return true;
}

/*---------------------------------------------------------------------------*
  Name:         ArcResourceAccessor::Detach

  Description:  Clears the registration for the registered archive data.

  Arguments:    None.

  Returns:      A pointer to the registered archive data.
 *---------------------------------------------------------------------------*/
void*
ArcResourceAccessor::Detach()
{
    NNS_ASSERT(IsAttached());

    mbAttached = false;
    return 0;
}

/*---------------------------------------------------------------------------*
  Name:         ArcResourceAccessor::GetResource

  Description:  Searches for a resource with the specified resource name from an archive, and returns that resource's starting address.
                

  Arguments:    resType:  The resource type.
                name:     The pointer to the resource name.

  Returns:      Returns the start address for the resource when it is found.
 *---------------------------------------------------------------------------*/
void*
ArcResourceAccessor::GetResource(
    ResType     resType,
    const char* name
)
{
    return GetResourceSub(mPathBuf, sizeof(mPathBuf), mResRootDir, resType, name);
}

/*---------------------------------------------------------------------------*
  Name:         ArcResourceAccessor::GetLocalizeResource

  Description:  Searches for a resource with the specified resource name from an archive, and returns that resource's starting address.
                

                When SetLanguage has been used to set the language, that language's folder will be searched for the resource.
                

  Arguments:    resType:  The resource type.
                Name:     The pointer to the resource name.

  Returns:      Returns the start address for the resource when it is found.
 *---------------------------------------------------------------------------*/
void*
ArcResourceAccessor::GetLocalizeResource(
    ResType     resType,
    const char* name
)
{
    return mLang != 0 ?
        GetLocalizeResourceSub(mPathBuf, sizeof(mPathBuf), mResRootDir, resType, mLang, name):
        GetResourceSub(mPathBuf, sizeof(mPathBuf), mResRootDir, resType, name);

}

/*---------------------------------------------------------------------------*
  Name:         ArcResourceAccessor::SetLanguage

  Description:  Sets the language to use in GetLocalizeResource().

  Arguments:    lang: The ISO 639 language code (two alphabetic characters) should be listed in the upper and lower bytes.
                      

  Returns:      None.
 *---------------------------------------------------------------------------*/
void
ArcResourceAccessor::SetLanguage(u16 lang)
{
    mLang = lang;
}

/*---------------------------------------------------------------------------*
  Name:         ArcResourceAccessor::Exists

  Description:  Determines whether the file exists.

  Arguments:    resType:  The resource type.
                lang:     The ISO 639 language code (two alphabetic characters) should be listed in the upper and lower bytes.
                          
                name:     The pointer to the resource name.

  Returns:      None.
 *---------------------------------------------------------------------------*/
bool
ArcResourceAccessor::Exists(
    ResType     resType,
    u16         lang,
    const char* name
)
{
    void *const resPtr = lang != 0 ?
        GetLocalizeResourceSub(mPathBuf, sizeof(mPathBuf), mResRootDir, resType, lang, name):
        GetResourceSub(mPathBuf, sizeof(mPathBuf), mResRootDir, resType, name);

    return 0 != resPtr;
}

}   // namespace m2d
}   // namespace ntmv
