#pragma once
//GcaSDK を利用するラッパー
//クラスのメソッドで STL を使わないようにして DLL 化することで
//VC6 以外からでも使えるようにする(DLL は VC6 で作成するしかないが)
//このクラスを使用する際に GcaSDK.h はインクルード不要

//CreateGca の version に渡す値
//IGca のインターフェースが変わったら値を変更する
#define IGCA_INTERFACE_VERSION 1

namespace nsIGca{
//以下の2つは GcaSDK ではグローバルに定義されるが IGca のメンバ関数として実装
//DWORD GetStartOffset(const string& strPathName);
//BOOL  GetSpellFromKeyFile(string &strSpell, const string &strKeyFile);

const int GCAM_OK        = 0;
const int GCAM_CANCEL    = 1;
const int nREPORT  =  4 << 24;
const int nWARNING =  8 << 24;
const int nERROR   = 12 << 24;
const int nQUERY   = 16 << 24;
const int nBEGIN   =  2 << 16;
const int nEND     =  3 << 16;
const int nENCODE  =  4 << 16;
const int nDECODE  =  8 << 16;
const int nEXIST   = 12 << 16;
const int nOPEN    = 16 << 16;
const int nCLOSE   = 20 << 16;
const int nREAD    = 24 << 16;
const int nWRITE   = 28 << 16;
const int nCRC     = 32 << 16;
const int nCRYPTO  = 36 << 16;
const int nCREATE  = 40 << 16;
const int nUNKNOWN_FORMAT = 128 << 16;
const int nANALYZE_SOLID  = 132 << 16;
const int nARC     =  4 << 8;
const int nFILE    =  8 << 8;
const int nDIRECTORY = 12 << 8;

const int GCAM_FILE_ENCODE_BEGIN  = nFILE | nENCODE | nBEGIN | nREPORT;
const int GCAM_FILE_ENCODE_END    = nFILE | nENCODE | nEND   | nREPORT;
const int GCAM_FILE_DECODE_BEGIN  = nFILE | nDECODE | nBEGIN | nREPORT;
const int GCAM_FILE_DECODE_END    = nFILE | nDECODE | nEND   | nREPORT;

const int GCAM_ARC_UNKNOWN_FORMAT = nARC  | nUNKNOWN_FORMAT  | nERROR;
const int GCAM_ARC_ANALYZE_SOLID  = nARC  | nANALYZE_SOLID   | nWARNING;

const int GCAM_FILE_EXIST         = nFILE | nEXIST | nQUERY;
const int GCAM_FILE_OPEN_ERROR    = nFILE | nOPEN  | nERROR;

const int GCAM_ARC_READ_ERROR     = nARC  | nREAD  | nERROR;
const int GCAM_FILE_READ_ERROR    = nFILE | nREAD  | nERROR;
const int GCAM_ARC_WRITE_ERROR    = nARC  | nWRITE | nERROR;
const int GCAM_FILE_WRITE_ERROR   = nFILE | nWRITE | nERROR;

const int GCAM_ARC_CRC_ERROR      = nARC  | nCRC   | nERROR;
const int GCAM_FILE_CRC_ERROR     = nFILE | nCRC   | nERROR;

const int GCAM_ARC_CRYPTO_ERROR   = nARC  | nCRYPTO | nERROR;
const int GCAM_FILE_CRYPTO_ERROR  = nFILE | nCRYPTO | nERROR;
const int GCAM_ARC_CRYPTO         = nARC  | nCRYPTO | nREPORT;
const int GCAM_FILE_CRYPTO        = nFILE | nCRYPTO | nREPORT;

const int GCAM_DIRECTORY_CREATE_ERROR = nDIRECTORY | nCREATE | nERROR;

class IGca
{
public:
    typedef unsigned __int64 QWORD;
	enum ArcType{ GCA0 = 0, GCA1, };//CGca::GCA0, CGca::GCA1 の代わり
    //以下の2つは IGca のメンバ関数として実装
    virtual DWORD WINAPI GetStartOffset(const char* strPathName)=0;
    virtual BOOL WINAPI GetSpellFromKeyFile(char* pstrSpell, int size, const char* strKeyFile)=0;
    //↑戻り値の pstrSpell の長さは 40 固定のようなので size は 41 以上あれば十分と思われる

    //CGca と共通のメソッド(圧縮関係を除く)
    virtual BOOL WINAPI Init(void)=0;
	virtual void WINAPI Free(void)=0;
	virtual void WINAPI SetArcFilePath(const char* strArcFilePath)=0;
	virtual void WINAPI SetOutputPath(const char* strOutputPath)=0;
	virtual void WINAPI SetRestoreDirectory(BOOL bRestoreDirectory)=0;
	virtual void WINAPI SetCrypto(BOOL bCrypto)=0;
	virtual void WINAPI SetSpell(const char* strSpell)=0;
    virtual void WINAPI SetStartOffset(int nStartOffset)=0;
    virtual void WINAPI SetProgressProc(BOOL (*pfnProgress)(QWORD, QWORD, PVOID))=0;
    virtual void WINAPI SetMessageProc(int (*pfnMessage)(int, const char *, PVOID))=0;
	virtual int WINAPI GetArcType(void)=0;
	virtual int WINAPI GetNumFiles(void)=0;
    virtual void  WINAPI GetFileName(int n, char *pszFileName, int size)=0;
    //↑ファイル名なので size は MAX_PATH*2 以上あれば十分と思われる
	virtual DWORD WINAPI GetFileCRC(int n)=0;
	virtual QWORD WINAPI GetDataSize(int n)=0;
	virtual QWORD WINAPI GetFileSize(int n)=0;
	virtual DWORD WINAPI GetFileAttributes(int n)=0;
	virtual FILETIME WINAPI GetFileTime(int n)=0;
	virtual BOOL WINAPI OpenArchive(void)=0;
	virtual BOOL WINAPI CloseArchive(void)=0;
	virtual BOOL WINAPI Extract(void)=0;
	virtual BOOL WINAPI ExtractFile(int n)=0;
	virtual BOOL WINAPI ExtractFileToMemory(int n, BYTE *pBuffer)=0;
	virtual void WINAPI SetUser(DWORD dwUser)=0; 
	virtual DWORD WINAPI GetUser(void)=0;

    //圧縮関係(機能しない)(GCA SDK が Archive() 未実装なので)		
	virtual void WINAPI SetOrder(const char** astrOrder)=0;
	virtual void WINAPI SetCompress(BOOL bCompress)=0;
	virtual void WINAPI SetArcType(int nType)=0;
    virtual BOOL WINAPI Archive(void)=0; //GCA SDK が未実装なので常に FALSE を返す
    //圧縮関係ここまで

    //IGca 専用
    virtual void WINAPI Release(void)=0;
};

typedef IGca* (WINAPI *pfnCreateGca)(int version);
//extern "C" IGca* WINAPI CreateGca(int version);//version には IGCA_INTERFACE_VERSION を渡すこと

}
using namespace nsIGca;
