#pragma once

#include "kpi.h"
#include "snesapu.dll/SNESAPU.H"

#pragma pack(push, 1)
struct ID666_TEXT
{
    char title[32];
    char game[32];
    char dumper[16];
    char comment[32];
    char date[11]; //MM/DD/YYYY
    char length[3];
    char fade[5];
    char artist[32];
    BYTE channel;
    BYTE emulator;
    BYTE reserved[45];
};
struct ID666_BIN
{
    char  title[32];
    char  game[32];
    char  dumper[16];
    char  comment[32];
    DWORD dwDate;//YYYYMMDD
    BYTE  unused[7];
    BYTE  length[3];
    DWORD dwFade;
    char  artist[32];
    BYTE  channel;
    BYTE  emulator;
    BYTE  reserved[46];
};
struct XID6_SUBCHUNK
{
    BYTE id;
    BYTE type;
    WORD length;
    //BYTE data[];
};
struct SPCDATA
{
    BYTE header[33]; //"SNES-SPC700 Sound File Data v0.30"
    BYTE Ox1AOx1A[2];//0x1A, 0x1A
    BYTE id666_contain;//0x1A = header contains ID666 information
                       //0x1B = header contains no ID666 tag
    BYTE version;
    struct
    {
        WORD PC;  //APURegisters.PC
        BYTE YABA;//APURegisters.YA.B.A
        BYTE X;   //APURegisters.X
        BYTE YABY;//APURegisters.YA.B.Y
        BYTE P;   //APURegisters.P
        BYTE S;   //APURegisters.S
        BYTE reserved[2];//
    }APURegisters;
    union
    {
        ID666_TEXT text;
        ID666_BIN  bin;
    }id666;
    BYTE APURAM[65536];  //64KB RAM
    BYTE DSPRAM[128];    //DSP Registers
    BYTE unused[64];
    BYTE APUExtraRAM[64];//Extra RAM (Memory region used when the 
                         //IPL ROM region is set to read-only)
};
#pragma pack(pop)

class KbId666
{
private:
    union
    {
        ID666_TEXT text;
        ID666_BIN  bin;
    }m_id666;
    BOOL   m_bIsBinary;
    BYTE  *m_pXid6;
    DWORD  m_dwXid6Size;
    struct ID666_LENGTHINFO
    {
        DWORD dwLength;//ms
        DWORD dwFade;  //ms
    }m_id666_length;
    struct XID6_LENGTHINFO
    {
        DWORD dwIntro; //tick
        DWORD dwFade;  //tick
        DWORD dwLoop;  //tick
        INT32 nEnd;    //tick(負の値も可だが書き込めるツールがない?)
        DWORD dwLoopCount;
        DWORD dwAmp;   //Amplification値(36h)
    }m_xid6_length;
public:
    ID666_TEXT *GetId666Text(void){return !m_bIsBinary ? &m_id666.text : NULL;}
    ID666_BIN  *GetId666Bin(void){return m_bIsBinary ? &m_id666.bin : NULL;}
    KbId666(void);
    ~KbId666(void);
    BOOL  __fastcall Open(IKpiFile *pFile);
    void  __fastcall ReadId666(IKpiTagInfo *pTagInfo, DWORD dwTagGetFlags);
    void  __fastcall ReadXid6(IKpiTagInfo *pTagInfo, DWORD dwTagGetFlags);
    void  __fastcall GetTagInfo(IKpiTagInfo *pTagInfo, DWORD dwTagGetFlags);
    UINT64 __fastcall GetLength(void);
    UINT64 __fastcall GetFade(void);
    UINT64 __fastcall GetLoop(void);
    INT64  __fastcall GetEnd(void);
    DWORD  __fastcall GetLoopCount(void);
    DWORD  __fastcall GetAmp(void);
};

