#ifndef CLASS_IMGFILE_H
#define CLASS_IMGFILE_H

#include "cFileObj.h"
#include "../dxtlib/dxtutility.h"

/*
#ifdef _DEBUG
  #pragma comment(lib, "FilePackage\\dxtlib\\dxtlib_d.lib")
#else
  #pragma comment(lib, "FilePackage\\dxtlib\\dxtlib.lib")
#endif */ /*_DEBUG*/

#define RGBToR5G6B5(r,g,b) (WORD) (((r) & 0xF8) << 8 | ((g) & 0xFC) << 3 | ((b) & 0xF8) >> 3)
#define RGBToR5G5B5(r,g,b) (WORD) (((r) & 0xF8) << 7 | ((g) & 0xF8) << 2 | ((b) & 0xF8) >> 3)

enum ImageFormat
{
	IMAGE_UNKNOWN		= 0,

	IMAGE_R5G6B5,
	IMAGE_A1R5G5B5,
	IMAGE_R8G8B8,
	IMAGE_A8R8G8B8,

	IMAGE_DXT1,
	IMAGE_DXT1a,
	IMAGE_DXT3,
	IMAGE_DXT5,
};

enum
{
	IMGFILE_ROP_OVERLAY		= DXT_ROP_OVERLAY,
	IMGFILE_ROP_SELECTSRC	= DXT_ROP_SELECTSRC,	
	IMGFILE_ROP_ADD			= DXT_ROP_ADD,			// 未實做,有空在撰寫
	IMGFILE_ROP_LAST,
};

// 載入圖形檔案時的參數設定
typedef struct ReadImageOptions
{
	ReadImageOptions()
	{
		fmt = IMAGE_DXT5;
		mipmapBool = false;
	};

	ImageFormat fmt;				// 指定圖形格式
	bool mipmapBool;				// 是否做MIPMAP處理
}ReadImageOptions;

inline bool IsDXTFormat( ImageFormat format )
{
	if ( format == IMAGE_DXT1 ) return true;
	else if ( format == IMAGE_DXT1a ) return true;
	else if ( format == IMAGE_DXT3 ) return true;
	else if ( format == IMAGE_DXT5 ) return true;
	return false;
}

inline int GetPower2(int size)
{
	int pow = (size > 0) ? 1 : 0;
	for ( ; pow < size; pow <<= 1 ) ;
	return pow;
}

inline bool IsImageFile( const TCHAR *fileNameStr )
{
	if ( fileNameStr == NULL ) return false;
	int len = lstrlen( fileNameStr );
	if ( len < 4 ) return false;
	if ( lstrcmpi( &fileNameStr[len - 4], _T(".BMP") ) == 0 ) return true;
	//else if ( lstrcmpi( &fileNameStr[len - 4], _T(".GIF") ) == 0 ) return true;
	else if ( lstrcmpi( &fileNameStr[len - 4], _T(".JPG") ) == 0 ) return true;
	else if ( lstrcmpi( &fileNameStr[len - 4], _T(".PCX") ) == 0 ) return true;
	else if ( lstrcmpi( &fileNameStr[len - 4], _T(".PNG") ) == 0 ) return true;
	else if ( lstrcmpi( &fileNameStr[len - 4], _T(".TGA") ) == 0 ) return true;
	else if ( lstrcmpi( &fileNameStr[len - 4], _T(".DDS") ) == 0 ) return true;
	return false;
}

class cImgFile : public cFileObj
{
public:
	cImgFile();
	virtual ~cImgFile();

	/**
	* 釋放所有資料
	*/
	void Destroy();

	/**
	* 取得圖形格式
	*/
	ImageFormat GetImageFormat( void ) { return m_imageFormat; }

	/**
	* 取得圖形尺寸大小
	*
	* @return 傳回寬度值
	*/
	int GetXSize( void ) { return m_width; }

	/**
	* 取得圖形尺寸大小
	*
	* @return 傳回高度值
	*/
	int GetYSize( void ) { return m_height; }

	/**
	* 取得MIPMAP層級數量
	*
	* @return 傳回層級數量
	*/
	int GetMipmapLevels( void ) { return m_mipmapLevels; }

