/*
** Haaf's Game Engine 1.6
** Copyright (C) 2003, Relish Games
** hge.relishgames.com
**
** Bitmap Font Builder
*/


#include "fonted.h"
#include <stdio.h>


HGE *hge=0;


hgeFont			*fnt;
hgeGUI			*gui;
HTEXTURE		texGui;
HTEXTURE		texFont=0;

hgeSprite		*sprFont=0, *sprBlack;
hgeSprite		*sprLeftPane1, *sprLeftPane2;
hgeSprite		*sprCursor;

CFontList		*FontList=0;
FEditorState	state;

float			psx=484, psy=300;
float			fw2, fh2;

void			InitEditor();
void			DoneEditor();
void			CreateGUI();

HTEXTURE		FontGenerate();


bool FrameFunc()
{
	float		dt=hge->Timer_GetDelta();

	// Update
	
	fw2=sprFont->GetWidth()/2;
	fh2=sprFont->GetHeight()/2;

	hge->Input_GetMousePos(&state.mx, &state.my);
	if(hge->Input_GetKeyState(HGEK_LBUTTON))
	{
		if(state.bDrag)
		{
			psx=state.nDragOldX+(state.mx-state.nDragXOffset);
			psy=state.nDragOldY+(state.my-state.nDragYOffset);
		}
	}
	else state.bDrag=false;

	if(HandleKeys(hge->Input_GetKey())) return true;
	if(DoCommands(gui->Update(dt))) return true;

	return false;
}

bool RenderFunc()
{
	int i;
	char		szTemp[128];

	// Render
	
	hge->Gfx_BeginScene();
	hge->Gfx_Clear(0xFF404040);

	sprBlack->SetTextureRect(0,0,sprFont->GetWidth(),sprFont->GetHeight());
	sprBlack->Render(psx-fw2, psy-fh2);
	sprFont->Render(psx-fw2, psy-fh2);

	float u0,v0,u1,v1;

	if(state.bBBox)
		for(i=state.sr.First;i<=state.sr.Last;i++)
		{
			u0=(float)vChars[i].x+psx-fw2;
			u1=u0+vChars[i].w;
			v0=(float)vChars[i].y+psy-fh2;
			v1=v0+vChars[i].h;

			hge->Gfx_RenderLine(u0+0.5f, v0+0.5f, u1,      v0+0.5f, 0xFF95883F);
			hge->Gfx_RenderLine(u1,      v0+0.5f, u1,      v1,      0xFF95883F);
			hge->Gfx_RenderLine(u1,      v1,      u0+0.5f, v1,      0xFF95883F);
			hge->Gfx_RenderLine(u0+0.5f, v1,      u0+0.5f, v0+0.5f, 0xFF95883F);
		}

	sprintf_s(szTemp, sizeof(szTemp), "Texture size: %dx%d",(int)sprFont->GetWidth(),(int)sprFont->GetHeight());
	fnt->SetColor(0xFF808080);
	fnt->Render(176, 580, HGETEXT_LEFT, szTemp);

	for(i=state.sr.First;i<=state.sr.Last;i++)
	{
		u0=(float)vChars[i].x+psx-fw2;
		u1=u0+vChars[i].w;
		v0=(float)vChars[i].y+psy-fh2;
		v1=v0+vChars[i].h;

		if(state.mx>=u0 && state.mx<u1 &&
			state.my>=v0 && state.my<v1)
		{
			hge->Gfx_RenderLine(u0+0.5f, v0+0.5f, u1,      v0+0.5f, 0xFFFF0000);
			hge->Gfx_RenderLine(u1,      v0+0.5f, u1,      v1,      0xFFFF0000);
			hge->Gfx_RenderLine(u1,      v1,      u0+0.5f, v1,      0xFFFF0000);
			hge->Gfx_RenderLine(u0+0.5f, v1,      u0+0.5f, v0+0.5f, 0xFFFF0000);

			if(i>=32 && i<=126)
				sprintf_s(szTemp, sizeof(szTemp),"\"%c\" = x:%d y:%d w:%d h:%d  a:%d c:%d",
					(char)i, vChars[i].x, vChars[i].y, vChars[i].w, vChars[i].h,
					vChars[i].a, vChars[i].c);
			else
				sprintf_s(szTemp, sizeof(szTemp),"0x%02X = x:%d y:%d w:%d h:%d  a:%d c:%d",
					i, vChars[i].x, vChars[i].y, vChars[i].w, vChars[i].h,
					vChars[i].a, vChars[i].c);
			fnt->Render(790, 580, HGETEXT_RIGHT, szTemp);

		}
	}
		
	sprLeftPane1->Render(0,0);
	sprLeftPane2->Render(0,512);
	
	gui->Render();

	if(state.bHelp)
	{
		fnt->SetColor(0xFFFFFFFF);
		fnt->Render(189, 18, HGETEXT_LEFT, "Left mouse button - drag font texture\n"
			"Typefaces listbox - use Up/Down arrows, Mouse wheel\n"
			"Characters range - click and drag\n"
			"Esc - Exit\n\n"
			"A saved font includes two files: .FNT and .PNG\n"
			"You could apply any additional effects to the saved PNG in your graphics editor\n"
			"Edit FONTED.INI file to run in fullscreen");
	}
	if(hge->Input_IsMouseOver()) sprCursor->Render(state.mx, state.my);

	hge->Gfx_EndScene();

	return false;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	hge = hgeCreate(HGE_VERSION);

	hge->System_SetState(HGE_INIFILE, "fonted.ini");
	hge->System_SetState(HGE_LOGFILE, "fonted.log");
	hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
	hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
	hge->System_SetState(HGE_TITLE, "HGE Bitmap Font Builder");
	hge->System_SetState(HGE_SCREENWIDTH, 800);
	hge->System_SetState(HGE_SCREENHEIGHT, 600);
	hge->System_SetState(HGE_SCREENBPP, 32);
	hge->System_SetState(HGE_USESOUND, false);

	if(hge->Ini_GetInt("HGE", "FullScreen",0))	hge->System_SetState(HGE_WINDOWED, false);
	else hge->System_SetState(HGE_WINDOWED, true);

	if(hge->System_Initiate())
	{
		InitEditor();
		hge->System_Start();
		DoneEditor();
	}
	else MessageBox(NULL, hge->System_GetErrorMessage(), "Error", MB_OK | MB_ICONERROR | MB_TASKMODAL);

	hge->System_Shutdown();
	hge->Release();
	return 0;
}

