#pragma once
#include <Multimedia/SDX.h>
#include <Multimedia/Screen.h>
#include <Multimedia/IFont.h>

namespace SDX
{
/** フォントの種類.*/
enum class FontType
{	
#ifdef DXLIB
	Normal = DX_FONTTYPE_NORMAL,
	Edge = DX_FONTTYPE_EDGE,
	AntiAliase = DX_FONTTYPE_ANTIALIASING,
	AntiAliaseEdge = DX_FONTTYPE_ANTIALIASING_EDGE,
#elif defined(SDL)
	Normal,
	Edge,
	AntiAliase,
	AntiAliaseEdge
#endif
};

/** フォントデータを表すクラス.*/
///	\include FontSample.h
class Font : public IFont
{
private:
	FontHandle handle = NULL_HANDLE;
	int size = 0;
	int thick = 0;
	int enterHeight = 0;
public:

	Font(){}
	
	Font(const char *フォント名,int 大きさ ,int 太さ , int 改行高さ, FontType フォントタイプ = FontType::Normal)
	{
		Font::Load( フォント名 , 大きさ , 太さ , 改行高さ , フォントタイプ);
	}

	/** メモリ上にフォントを作成する.*/
	///太さは0～9で指定、大きさと太さは-1にするとデフォルトになる\n
	///改行高さは0の場合、改行後の文字が上下くっつく。
	bool Load(const char *フォント名,int 大きさ ,int 太さ , int 改行高さ, FontType フォントタイプ = FontType::Normal)
	{
		Release();
		this->size = 大きさ;
		this->enterHeight = 改行高さ + 大きさ;
		this->thick = 太さ;
	#ifdef DXLIB
		this->handle = DxLib::CreateFontToHandle(フォント名,大きさ,太さ,(int)フォントタイプ);
		return ( handle != -1 );
	#elif defined(SDL)
		handle = TTF_OpenFont(フォント名,大きさ);
		return true;
	#endif
	}
			
	/** フォントをメモリから開放する.*/
	bool Release() const
	{
		if(handle != NULL_HANDLE) return false;
	#ifdef DXLIB
		return !DxLib::DeleteFontToHandle(this->handle);
	#elif defined(SDL)
		TTF_CloseFont(handle);
		return true;
	#endif
	}
			
	/** フォントのハンドルを取得.*/
	FontHandle GetHandle() const
	{
		return handle;
	}
	
	/** 大きさを取得.*/
	int GetSize() const
	{
		return this->size;
	}
			
	/** 太さを取得.*/
	int Getthick() const
	{
		return this->thick;
	}
			
	/** 描画時の幅を取得.*/
	int GetDrawStringWidth(const char *文字列 , ... ) const
	{
	#ifdef DXLIB
		char bufstr[1024];

		va_list args;
		va_start(args, 文字列);
		vsprintf_s(bufstr, 1024, 文字列, args);
		va_end(args);

		return DxLib::GetDrawStringWidthToHandle(bufstr,strlen(bufstr),this->handle);
	#elif defined(SDL)
		return 0;
	#endif
	}

	/** 書式付きで文字を描画.*/
	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);

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

		#ifdef DXLIB
		while(stro != NULL)
		{
			DxLib::DrawStringToHandle(X座標, Y座標, stro, 色, handle);
			stro = strtok_s(NULL,"\n",&pstr);
			Y座標 += this->enterHeight;
		}
		#elif defined(SDL)
		SDL_Surface* image;
		SDL_Texture* moji;
		SDL_Rect temp;

		while (stro != NULL)
		{
			size_t ret;
			wchar_t wc[100];//とりあえず50文字まで
			mbstowcs_s(&ret,wc,100, stro,_TRUNCATE);
			Uint16 text[100];
			for (unsigned int i = 0; i < strlen(stro); ++i)
			{
				text[i] = wc[i];
			}

			image = TTF_RenderUNICODE_Blended(handle, text, 色);
			moji = SDL_CreateTextureFromSurface(Screen::GetHandle(), image);
			temp = { X座標, Y座標, image->w, image->h };
			SDL_RenderCopy(Screen::GetHandle(), moji, 0, &temp);

			stro = strtok_s(NULL, "\n", &pstr);
			Y座標 += this->enterHeight;
			SDL_FreeSurface(image);
			SDL_DestroyTexture(moji);
		}
		#endif

		return true;
	}

	bool ZMask(int X座標 , int Y座標 , ZMaskType Zマスクタイプ , const char *str , ...) const
	{
	#ifdef DXLIB
	//改行コード有効
		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;
	#elif defined(SDL)
		return false;
	#endif
	}
	

	/** 拡大率を指定して文字を描画.*/
	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);

		char *pstr,*stro;
		strcpy_s(bufstr, 1024, 描画文字列);

		stro = strtok_s(bufstr,"\n",&pstr);
		#ifdef DXLIB
		while(stro != NULL)
		{
			DxLib::DrawExtendStringToHandle(X座標,Y座標,X拡大率 , Y拡大率 , stro , 描画色, handle );
			stro = strtok_s(NULL,"\n",&pstr);
			Y座標 += int( this->enterHeight * Y拡大率 );
		}
		#elif defined(SDL)
		SDL_Surface* image;
		SDL_Texture* moji;
		SDL_Rect temp;

		while (stro != NULL)
		{
			size_t ret;
			wchar_t wc[100];//とりあえず50文字まで
			mbstowcs_s(&ret, wc, 100, stro, _TRUNCATE);
			Uint16 text[100];
			for (unsigned int i = 0; i < strlen(stro); ++i)
			{
				text[i] = wc[i];
			}

			image = TTF_RenderUNICODE_Blended(handle, text, 描画色);
			moji = SDL_CreateTextureFromSurface(Screen::GetHandle(), image);
			temp = { X座標, Y座標, int(image->w * X拡大率), int(image->h * Y拡大率) };

			SDL_RenderCopy(Screen::GetHandle(), moji, 0, &temp);

			stro = strtok_s(NULL, "\n", &pstr);
			Y座標 += int(this->enterHeight * Y拡大率);
			SDL_FreeSurface(image);
			SDL_DestroyTexture(moji);
		}
		#endif
		return true;
	}		
	bool ZMaskExtend(int X座標, int Y座標, double X拡大率, double Y拡大率, ZMaskType Zマスクタイプ, const char *str, ...) const
	{
	#ifdef DXLIB
		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座標, X拡大率, Y拡大率, stro, handle, (int)Zマスクタイプ);
			stro = strtok_s(NULL,"\n",&pstr);
			Y座標 += this->enterHeight;
		}
		return true;
	#elif defined(SDL)
		return false;
	#endif
	}
};
}