	/**
	* 取得圖形資料量大小
	*
	* @return 傳回圖形資料量大小,單位BYTE
	*/
	int GetPixelsSize( void ) { return m_dataSize; }

	/**
	* 取得圖形資料
	*
	* @return 傳回圖形資料指標
	*/
	BYTE *GetPixels( void ) { return m_pData; }

	/**
	* 從檔案內讀取資料
	*
	* @param workDirStr  工作路徑
	* @param fileNameStr  檔案名稱
	* @param format  檔案壓縮格式
	* @param pSpecialData  擴充用參數,指標指向ReadImageOptions結構
	*
	* @return true 成功  false 失敗
	*/
	virtual bool LoadFromFile( const TCHAR *workDirStr, const TCHAR *fileNameStr, CompressFormat format = COMPRESS_FMT_NORMAL, void *pSpecialData = NULL );	

protected:

	/**
	* 讀取圖形檔案資料
	*
	* @param fileNameStr   檔案名稱
	* @param pSpecialData  載入圖形參數設定(ReadImageOptions)
	*
	* @return  true 成功 false 失敗
	*/
	virtual bool Read( const TCHAR *fileNameStr, ReadImageOptions *pSpecialData );

	/**
	* 讀取DDS圖形檔案
	*
	* @param fileNameStr   檔案名稱
	* @param pSpecialData  載入圖形參數設定(ReadImageOptions)
	*
	* @return  true 成功 false 失敗
	*/
	virtual bool ReadDDS( const TCHAR *fileNameStr, ReadImageOptions *pSpecialData );

public:

	/**
	* 拷貝圖形資料至指定記憶體內,目的記憶體不可為DXT壓縮格式
	*
	* @param pDest  目的記憶體指標
	* @param format  目的記憶體圖形格式,不並不支援DXT格式
	* @param x  複制到目的圖形座標
	* @param y  複制到目的圖形座標
	* @param width  目的圖形寬度
	* @param height  目的圖形高度
	*
	* @return  true 成功  false 失敗
	*/
	bool BltToRGB( BYTE *pDest, ImageFormat format, int x, int y, int width, int height );

	/**
	* 拷貝DXT圖形資料至指定記憶體內,目的記憶體需為DXT格式
	*
	* @param pDest  目的記憶體指標
	* @param format  目的記憶體圖形格式,必需為DXT格式
	* @param x  複制到目的圖形座標
	* @param y  複制到目的圖形座標
	* @param width  目的圖形寬度
	* @param height  目的圖形高度		
	* @param mipmapLevels  指定來源MIPMAP層級,第一層為0,第二層為1,其於依此類堆
	* @param color  預乘顏色值
	* @param rop  貼圖方式
	*
	* @return  true 成功  false 失敗
	*/
	bool BltToDXT( void *pDest, ImageFormat format, int x, int y, int width, int height, int mipmapLevels = 0,
		DWORD color = 0xFFFFFFFF, DWORD rop = IMGFILE_ROP_SELECTSRC );

protected:

	/**
	* 儲存檔頭資料
	*/
	virtual void SaveHeader( cListData &header );

	/**
	* 讀取檔頭資料
	*/
	virtual void LoadHeader( HANDLE hFile );

	/**
	* 轉換圖形格式,來源格式需為A8R8G8B8 32Bits
	* 
	* @param pDest  目的記憶體指標
	* @param format  目的圖形格式
	* @param x  目的圖形座標
	* @param y  目的圖形座標
	* @param width  目的圖形寬度
	* @param height  目的圖形高度
	* @param pSrc  來源圖形資料,需為A8R8G8B8格式
	* @param srcWidth  來源圖形寬度
	* @param srcHeight  來源圖形高度
	*
	* @return true 成功  false 失敗
	*/
	bool Transfrom( void *pDest, ImageFormat format, int x, int y, int width, int height, void *pSrc, int srcWidth, int srcHeight);

protected:

	ImageFormat	m_imageFormat;				// 圖形格式
	int			m_width;					// 圖形寬度
	int			m_height;					// 圖形高度
	int			m_mipmapLevels;				// mipmap數量 (0或1都代表沒有mipmap)
};

#endif CLASS_IMGFILE_H