#pragma once
#include <DxLib.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "IFont.h"
#define NULL_HANDLE -1

namespace DXFW
{
/// <summary>フォントの種類</summary>
enum class FontType
{	
	Normal = DX_FONTTYPE_NORMAL,
	Edge = DX_FONTTYPE_EDGE,
	AntiAliase = DX_FONTTYPE_ANTIALIASING,
	AntiAliaseEdge = DX_FONTTYPE_ANTIALIASING_EDGE,
};

///<summary>フォントクラス</summary>
///
///<example>
///[サンプルコード:未完成]<BR/>
///サンプル説明
///<code>
///int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )<BR>
///{<BR>
///	Dx::Initialise();<BR/>
///	Dx::End();<BR/>
///	return 0;<BR/>
///}<BR/>
/// </code>	
/// </example>
class Font : public IFont
{
private:
	int size;
	int thick;
	int handle;
	int enterHeight;
public:
	Font():
		size(0),
		thick(0),
		handle(NULL_HANDLE),
		enterHeight(0)
	{}
	
	///<summary>フォントデータを作成</summary>
	///File::Load参照
	Font(const char *フォント名,int 大きさ ,int 太さ , int 改行高さ, FontType フォントタイプ = FontType::Normal)
	{
		Font::Load( フォント名 , 大きさ , 太さ , 改行高さ , フォントタイプ);
	}
			
	///<summary>メモリ上にフォントを作成する</summary>
	///太さは0〜9で指定、大きさと太さは-1にするとデフォルトになる
	///改行高さは0の場合、改行後の文字が上下くっつく。
	bool Load(const char *フォント名,int 大きさ ,int 太さ , int 改行高さ, FontType フォントタイプ = FontType::Normal)
	{
		if( this->handle != NULL_HANDLE ) DxLib::DeleteFontToHandle(this->handle);
		this->handle = DxLib::CreateFontToHandle(フォント名,大きさ,太さ,(int)フォントタイプ);
		this->size = 大きさ;
		this->thick = 太さ;
		this->enterHeight = 改行高さ;
		return ( handle != -1 );
	}
			
	///<summary>フォントをメモリから開放する</summary>
	bool Release() const
	{
		return !DxLib::DeleteFontToHandle(this->handle);
	}
			
	///<summary>フォントのハンドルを取得</summary>
	int GetHandle() const
	{
		return this->handle;
	}
	
	/// <summary>大きさを取得</summary>
	int GetSize() const
	{
		return this->size;
	}
			
	/// <summary>太さを取得</summary>
	int Getthick() const
	{
		return this->thick;
	}
			
	/// <summary>描画時の幅を取得</summary>
	int GetDrawStringWidth(int strLen ,const char *str , ... ) const
	{
		char bufstr[1024];

		va_list args;
		va_start(args,str);
		vsprintf_s( bufstr , 1024,str, args );
		va_end(args);

		return DxLib::GetDrawStringWidthToHandle(bufstr,strLen,this->handle);
	}

	/// <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);


		char *pstr,*stro;
		strcpy_s(bufstr,1024,str);

		stro = strtok_s(bufstr,"\n",&pstr);

		while(stro != NULL)
		{
			DxLib::DrawStringToHandle(x,y,stro,rgb,handle);
			stro = strtok_s(NULL,"\n",&pstr);
			y += this->enterHeight;
		}

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

		char *pstr,*stro;
		strcpy_s(bufstr,1024,str);

		stro = strtok_s(bufstr,"\n",&pstr);

		while(stro != NULL)
		{
			DxLib::DrawStringToHandleToZBuffer(x,y,stro,handle, (int)Zマスクタイプ);
			stro = strtok_s(NULL,"\n",&pstr);
			y += this->enterHeight;
		}

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

		char *pstr,*stro;
		strcpy_s(bufstr,1024,str);

		stro = strtok_s(bufstr,"\n",&pstr);

		while(stro != NULL)
		{
			DxLib::DrawExtendStringToHandle(x,y,extRateX , extRateY , stro , rgb , handle );
			stro = strtok_s(NULL,"\n",&pstr);
			y += this->enterHeight;
		}

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

		char *pstr,*stro;
		strcpy_s(bufstr,1024,str);

		stro = strtok_s(bufstr,"\n",&pstr);

		while(stro != NULL)
		{
			DxLib::DrawExtendStringToHandleToZBuffer(x,y,extRateX , extRateY , stro , handle , (int)Zマスクタイプ );
			stro = strtok_s(NULL,"\n",&pstr);
			y += this->enterHeight;
		}

		return true;
	}
};
}