#pragma once
#include "Image.h"
#include "Anime.h"
#include "Font.h"
#include "Screen.h"

namespace DXFW
{
///<summary>ビットマップフォントを扱うクラス</summary>
///ビットマップフォントを通常のフォントと同じ様に扱うクラス。
///<example>
///[サンプルコード:未完成]<BR>
///サンプル説明<BR>
///<code>
///int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )<BR>
///{<BR>
///	if( !Dx::Initialise() ) return -1;<BR>
///	Dx::End();<BR>
///	return 0;<BR>
///}<BR>
///</code>	
///</example>
class BmpFont : public IFont
{
private:
	ImagePack *divImageNumber;
	ImagePack *divImageAlphabetCapital;
	ImagePack *divImageAlphabetLow;

	bool isNumber;
	bool isAlphabetCapital;
	bool isAlphabetLow;
	int numberHeight;
	int numberWidth;
		
	int alphabetCapitalHeight;
	int alphabetCapitalWidth;

	int alphabetLowHeight;
	int alphabetLowWidth;

	int maxHeight;

	int enterSpace;

	int spaceWidth;
public:
	BmpFont():
		isNumber(false),
		isAlphabetCapital(false),
		isAlphabetLow(false),
		enterSpace(0)
	{}

	~BmpFont(){};
		
	///<summary>改行の高さを取得</summary>
	///改行の高さを取得
	int GetEnterHeight() const
	{
		return this->enterSpace;
	}
			
	///<summary>改行の高さを設定</summary>
	///0の場合、改行後の上下がくっつく。
	///初期値は0
	void SetEnterHeight(int height)
	{
		this->enterSpace;
	}
			
	///<summary>数字フォントを設定</summary>
	///数字に使うImagePackを設定する。
	///0〜9の順に10個並べた画像を使う
	bool SetNumber( ImagePack &数字用イメージ )
	{
		if( 数字用イメージ.GetSize() < 10 ) return false;

		this->divImageNumber = &数字用イメージ;

		this->numberWidth = 数字用イメージ.GetWidth();
		this->numberHeight = 数字用イメージ.GetHeight();
		this->spaceWidth = 数字用イメージ.GetWidth();

		this->maxHeight   = max( this->maxHeight , 数字用イメージ.GetHeight() );

		this->isNumber = true;

		return true;
	}
			
	///<summary>英大文字フォントをセット</summary>
	///英大文字に使うImagePackを設定する。
	///A〜Zの順に26個並べた画像を使う。
	bool SetAlphabetCapital(ImagePack &大文字用イメージ )
	{
		if( 大文字用イメージ.GetSize() < 26 ) return false;

		this->divImageAlphabetCapital = &大文字用イメージ;

		this->alphabetCapitalWidth = 大文字用イメージ.GetWidth();
		this->alphabetCapitalHeight = 大文字用イメージ.GetHeight();
		this->spaceWidth = 大文字用イメージ.GetWidth();
	
		this->maxHeight   = max( this->maxHeight , 大文字用イメージ.GetHeight() );
				
		this->isAlphabetCapital = true;

		return true;
	}
			
	///<summary>英小文字フォントをセット</summary>
	///英小文字に使うImagePackを設定する。
	///A〜Zの順に26個並べた画像を使う。
	bool SetAlphabetLow(ImagePack &小文字用イメージ )
	{
		if( 小文字用イメージ.GetSize() < 26 ) return false;

		this->divImageAlphabetLow = &小文字用イメージ;

		this->alphabetLowWidth = 小文字用イメージ.GetWidth();
		this->alphabetLowHeight = 小文字用イメージ.GetHeight();
		this->spaceWidth = 小文字用イメージ.GetWidth();
				
		this->maxHeight   = max( this->maxHeight , 小文字用イメージ.GetHeight() );
				
		this->isAlphabetLow = true;
		return true;
	}
			
