//CFTTTexture - [2020-04-13 11:57:46]
#ifndef _CFTTTEXTURE_H_
#define _CFTTTEXTURE_H_

#include "CFTTVector32x4.h"
#include "CFTTTexLoadOptions.h"
#include "CFTTFile.h"
#include <GLES2/gl2.h>

/*
00222034 CFTTTexture::CFTTTexture()
00222070 CFTTTexture::~CFTTTexture()
0022208C CFTTTexture::~CFTTTexture()
00222090 CFTTTexture::AddFileHandler(TFTTTexture_FileHandler *)
002220CC CFTTTexture::DetermineBestTextureFile(char const*,char *,int)
00222128 CFTTTexture::OpenBestTextureFile(char const*,TFTTTexture_FileHandler **)
002221EC CFTTTexture::BufferCheckFormat(void const*,int,TFTTTexture_FileHandler const**)
00222224 CFTTTexture::FileIsValid(char const*)
00222278 CFTTTexture::FileExists(char const*,bool)
002222D4 CFTTTexture::LoadBuffer(void const*,int,CFTTTexLoadOptions const&,TFTTTexture_FileHandler const*)
00222324 CFTTTexture::LoadName(char const*,CFTTTexLoadOptions const&,bool)
002223F8 CFTTTexture::SaveName(char const*,EFTTTextureSaveQuality,EFTTRendererType)
00222474 CFTTTexture::CanSaveName(char const*,int *,int *,char *,int)
00222528 CFTTTexture::RenderSaveCube(char const*,bool,CFTTVector32x4)
00222860 CFTTTexture::SplitCube()
002228DC CFTTTexture::SaveCube(char const*)
0022294C CFTTTexture::ResetAllFlags(int)
0022295C CFTTTexture::ApplyTexLoadOptions(CFTTTexLoadOptions const&)
00222994 CFTTTexture::AddFlags(int)
002229AA CFTTTexture::RemoveAlpha()

                                      CFTTTexture
                                      /         \
                                     /           \
                      CFTTTextureVulkan       CFTTTextureOGLES

vptr_CFTTTextureVulkan_328B80:
  destructor_CFTTTexture
  destructor_CFTTTexture2
  GetDataSize()
  GetPixel(int,int)
  GetPixelMip(int,int,int)
  LoadPixel(uchar *,int)
  StorePixel(uchar *,uint,int)
  SetPixelARGB(uint,int,int)
  RebuildMipMaps(EFTTTex_MipGenFilter)
  FreeLocalTextureData()
  SetMinFilter(EFTTTex_MinFilter)
  SetMagFilter(EFTTTex_MagFilter)
*/

enum EFTTTextureType {
  EFTTTextureType_0,
  EFTTTextureType_1,
  EFTTTextureType_2,
  EFTTTextureType_3,
  EFTTTextureType_4,
  EFTTTextureType_5,
  EFTTTextureType_6,
  EFTTTextureType_7,
  EFTTTextureType_8,
  EFTTTextureType_9,
  EFTTTextureType_10,
  EFTTTextureType_11,
  EFTTTextureType_12,
  EFTTTextureType_13,
  EFTTTextureType_14,
  EFTTTextureType_15,
  EFTTTextureType_16,
  EFTTTextureType_17,
  EFTTTextureType_18,
  EFTTTextureType_19,
  EFTTTextureType_20,
  EFTTTextureType_21,
  EFTTTextureType_22,
  EFTTTextureType_23,
  EFTTTextureType_24,
};

enum EFTTRendererType {
  EFTTRendererType_0,
  EFTTRendererType_1,
  EFTTRendererType_2,
  EFTTRendererType_3,
  EFTTRendererType_4,
  EFTTRendererType_5
};

enum EFTTDummyTexture {
  EFTTDummyTexture_0,
  EFTTDummyTexture_1,
  EFTTDummyTexture_2,
  EFTTDummyTexture_3,
  EFTTDummyTexture_4,
  EFTTDummyTexture_5,
  EFTTDummyTexture_6,
};

enum EFTTTex_MipGenFilter {
  EFTTTex_MipGenFilter_UNK = -1,
  EFTTTex_MipGenFilter_0,
  EFTTTex_MipGenFilter_1,
  EFTTTex_MipGenFilter_2,
  EFTTTex_MipGenFilter_3,
  EFTTTex_MipGenFilter_4,
};

enum EFTTTextureSaveQuality {
  EFTTTextureSaveQuality_0,
  EFTTTextureSaveQuality_1,
  EFTTTextureSaveQuality_2,
  EFTTTextureSaveQuality_3,
  EFTTTextureSaveQuality_4,
};

