#pragma once
#include <Multimedia/Image.h>
#include <Framework/Anime.h>
#include <Multimedia/Font.h>
#include <Multimedia/Screen.h>

namespace SDX
{
/** ビットマップフォントを表すクラス.*/
///	\include BmpFontSample.h
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(){};
		
	/** 改行の高さを取得.*/
	int GetEnterHeight() const
	{
		return this->enterSpace;
	}
			
	/** 改行の高さを設定.*/
	///0の場合、改行後の上下がくっつく。
	void SetEnterHeight(int height)
	{
		this->enterSpace;
	}
			
	/** 数字フォントを設定.*/
	///数字描画に使うImagePackを設定する
	///0～9の順に10個並べた画像を使う
	bool SetNumber( ImagePack* 数字用イメージ )
	{
		if( 数字用イメージ->GetSize() < 10 ) return false;

		divImageNumber = 数字用イメージ;

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

		maxHeight   = std::max( maxHeight , 数字用イメージ->GetHeight() );
		isNumber = true;

		return true;
	}
			
	/** 英大文字フォントをセット.*/
	///英大文字に使う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 = std::max(this->maxHeight, 大文字用イメージ->GetHeight());
				
		this->isAlphabetCapital = true;

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

		divImageAlphabetLow = 小文字用イメージ;

		alphabetLowWidth = 小文字用イメージ->GetWidth();
		alphabetLowHeight = 小文字用イメージ->GetHeight();
		spaceWidth = 小文字用イメージ->GetWidth();
				
		maxHeight = std::max( maxHeight, 小文字用イメージ->GetHeight());
				
		isAlphabetLow = true;
		return true;
	}
			
	/** 書式付きで文字を描画.*/
	bool Draw(int X座標 , int Y座標 , Color 描画色 , const char *描画文字列 , ...) const
	{
		char bufstr[1024];
		va_list args;
		va_start(args, 描画文字列);
		vsprintf_s(bufstr, 1024, 描画文字列, args);
		va_end(args);

		Screen::SetBright(描画色);

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

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

				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)
			{

				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 += spaceWidth;
			}
			else if (bufstr[i] == '\\' && bufstr[i+1] == 'n' )
			{
				addY += maxHeight + enterSpace;
			}
			++i;
			if(i == strlen(bufstr) ) break;
		}

		Screen::SetBright(Color::White);
		return true;
	}
	bool ZMask(int X座標, int Y座標, ZMaskType Zマスクタイプ, const char *描画文字列, ...) const
	{
		char bufstr[1024];
		va_list args;
		va_start(args, 描画文字列);
		vsprintf_s(bufstr, 1024, 描画文字列, 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;
	}
	
	/** 拡大率を指定して文字を描画.*/
	bool DrawExtend(int X座標, int Y座標, double X拡大率, double Y拡大率, Color 描画色, const char *描画文字列, ...) const
	{
		char bufstr[1024];
		va_list args;
		va_start(args, 描画文字列);
		vsprintf_s(bufstr, 1024, 描画文字列, args);
		va_end(args);

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

		Screen::SetBright(描画色);

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

				this->divImageNumber[0][bufstr[i] - '0' ]->DrawExtend
				(
					X座標 + int(addX * X拡大率),
					Y座標 + int((addY - this->numberHeight) * Y拡大率),
					X座標 + int((addX + this->numberWidth) * X拡大率),
					Y座標 + int(addY * Y拡大率)
				);

				addX += this->numberWidth;

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

				this->divImageAlphabetCapital[0][ bufstr[i] - 'A' ]->DrawExtend
				(
					X座標 + int(addX * X拡大率),
					Y座標 + int((addY - this->alphabetCapitalHeight) * Y拡大率),
					X座標 + int((addX + this->alphabetCapitalWidth) * X拡大率),
					Y座標 + int(addY * Y拡大率)
				);

				addX += this->alphabetCapitalWidth;

			}
			else if (bufstr[i] >= 'a' && bufstr[i] <= 'z' && this->isAlphabetLow)
			{
				this->divImageAlphabetLow[0][ bufstr[i] - 'a']->DrawExtend
				(
					X座標 + int(addX * X拡大率),
					Y座標 + int((addY - this->alphabetLowHeight) * Y拡大率),
					X座標 + int((addX + this->alphabetLowWidth) * X拡大率),
					Y座標 + int(addY * Y拡大率)
				);

				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;
		}

		Screen::SetBright(Color::White);

		return true;
	}		
	bool ZMaskExtend(int X座標, int Y座標, double X拡大率, double Y拡大率, ZMaskType Zマスクタイプ, const char *描画文字列, ...) const
	{
		char bufstr[1024];
		va_list args;
		va_start(args, 描画文字列);
		vsprintf_s(bufstr, 1024, 描画文字列, 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 * X拡大率),
					Y座標 + int((addY - this->numberHeight) * Y拡大率),
					X座標 + int((addX + this->numberWidth) * X拡大率),
					Y座標 + int(addY * Y拡大率),
					Zマスクタイプ
				);

				addX += this->numberWidth;

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

				this->divImageAlphabetCapital[0][ bufstr[i] - 'A' ]->ZMaskExtend
				(
					X座標 + int(addX * X拡大率),
					Y座標 + int((addY - this->alphabetCapitalHeight) * Y拡大率),
					X座標 + int((addX + this->alphabetCapitalWidth) * X拡大率),
					Y座標 + int(addY * Y拡大率),
					Zマスクタイプ
				);

				addX += this->alphabetCapitalWidth;

			}
			else if (bufstr[i] >= 'a' && bufstr[i] <= 'z' && this->isAlphabetLow)
			{
				this->divImageAlphabetLow[0][ bufstr[i] - 'a']->ZMaskExtend
				(
					X座標 + int(addX * X拡大率),
					Y座標 + int((addY - this->alphabetLowHeight) * Y拡大率),
					X座標 + int((addX + this->alphabetLowWidth) * X拡大率),
					Y座標 + int(addY * Y拡大率),
					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;
	}
	
};
}