	///<summary>書式付きで文字を描画</summary>
	///ビットマップフォントなので、色は無視される
	bool Draw(int x , int y , int rgb , const char *str , ...) const
	{
		char bufstr[1024];
		va_list args;
		va_start(args,str);
		vsprintf_s( bufstr , 1024 ,str, args );
		va_end(args);

		int i = 0;
		int addX = 0;
		int addY = this->maxHeight;

		while( bufstr[i] != NULL)
		{
			if( bufstr[i] >= '0' && bufstr[i] <= '9' && this->isNumber)
			{
				this->divImageNumber[0][ bufstr[i] - '0' ]->DrawExtend(
					x + addX,
					y + addY - this->numberHeight  ,
					x + addX + this->numberWidth  ,
					y + addY  );

				addX += this->numberWidth;
			}
			else if (bufstr[i] >= 'A' && bufstr[i] <= 'Z' && this->isAlphabetCapital)
			{

				this->divImageAlphabetCapital[0][ bufstr[i] - 'A' ]->DrawExtend
					(
					x + addX ,
					y + addY - this->alphabetCapitalHeight ,
					x + addX + this->alphabetCapitalWidth ,
					y + addY  
					);

				addX += this->alphabetCapitalWidth;

			}
			else if (bufstr[i] >= 'a' && bufstr[i] <= 'z' && this->isAlphabetLow)
			{

				this->divImageAlphabetLow[0][ bufstr[i] - 'a']->DrawExtend
					(
					x + addX,
					y + addY - this->numberHeight  ,
					x + addX + this->numberWidth  ,
					y + addY
					);

				addX += this->alphabetLowWidth;

			}
			else if (bufstr[i] == ' ')
			{
				addX += this->spaceWidth;
			}
			else if (bufstr[i] == '\\' && bufstr[i+1] == 'n' )
			{
				addY += this->maxHeight + this->enterSpace;
			}
			i++;
			if(i == strlen(bufstr) ) break;
		}
		return true;
	}
	bool ZMask(int x , int y , ZMaskType Zマスクタイプ , const char *str , ...) const
	{
		char bufstr[1024];
		va_list args;
		va_start(args,str);
		vsprintf_s( bufstr , 1024 ,str, args );
		va_end(args);

		int i = 0;
		int addX = 0;
		int addY = this->maxHeight;

		while( bufstr[i] != NULL)
		{
			if( bufstr[i] >= '0' && bufstr[i] <= '9' && this->isNumber)
			{
				this->divImageNumber[0][ bufstr[i] - '0' ]->ZMaskExtend
					(
						x + addX,
						y + addY - this->numberHeight  ,
						x + addX + this->numberWidth  ,
						y + addY ,
						Zマスクタイプ
					);
				addX += this->numberWidth;
			}
			else if (bufstr[i] >= 'A' && bufstr[i] <= 'Z' && this->isAlphabetCapital)
			{

				this->divImageAlphabetCapital[0][ bufstr[i] - 'A' ]->ZMaskExtend
					(
						x + addX ,
						y + addY - this->alphabetCapitalHeight ,
						x + addX + this->alphabetCapitalWidth ,
						y + addY ,
						Zマスクタイプ
					);

				addX += this->alphabetCapitalWidth;

			}
			else if (bufstr[i] >= 'a' && bufstr[i] <= 'z' && this->isAlphabetLow)
			{

				this->divImageAlphabetLow[0][ bufstr[i] - 'a']->ZMaskExtend
					(
						x + addX,
						y + addY - this->numberHeight  ,
						x + addX + this->numberWidth  ,
						y + addY,
						Zマスクタイプ
					);

				addX += this->alphabetLowWidth;

			}
			else if (bufstr[i] == ' ')
			{
				addX += this->spaceWidth;
			}
			else if (bufstr[i] == '\\' && bufstr[i+1] == 'n' )
			{
				addY += this->maxHeight + this->enterSpace;
			}
			i++;
			if(i == strlen(bufstr) ) break;
		}
		return true;
	}
	
