/*--------------------------------------------------------------------------
  Project:  Manual 2D Library - m2d
  File:     common.h

  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.38 $
 *-------------------------------------------------------------------------*/

#ifndef NTMV_M2D_COMMON_H_
#define NTMV_M2D_COMMON_H_

#if defined(__CWCC__)
#pragma once
#endif

#include <nnsys/fnd.h>
#include <ntmv/m2d/debug.h>
#include <ntmv/m2d/inlines.h>
#include <ntmv/m2d/manualPageResource.h>

struct NNSG2dPaletteData;

namespace ntmv
{
namespace m2d
{

struct Color;
struct Rect;
struct Size;
class DrawInfo;
class ResourceAccessor;
class TexMap;
struct TextureList;

struct ResBlockSet
{
    ResourceAccessor*           pResAccessor;
    const res::NameBlock*       pNameBlock;
    const res::TextBlock*       pTextBlock;
    const TextureList*          pTextureList;
};

namespace detail
{

struct TextureFlipInfo
{
    s8      coords[2];
    s8      dir[2];
    u8      swap;

};

#if !defined(NTMV_M2D_USE_DIRECTTEXTURE)
/*
    Class to pick up texels
*/
class TexelPicker
{
public:
    static TexelPicker* Create(
                            TexelPicker*    pTexelPicker,
                            const TexMap*   pTexMap);

                        TexelPicker()
                        :   mpImage(0),
                            mpPalette(0),
                            mHStrideBytes(0),
                            mbHasAlphaPal(false)
                        {}

    virtual u16         Get(Point pt) const;

protected:
    const void*         mpImage;
    const u16*          mpPalette;
    Size                mTexSize;
    u32                 mHStrideBytes;
    bool                mbHasAlphaPal;
};

/*
    Class to pick up texels from a texture in the Direct format.
    NOTE: You cannot add member variables.
*/
class DirectTexelPicker : public TexelPicker
{
public:
                        DirectTexelPicker(const TexMap* pTexMap);

    virtual u16         Get(Point pt) const;
};

/*
    Class to pick up texels from a texture in 256-color palette format.
    NOTE: You cannot add member variables.
*/
class Palette256TexelPicker : public TexelPicker
{
public:
                        Palette256TexelPicker(const TexMap* pTexMap);

    virtual u16         Get(Point pt) const;
};
#endif  // #if !defined(NTMV_M2D_USE_DIRECTTEXTURE)

inline s32
GetSignatureInt(const char sig[4])
{
    return (sig[0] << 24) | (sig[1] << 16) | (sig[2] << 8) | sig[3];
}

bool            TestFileHeader(const res::BinaryFileHeader& fileHeader, u32 testSig);

inline
bool
TestFileVersion(const res::BinaryFileHeader& fileHeader)
{
    // Make processing possible only if the major version is the same and the minor version is less than or equal to the expected version.
    // 
    const u32 majorVer = BitExtract(fileHeader.version, 8, 8);
    const u32 minorVer = BitExtract(fileHeader.version, 0, 8);
    bool ret =
           majorVer == res::FileBinaryFileFormatMajorVersion
        &&  (   minorVer >= res::FirstBinaryFileFormatMinorVersion
            &&  minorVer <= res::LatestBinaryFileFormatMinorVersion
            );

    NTMV_WARNING(
        ret,
        "Version check failed. library ver. '%d.%d', file ver. '%d.%d').",
            res::FileBinaryFileFormatMajorVersion,
            res::FirstBinaryFileFormatMinorVersion,
            majorVer,
            minorVer);

    return ret;
}

inline const char*
GetNamePoolStr(const u32 offsetTable[], int index)
{
    return detail::ConvertOffsToPtr<const char>(offsetTable, offsetTable[index]);
}

inline const wchar_t*
GetTextPoolStr(const u32 offsetTable[], int index)
{
    return detail::ConvertOffsToPtr<const wchar_t>(offsetTable, offsetTable[index]);
}

void            FillColor(
                    const DrawInfo& drawInfo,
                    Point           pt,
                    Size            size,
                    GXRgb           color);

const Rect      GetDrawRect(
                    const Point             pt,
                    const Size              texSz,
                    const Rect&             canvasRect);

u16*            GetLineBuf(
                    const DrawInfo& drawInfo,
                    s16             y);

const u16*      GetLineBuf(
                    const TexMap&   texMap,
                    s16             y);

const TextureFlipInfo&
                GetTexutreFlipInfo(u8 textureFlip);

void            GetTexCoord(
                    Point&                  texCd,
                    const Size&             texSize,
                    const TextureFlipInfo&  flipInfo);

void            DrawImage(
                    const DrawInfo& drawInfo,
                    Point           myPt,
                    const TexMap&   texMap);

void            DrawImage(
                    const DrawInfo&         drawInfo,
                    const Point             pt,
                    const Size              size,
                    const TexMap&           texMap,
                    const Point             texCd,
                    const TextureFlipInfo&  flipInfo);

void            DrawSelectImage(
                    const DrawInfo&         drawInfo,
                    const Point             pt,
                    const Size              size,
                    const TexMap&           texMap,
                    const Point             texCd,
                    const TextureFlipInfo&  flipInfo);

inline
u8
GetHorizontalPosition(u8 var)
{
    return static_cast<u8>(var & ((1 << 4) - 1));
}

inline
u8
GetVerticalPosition(u8 var)
{
    return static_cast<u8>(var >> 4);
}

u8                  GetOwnerFavoriteColor();

void*               LoadFile(
                        const char*         filePath,
                        NNSFndAllocator*    pAllocator,
                        u32                 align       = 4,
                        u32*                pFileBytes  = 0);

void*               LoadBLZFile(
                        const char*         filePath,
                        NNSFndAllocator*    pAllocator,
                        u32                 align           = 4,
                        u32*                pExtractBytes   = 0);

}   // namespace detail

}   // namespace m2d
}   // namespace ntmv

/* NTMV_M2D_COMMON_H_ */
#endif