class CFTTTexture;

typedef bool (*FileHandler_Is)(void const *pData, int dLen);  //传入的数据是不是某种类型，如ftc
typedef CFTTTexture *(*FileHandler_Load)(const void *pData, int dLen, CFTTTexLoadOptions const &pTexLoadOptions);
typedef bool (*FileHandler_Save)(CFTTTexture *pTexture, const char *pFileName, EFTTTextureSaveQuality a3, EFTTRendererType a4);
typedef bool (*FileHandler_CanSave)(CFTTTexture *pTexture);

struct TFTTTexture_FileHandler {
  const char *pSuffix_0;  //suffix name
  int dIndex_4;
  FileHandler_Is fun_Is_8;             //IsFtc      00229D10  IsFtc(const void *, int)
  FileHandler_Load fun_Load_C;         //LoadFtc    0022A02C  LoadFtc(const void *, int, const CFTTTexLoadOptions *)
  FileHandler_Save fun_Save_10;        //SaveFtc    0022A45C  SaveFtc(CFTTTexture *, char const*, EFTTTextureSaveQuality, EFTTRendererType)
  FileHandler_CanSave fun_CanSave_14;  //CanSaveFtc 0022A460  CanSaveFtc(CFTTTexture *, int *, int *, char *, int)
  TFTTTexture_FileHandler *next_18;
};

int GetBPP(EFTTTexFormat);
int GetFullMipChainCount(int width, int height, EFTTTexFormat eFormat);

class CFTTTexture {
public:
  CFTTTexture();
  virtual ~CFTTTexture();
  virtual int GetDataSize() const = 0;
  virtual uchar *GetPixel(int, int) = 0;
  virtual int GetPixelMip(int, int, int) = 0;
  virtual int LoadPixel(uchar *, int) = 0;
  virtual void StorePixel(uchar *, uint, int) = 0;
  virtual void SetPixelARGB(uint, int, int) = 0;
  virtual void RebuildMipMaps(EFTTTex_MipGenFilter) = 0;
  virtual void FreeLocalTextureData() = 0;
  virtual void SetMinFilter(EFTTTex_MinFilter) = 0;
  virtual void SetMagFilter(EFTTTex_MagFilter) = 0;

  static void AddFileHandler(TFTTTexture_FileHandler *pFileHandler);  //00222090
  static TFTTTexture_FileHandler *DetermineBestTextureFile(char const *pDat,
                                                           char *pOut,
                                                           int dOutLen);  //002220CC
  static CFTTFile *OpenBestTextureFile(char const *pFileName,
                                       TFTTTexture_FileHandler **ppFileHandler);       //00222128
  static bool BufferCheckFormat(void const *, int, TFTTTexture_FileHandler const **);  //002221EC
  static bool FileIsValid(char const *pFileName);                                      //00222224
  static bool FileExists(char const *, bool);                                          //00222278
  static CFTTTexture *LoadBuffer(void const *,
                                 int,
                                 CFTTTexLoadOptions const &,
                                 TFTTTexture_FileHandler const *);               //002222D4
  static CFTTTexture *LoadName(char const *, CFTTTexLoadOptions const &, bool);  //00222324
  bool SaveName(char const *, EFTTTextureSaveQuality, EFTTRendererType);         //002223F8
  bool CanSaveName(char const *, int *, int *, char *, int);                     //00222474
  void RenderSaveCube(char const *, bool, CFTTVector32x4);                       //00222528
  int SplitCube();                                                               //00222860
  void SaveCube(char const *);                                                   //002228DC
  void ResetAllFlags(int);                                                       //0022294C
  void ApplyTexLoadOptions(CFTTTexLoadOptions const &);                          //0022295C
  void AddFlags(int);                                                            //00222994
  void RemoveAlpha();                                                            //002229AA

  uint16 width_4;
  uint16 height_6;
  uint16 width_8;
  uint16 height_A;
  int dCount_C;  //glTexStorage2D levels //00224D84   LDR.W           R1, [R9,#0xC]
  EFTTTexFormat eFormat_10;
  bool bFlag_14;  //true -> 已分配 pData_18 的内存
  //uchar byte_15;
  //uchar byte_16;
  //uchar byte_17;
  uchar *pData_18;
  GLuint textures_1C;
  EFTTTextureType eTextureType_20;
  //volatile int flag_24;
  int8 flag_24;
  EFTTTex_MinFilter eMinFilter_28;
  EFTTTex_MagFilter eMagFilter_2C;

  static TFTTTexture_FileHandler *ms_pFileHandlers;
};

#endif  //_CFTTTEXTURE_H_