	///<summary>拡大率を指定して文字を描画</summary>
	///ビットマップフォントなので、色は無視される
	bool DrawExtend( int x , int y , double extRateX , double extRateY , int rgb , const char *str , ...) const
	{
		char bufstr[1024];
		va_list args;
		va_start(args,str);
		vsprintf_s( bufstr , 1024 ,str, args );
		va_end(args);

		int i = 0;
		double addX = 0;
		double addY = this->maxHeight;

		while( bufstr[i] != NULL)
		{
			if( bufstr[i] >= '0' && bufstr[i] <= '9' && this->isNumber)
			{

				this->divImageNumber[0][bufstr[i] - '0' ]->DrawExtend
				(
					x + int(addX * extRateX ) ,
					y + int((addY - this->numberHeight) * extRateY) ,
					x + int((addX + this->numberWidth ) * extRateX ),
					y + int(addY * extRateY )
				);

				addX += this->numberWidth;

			}
			else if (bufstr[i] >= 'A' && bufstr[i] <= 'Z' && this->isAlphabetCapital)
			{

				this->divImageAlphabetCapital[0][ bufstr[i] - 'A' ]->DrawExtend
				(
					x + int(addX * extRateX ) ,
					y + int((addY - this->alphabetCapitalHeight) * extRateY) ,
					x + int((addX + this->alphabetCapitalWidth) * extRateX ),
					y + int(addY * extRateY )
				);

				addX += this->alphabetCapitalWidth;

			}
			else if (bufstr[i] >= 'a' && bufstr[i] <= 'z' && this->isAlphabetLow)
			{
				this->divImageAlphabetLow[0][ bufstr[i] - 'a']->DrawExtend
				(
					x + int(addX * extRateX ) ,
					y + int((addY - this->alphabetLowHeight) * extRateY ) ,
					x + int((addX + this->alphabetLowWidth) * extRateX ),
					y + int(addY * extRateY )
				);

				addX += this->alphabetLowWidth;
			}
			else if (bufstr[i] == ' ')
			{
				addX += this->spaceWidth;
			}
			else if (bufstr[i] == '\\' && bufstr[i+1] == 'n' )
			{
				addY += this->maxHeight + this->enterSpace;
			}
			i++;
			if(i == strlen(bufstr) ) break;
		}
		return true;
	}		
	bool ZMaskExtend( int x , int y , double extRateX , double extRateY , ZMaskType Zマスクタイプ, const char *str , ...) const
	{
		char bufstr[1024];
		va_list args;
		va_start(args,str);
		vsprintf_s( bufstr , 1024 ,str, args );
		va_end(args);

		int i = 0;
		double addX = 0;
		double addY = this->maxHeight;

		while( bufstr[i] != NULL)
		{
			if( bufstr[i] >= '0' && bufstr[i] <= '9' && this->isNumber)
			{

				this->divImageNumber[0][bufstr[i] - '0' ]->ZMaskExtend
				(
					x + int(addX * extRateX ) ,
					y + int((addY - this->numberHeight) * extRateY) ,
					x + int((addX + this->numberWidth ) * extRateX ),
					y + int(addY * extRateY ),
					Zマスクタイプ
				);

				addX += this->numberWidth;

			}
			else if (bufstr[i] >= 'A' && bufstr[i] <= 'Z' && this->isAlphabetCapital)
			{

				this->divImageAlphabetCapital[0][ bufstr[i] - 'A' ]->ZMaskExtend
				(
					x + int(addX * extRateX ) ,
					y + int((addY - this->alphabetCapitalHeight) * extRateY) ,
					x + int((addX + this->alphabetCapitalWidth) * extRateX ),
					y + int(addY * extRateY ),
					Zマスクタイプ
				);

				addX += this->alphabetCapitalWidth;

			}
			else if (bufstr[i] >= 'a' && bufstr[i] <= 'z' && this->isAlphabetLow)
			{
				this->divImageAlphabetLow[0][ bufstr[i] - 'a']->ZMaskExtend
				(
					x + int(addX * extRateX ) ,
					y + int((addY - this->alphabetLowHeight) * extRateY ) ,
					x + int((addX + this->alphabetLowWidth) * extRateX ),
					y + int(addY * extRateY ),
					Zマスクタイプ
				);

				addX += this->alphabetLowWidth;
			}
			else if (bufstr[i] == ' ')
			{
				addX += this->spaceWidth;
			}
			else if (bufstr[i] == '\\' && bufstr[i+1] == 'n' )
			{
				addY += this->maxHeight + this->enterSpace;
			}
			i++;
			if(i == strlen(bufstr) ) break;
		}
		return true;
	}
	
};
}