void InitEditor()
{
	hge->Resource_AttachPack("fonted.paq");

	fnt=new hgeFont("font3.fnt");

	state.bHelp=false;
	state.bBBox=false;
	state.bDrag=false;

	FontList=new CFontList();
	FontList->BuildList();

	state.FontFamily=FontList->GetFontByIdx(0);
	state.nSize=20;
	state.bBold=false;
	state.bItalic=false;
	state.bAntialias=true;
	state.sr.First=32;
	state.sr.Last=126;

	cmdGenerateFont();

	texGui=hge->Texture_Load("fgui.png");

	sprCursor=new hgeSprite(texGui, 487, 181, 19, 26);
	sprBlack=new hgeSprite(0,0,0,100,100);
	sprBlack->SetColor(0xFF000000);

	sprLeftPane1=new hgeSprite(texGui, 0, 0, 168, 512);
	sprLeftPane2=new hgeSprite(texGui, 336, 0, 168, 88);

	gui=new hgeGUI();
	CreateGUI();
}

void DoneEditor()
{
	delete gui;
	delete sprLeftPane1;
	delete sprLeftPane2;
	delete sprCursor;
	delete fnt;
	delete sprFont;
	delete sprBlack;

	delete FontList;

	hge->Texture_Free(texFont);
	hge->Texture_Free(texGui);

	hge->Resource_RemoveAllPacks();
}

void CreateGUI()
{
	hgeGUIListbox *listbox;
	hgeGUIButton  *button;
	hgeGUISlider  *slider;
	hgeGUIText	  *text;
	hgeGUIRange	  *range;
	int i;

	gui->AddCtrl(new hgeGUIButton(CMD_SAVE, 9, 485, 47, 17, texGui, 336, 338));
	gui->AddCtrl(new hgeGUIButton(CMD_EXIT, 111, 485, 47, 17, texGui, 336, 338));
	button=new hgeGUIButton(CMD_HELP, 60, 485, 47, 17, texGui, 336, 338);
	button->SetMode(true);
	gui->AddCtrl(button);

	button=new hgeGUIButton(CMD_BOLD, 9, 180, 8, 8, texGui, 368, 176);
	button->SetMode(true);
	button->SetState(state.bBold);
	gui->AddCtrl(button);
	button=new hgeGUIButton(CMD_ITALIC, 52, 180, 8, 8, texGui, 368, 176);
	button->SetMode(true);
	button->SetState(state.bItalic);
	gui->AddCtrl(button);
	button=new hgeGUIButton(CMD_ANTIALIAS, 97, 180, 8, 8, texGui, 368, 176);
	button->SetMode(true);
	button->SetState(state.bAntialias);
	gui->AddCtrl(button);	
	
	button=new hgeGUIButton(CMD_BOUNDINGBOX, 9, 461, 8, 8, texGui, 368, 176);
	button->SetMode(true);
	button->SetState(state.bBBox);
	gui->AddCtrl(button);

	listbox=new hgeGUIListbox(CMD_FAMILYLIST, 10, 44, 139, 128, fnt, 0xFF7697A4, 0xFFBBCBD2, 0x40D4C25A);
	for(i=0; i<FontList->GetNumFonts(); i++) listbox->AddItem(FontList->GetFontByIdx(i));
	gui->AddCtrl(listbox);

	slider=new hgeGUISlider(CMD_FAMILYSLIDER, 152, 44, 6, 128, texGui, 417, 177, 6, 6, true);
	slider->SetMode(0, (float)listbox->GetNumItems()-listbox->GetNumRows(), HGESLIDER_BAR);
	slider->SetValue(0);
	gui->AddCtrl(slider);

	range=new hgeGUIRange(CMD_CHARRANGE, 14, 266, 144, 144, 16, 16, 0x4D99FCD2);
	range->SetRange(state.sr.First, state.sr.Last);
	gui->AddCtrl(range);

	slider=new hgeGUISlider(CMD_FONTSIZE, 10, 219, 148, 6, texGui, 417, 177, 6, 6, false);
	slider->SetMode(5, 80, HGESLIDER_BAR);
	slider->SetValue((float)state.nSize);
	gui->AddCtrl(slider);
	text=new hgeGUIText(CMD_TFONTSIZE, 116, 205, 28, 12, fnt);
	text->SetMode(HGETEXT_RIGHT);
	text->printf("%d",state.nSize);
	gui->AddCtrl(text);
}

