#pragma once

#include <vector>
#include <string>
#include <Widgets/Main.h>
#include <Widgets/FullscreenPanel.h>
#include <Widgets/Tabpanel.h>
#include <Widgets/Listbox.h>
#include "../Common/FileHandling.h"
#include <iosfwd>
#include <Widgets/Dialogs/TextInput.h>
#include <Gorgon/Folder.h>
#include <Gorgon/Base.h>
#include <Gorgon/Game/Animation.h>
#include <Gorgon/Generic/DataArray.h>
#include <Widgets/Dialogs/Query.h>
#include <Widgets/Numberbox.h>
#include <Gorgon/Extended/Sound.h>
#include <Gorgon/Link.h>
#include <Widgets/InlinePanel.h>
#include <Widgets/Dialogs/Message.h>

class UI {
public:

#define eventhandler(name, ind, parent, type) name.ChangeEvent.RegisterLambda([&]{ if(parent) { parent->Get<resource::type>(ind).value=name.Value; changed=true; } });
#define eventhandlerStr(name, ind, parent, type) name.ChangeEvent.RegisterLambda([&]{ if(parent) { parent->Get<resource::type>(ind).value=name.Text; changed=true; } });

	UI() {
		changed=false;

		CurrentFile.AddGameLoaders();
		CurrentFile.SetFileType(gorgon::GID::File::Game);

		os::window::Closing.RegisterLambda([&](bool &reply){
			if(changed) {
				AskQuit();
				reply=false;
			}
		});

		toplevel.Padding=0;


		navigation.SetContainer(toplevel);
		navigation.FillContainer();
		navigation.SetWidth(299);
		navigation.Add("Files");
		navigation("Files").Padding=utils::Margins(navigation("Files").Padding)+utils::Margins(40, 0,40,0);
		navigation.Add("Edit");
		navigation("Edit").Disable();
		navigation.reorganize();
		

		file.SetPanel(navigation("Files"));
		file.SetPanel(navigation("Files"));
		file.Quit.ClickEvent.RegisterLambda([&]{
			if(changed) AskQuit();
			else        Main.Exit(0);
		});
		file.New.ClickEvent.Register(this, &UI::NewFile);
		file.Load.ClickEvent.Register(this, &UI::LoadFile);
		file.Save.ClickEvent.RegisterLambda([&]{ actionafter=action_none; Save(); });
		file.SaveAs.ClickEvent.RegisterLambda([&]{ actionafter=action_none; AskSavename(); });
		file.RefreshFiles();
		
		navigation("Edit").SetOrganizer(editororganizer);

		auto nl=editororganizer.nextline;

		editororganizer
			
			<< "*General Constants*"			<< nl
			<< "TB Cap Dnm: "					<< TBCapDnm << nl
			<< "Wildling DS: "					<< wildlingDS << nl
			<< "Wildling NS: "					<< wildlingNS  << nl
			<< "Wildling WR Dnm: "			<< wildlingWRDnm    << nl
			<< "Wildling WR Mul: "			<< wildlingWDRMul	   << nl
			<< "Retry Delay: "			<< retryDelay	   << nl
			<< "Male Title: "			<< maleTitle	   << nl
			<< "Female Title: "			<< femaleTitle	   << nl
			<< "WR Value: "			<< WRValue	   << nl
			<< "WR Range: "			<< WRRange	   << nl
			<< "TC Sight: "			<< townCenterSight	   << nl
			<< "TC Build Range: "			<< townCenterBuildRange	   << nl
			<< "Den Range: "			<< denRage	   << nl
			<< "Pathing Limit Margin: "			<< pathingLimitMargin	   << nl

			<< "*Stats Constants*"			<< nl
			<< "Minimum: "					<< minStat << nl
			<< "Maximum: "					<< maxStat << nl
			<< "Max Lvl: "					<< maxLvl  << nl
			<< "Walking S.D.R: "			<< wSDR    << nl
			<< "Jogging S.D.R: "			<< jSDR	   << nl
			<< "Running S.D.R: "			<< rSDR	   << nl
			<< "S.D.R: Stamina Drain Rate " << nl
			
			<< " "				    << nl
			<< "*Crafting Constants*" << nl
			<< "Base: "				<< craftingBase  << nl
			<< "Str Multiplier: "	<< craftingStrM  << nl
			<< "Dex Multiplier: "	<< craftingDexM  << nl
			<< "Intl Multiplier: "	<< craftingIntlM << nl
			<< "Lvl Multiplier: "	<< craftingLvlM  << nl

			<< " "						  << nl
			<< "*Resource(Gold) Constants*" << nl
			<< "Base: "					  << goldBase    << nl
			<< "Lvl Multipier: "		  << goldLvlM    << nl
			<< "Lvl^2 Multiplier: "		  << goldLvlSqrM << nl
			<< "Soldier Gold Cost: "	  << soldierGoldCost    << nl
			<< "Artisan Gold Cost: "	  << artisanGoldCost << nl

			<< " "				     << nl
			<< "*Happiness Constants*" << nl
			<< "Base: "		  << happinessBase		<< nl
			<< "Tax Rate Mul: "		  << happinessTaxRateMul		<< nl
			<< "Pop. Mul: "		 << happinessPopMul			<< nl
			<< "Dif. Den.: "		     << happinessDiffDenominator << nl
			<< "Time Mul 1: "			 << happinessTimeMul1    << nl
			<< "Time Mul 2: "	 << happinessTimeMul2	    << nl
			<< "pop lim: "	 << popLim       << nl
			<< "Current H. Mod: "	 << currentHapMod	    << nl
			<< "Current H. Mul: "	 << currentHapMul       << nl
			<< "TB Killed Mod: "	 << happinessDeathMod       << nl

			<< " "				      << nl
			<< "*Combat Constants*"     << nl
			<< "Dodge Chance Mod.: "  << dodgeChanceMod		 << nl
			<< "Parry CD Mod.: "	  << parryCDMod			 << nl
			<< "Block Chance Mod.: "  << blockChanceMod		 << nl
			<< "Stag. Str Dnm.: "	  << staggerStrDnm		 << nl
			<< "Stag. Vit Dnm.: "	  << staggerVitDnm		 << nl
			<< "Stag. Mul: "		  << staggerLvlMul			 << nl
			<< "Stag. Stam. Dnm.: "	  << staggerStamDnm		 << nl
			<< "Stag. Att. CD Dnm.: " << staggerAtckCDDnm	 << nl
			<< "Stag. Effect Dnm.: "  << staggerEffctMod	 << nl
			<< "AP Effect Mod.: "	  << APEffectMod		 << nl
			<< "OS Time Mul: "		  << OSTimeM			 << nl
			<< "Archer Min Range: "	  << archerMinRange << nl
			<< "RA Effect Mod.: "	  << rngdAttckEffectMod	 << nl
			<< "RA MC Dnm: "		  << rngedMissChanceDnm  << nl
			<< "RA MC Acc Mul: "	  << rngedMissChanceAccM << nl
			<< "RA MC Lvl Mul: "	  << rngedMissChanceLvlM << nl
			<< "Mod: Modifier, Mul: Multiplier"				 << nl
			<< "Stag: Stagger, Dnm: Denominator"			 << nl
			<< "AP: Armor Pierce, OS: Over Shoot"            << nl
			<< "RA: Ranged Attack, MC: Miss Chance"          << nl

			<< " " << nl
			<< "*Human Constants*" << nl
			<< "HP Base: "		<< HPBase	 << nl
			<< "HP Vit Mul.: "	<< HPVitM	 << nl
			<< "HP Lvl Mul: "	<< HPLvlM	 << nl
			<< "Stam Base: "	<< stamBase	 << nl
			<< "Stam Vit Mul: " << stamVitM	 << nl
			<< "Stam Str Mul: " << stamStrM	 << nl
			<< "Stam Lvl Mul: " << stamLvlM	 << nl
			<< "MS Base: "		<< mvmntBase << nl
			<< "MS Spe Mul: "	<< mvmntSpeM << nl
			<< "MS Lvl Mul: "	<< mvmntLvlM << nl
			<< "DS Base: "		<< DSBase	 << nl
			<< "DS Vit Mul: "	<< DSVitM	 << nl
			<< "DS Intl Mul: "	<< DSIntlM	 << nl
			<< "DS Lvl Mul: "	<< DSLvlM	 << nl
			<< "NS Base: "		<< NSBase	 << nl
			<< "NS Vit Mul: "	<< NSVitM	 << nl
			<< "NS Intl Mul: "	<< NSIntlM	 << nl
			<< "NS Lvl Mul: "	<< NSLvlM	 << nl
			<< "Female Str: "	<< fmlStr	 << nl
			<< "Female Dex.: "	<< fmlDex	 << nl
			<< "Female Acc: "	<< fmlAcc	 << nl
			<< "Female Spe: "	<< fmlSpe	 << nl
			<< "Female Intl: "	<< fmlInlt	 << nl
			<< "Female Vit.: "	<< fmlVit	 << nl
			<< "Male Str: "		<< mlStr	 << nl
			<< "Male Dex: "		<< mlDex	 << nl
			<< "Male Acc: "		<< mlAcc	 << nl
			<< "Male Spe: "		<< mlSpe	 << nl
			<< "Male Intl: "	<< mlIntl	 << nl
			<< "Male Vit: "		<< mlVit	 << nl
			<< "Stat Denominator: "		<< statDenominator	 << nl
			<< "dodgeBase: "		<< dodgeBase	 << nl
			<< "dodgeAccMul: "		<< dodgeAccMul	 << nl
			<< "dodgeIntlMul: "		<< dodgeIntlMul	 << nl
			<< "dodgeLvlMul: "		<< dodgeLvlMul	 << nl
			<< "MS: Movement Speed, DS: Day Sight" << nl
			<< "NS: Night Sight" << nl

			<< " " <<  nl
			<< "*Leveling Constats*" << nl
			<< "XP Inlt Mod: "     << XPIntlMod	  << nl
			<< "XP Intl Dnm: "     << XPIntlDnm	  << nl
			<< "Soldier Lvl Cap: " << sldrLvlCap  << nl
			<< "Artisan Lvl Cap: " << artsnLvlCap << nl
			<< "Next Lvl Base: "   << nxtLvlBase  << nl
			<< "Next Lvl Incre: "  << nxtLvlIncre << nl
			<< "Next Lvl Mul: "    << nxtLvlM	  << nl
			<< "XP Mul: "    << XPMul	  << nl
		;
		

		//general
			eventhandler(TBCapDnm, 0, generalInfo, FloatData);
			eventhandler(wildlingDS, 1, generalInfo, FloatData);
			eventhandler(wildlingNS, 2, generalInfo, FloatData);
			eventhandler(wildlingWRDnm, 3, generalInfo, FloatData);
			eventhandler(wildlingWDRMul, 4, generalInfo, FloatData);
			eventhandler(retryDelay, 5, generalInfo, FloatData);
			eventhandlerStr(maleTitle, 6, generalInfo, StringData);
			eventhandlerStr(femaleTitle, 7, generalInfo, StringData);
			eventhandler(WRValue, 8, generalInfo, FloatData);
			eventhandler(WRRange, 9, generalInfo, FloatData);
			eventhandler(townCenterSight, 10, generalInfo, FloatData);
			eventhandler(townCenterBuildRange, 11, generalInfo, FloatData);
			eventhandler(denRage, 12, generalInfo, FloatData);
			eventhandler(pathingLimitMargin, 13, generalInfo, FloatData);

		// stats
		eventhandler(minStat, 0, statInfo, IntegerData);
		eventhandler(maxStat, 1, statInfo, IntegerData);
		eventhandler(maxLvl, 2, statInfo, IntegerData);
		eventhandler(wSDR, 3, statInfo, FloatData);
		eventhandler(jSDR, 4, statInfo, FloatData);
		eventhandler(rSDR, 5, statInfo, FloatData);
		
		// crafting
		eventhandler(craftingBase, 0, craftingInfo, FloatData);
		eventhandler(craftingStrM, 1, craftingInfo, FloatData);
		eventhandler(craftingDexM, 2, craftingInfo, FloatData);
		eventhandler(craftingIntlM, 3, craftingInfo, FloatData);
		eventhandler(craftingLvlM, 4, craftingInfo, FloatData);

		// gold
		eventhandler(goldBase, 0, goldInfo, FloatData);
		eventhandler(goldLvlM, 1, goldInfo, FloatData);
		eventhandler(goldLvlSqrM, 2, goldInfo, FloatData);
		eventhandler(soldierGoldCost, 3, goldInfo, FloatData);
		eventhandler(artisanGoldCost, 4, goldInfo, FloatData);

		// happiness
		eventhandler(happinessBase, 0, happinessInfo, FloatData);
		eventhandler(happinessTaxRateMul, 1, happinessInfo, FloatData);
		eventhandler(happinessPopMul, 2, happinessInfo, FloatData);
		eventhandler(happinessDiffDenominator, 3, happinessInfo, FloatData);
		eventhandler(happinessTimeMul1, 4, happinessInfo, FloatData);
		eventhandler(happinessTimeMul2, 5, happinessInfo, FloatData);
		eventhandler(popLim, 6, happinessInfo, FloatData);
		eventhandler(currentHapMod, 7, happinessInfo, FloatData);
		eventhandler(currentHapMul, 8, happinessInfo, FloatData);
		eventhandler(happinessDeathMod, 9, happinessInfo, FloatData);

		// combat
		eventhandler(dodgeChanceMod, 0, combatInfo, FloatData);
		eventhandler(parryCDMod, 1, combatInfo, FloatData);
		eventhandler(blockChanceMod, 2, combatInfo, FloatData);
		eventhandler(staggerStrDnm, 3, combatInfo, FloatData);
		eventhandler(staggerVitDnm, 4, combatInfo, FloatData);
		eventhandler(staggerLvlMul, 5, combatInfo, FloatData);
		eventhandler(staggerStamDnm, 6, combatInfo, FloatData);
		eventhandler(staggerAtckCDDnm, 7, combatInfo, FloatData);
		eventhandler(staggerEffctMod, 8, combatInfo, FloatData);
		eventhandler(APEffectMod, 8, combatInfo, FloatData);
		eventhandler(OSTimeM, 10, combatInfo, FloatData);
		eventhandler(archerMinRange, 11, combatInfo, IntegerData);
		eventhandler(rngdAttckEffectMod, 12, combatInfo, FloatData);
		eventhandler(rngedMissChanceDnm, 13, combatInfo, FloatData);
		eventhandler(rngedMissChanceAccM, 14, combatInfo, FloatData);
		eventhandler(rngedMissChanceLvlM, 15, combatInfo, FloatData);

		// human
		eventhandler(HPBase, 0, humanInfo, FloatData);
		eventhandler(HPVitM, 1, humanInfo, FloatData);
		eventhandler(HPLvlM, 2, humanInfo, FloatData);
		eventhandler(stamBase, 3, humanInfo, FloatData);
		eventhandler(stamVitM, 4, humanInfo, FloatData);
		eventhandler(stamStrM, 5, humanInfo, FloatData);
		eventhandler(stamLvlM, 6, humanInfo, FloatData);
		eventhandler(mvmntBase, 7, humanInfo, FloatData);
		eventhandler(mvmntSpeM, 8, humanInfo, FloatData);
		eventhandler(mvmntLvlM, 9, humanInfo, FloatData);
		eventhandler(DSBase, 10, humanInfo, FloatData);
		eventhandler(DSVitM, 11, humanInfo, FloatData);
		eventhandler(DSIntlM, 12, humanInfo, FloatData);
		eventhandler(DSLvlM, 13, humanInfo, FloatData);
		eventhandler(NSBase, 14, humanInfo, FloatData);
		eventhandler(NSVitM, 15, humanInfo, FloatData);
		eventhandler(NSIntlM, 16, humanInfo, FloatData);
		eventhandler(NSLvlM, 17, humanInfo, FloatData);
		eventhandler(fmlStr, 18, humanInfo, FloatData);
		eventhandler(fmlDex, 19, humanInfo, FloatData);
		eventhandler(fmlAcc, 20, humanInfo, FloatData);
		eventhandler(fmlSpe, 21, humanInfo, FloatData);
		eventhandler(fmlInlt, 22, humanInfo, FloatData);
		eventhandler(fmlVit, 23, humanInfo, FloatData);
		eventhandler(mlStr, 24, humanInfo, FloatData);
		eventhandler(mlDex, 25, humanInfo, FloatData);
		eventhandler(mlAcc, 26, humanInfo, FloatData);
		eventhandler(mlSpe, 27, humanInfo, FloatData);
		eventhandler(mlIntl, 28, humanInfo, FloatData);
		eventhandler(mlVit, 29, humanInfo, FloatData);
		eventhandler(statDenominator, 30, humanInfo, FloatData);
		eventhandler(dodgeBase, 31, humanInfo, FloatData);
		eventhandler(dodgeAccMul, 32, humanInfo, FloatData);
		eventhandler(dodgeIntlMul, 33, humanInfo, FloatData);
		eventhandler(dodgeIntlMul, 34, humanInfo, FloatData);

		// leveling
		eventhandler(XPIntlMod, 0, levelingInfo, FloatData);
		eventhandler(XPIntlDnm, 1, levelingInfo, FloatData);
		eventhandler(sldrLvlCap, 2, levelingInfo, IntegerData);
		eventhandler(artsnLvlCap, 3, levelingInfo, IntegerData);
		eventhandler(nxtLvlBase, 4, levelingInfo, FloatData);
		eventhandler(nxtLvlIncre, 5, levelingInfo, FloatData);
		eventhandler(nxtLvlM, 6, levelingInfo, FloatData);
		eventhandler(XPMul, 7, levelingInfo, FloatData);
	}

	~UI() {
		navigation("Edit").RemoveOrganizer();
	}


	void SetDirectory(const std::string &dir) {
		file.SetDirectory(dir);
	}

	void AskQuit() {
		auto &d=widgets::dialog::AskConfirm("You have changed the file, do you wish to save?", "Quit");
		d.RepliedEvent.RegisterLambda([&](bool reply){
			if(reply) {
				actionafter=action_quit;
				Save();
				return;
			}
			else {
				Main.Exit(0);
			}
		});
		d.ShowCancel=true;
	}

	void AskSavename() {
		widgets::dialog::AskText("Enter the name for the file.", CurrentFile.GetFilename(), 
			"Save").RepliedEvent.RegisterLambda([&](const std::string &str) {
				CurrentFile.SetFilename(file.directory.Text+"/"+str);
				Save();
		});
	}

	bool Save() {
		if(CurrentFile.GetFilename()=="") {
			AskSavename();
			return false;
		}

		try {
			CurrentFile.SaveFile(CurrentFile.GetFilename());
			file.RefreshFiles();
		}
		catch(std::exception ex) {
			widgets::dialog::ShowMessage(std::string(ex.what())+"\nCheck if file path is valid.", "Save error");
		}
		changed=false;

		if(actionafter==action_newfile) {
			NewFile();
		}
		else if(actionafter==action_loadfile) {
			LoadFile();
		}
		else if(actionafter==action_quit) {
			Main.Exit(0);
		}

		return true;
	}

	void AskNew() {
		auto &d=widgets::dialog::AskConfirm("You have changed the file, do you wish to save?", "New file");
		d.RepliedEvent.RegisterLambda([&](bool reply){
			if(reply) {
				actionafter=action_newfile;
				Save();
				return;
			}
			else {
				ForceNewFile();
			}
		});
		d.ShowCancel=true;
	}

	void NewFile() {
		if(changed) {
			AskNew();
		}
		else {
			ForceNewFile();
		}
	}

	void ForceNewFile() {
		CurrentFile.New();
		CurrentFile.Root().Add(*new gorgon::Folder("Info"));

		gorgon::DataArray &dinf=*new gorgon::DataArray;
		dinf.SetCaption("Info");
		dinf.Add("trinlibr:consts").name="ID";

		CurrentFile.Root().Get<gorgon::Folder>(0).Add(dinf);

		navigation("Edit").Enable();
		file.Save.Enable();
		file.SaveAs.Enable();
		navigation.reorganize();
		navigation.Activate(navigation("Edit"));

		CreateNewFile();
	}

	void AskLoad() {
		auto &d=widgets::dialog::AskConfirm("You have changed the file, do you wish to save?", "Load file");
		d.RepliedEvent.RegisterLambda([&](bool reply){
			if(reply) {
				actionafter=action_loadfile;
				Save();
				return;
			}
			else {
				ForceLoadFile();
			}
		});
		d.ShowCancel=true;
	}

	void LoadFile() {
		if(changed) {
			AskLoad();
		}
		else
			ForceLoadFile();

	}

	void ForceLoadFile() {
		std::string filename=(std::string)file.directory.Text + "/" + file.lst.GetValue().Filename;

		CurrentFile.LoadFile(filename);
		CurrentFile.Prepare();

		if(CurrentFile.Root().Get<gorgon::Folder>(0).GetCount()==0) {
			gorgon::DataArray &dinf=*new gorgon::DataArray;
			dinf.SetCaption("Info");
			dinf.Add("trinlibr:consts").name="ID";

			CurrentFile.Root().Get<gorgon::Folder>(0).Add(dinf);
		}

		navigation("Edit").Enable();
		file.Save.Enable();
		file.SaveAs.Enable();
		navigation.reorganize();
		navigation.Activate(navigation("Edit"));

		LoadFileData();
	}

	void CreateNewFile() {
		gorgon::DataArray &d=*new gorgon::DataArray;


		//general
		d.SetCaption("General");
		generalInfo=new gorgon::DataArray;
		generalInfo->SetCaption("General");
		generalInfo->Add(5.f).name   = "TB Cap Dnm";
		generalInfo->Add(5.f).name   = "Wildling DS";
		generalInfo->Add(5.f).name   = "Wildling NS";
		generalInfo->Add(5.f).name   = "Wildling WR Dnm";
		generalInfo->Add(5.f).name   = "Wildling WR Mul";
		generalInfo->Add(5.f).name   = "Retry Delay";
		generalInfo->Add("Lord").name   = "Male Tittle";
		generalInfo->Add("Lady").name   = "Female Tittle";
		generalInfo->Add(5.f).name   = "WR Value";
		generalInfo->Add(5.f).name   = "WR Range";
		generalInfo->Add(5.f).name   = "TC Sight";
		generalInfo->Add(5.f).name   = "TC Build Range";
		generalInfo->Add(5.f).name   = "Den Range";
		generalInfo->Add(5.f).name   = "Pathing Limit Margin";


		d.SetCaption("Stats");
		//Stats
		// S.D.R = stamina drain rate
		// w = walking, j = jogging, r = running
		statInfo=new gorgon::DataArray;
		statInfo->SetCaption("Stats");
		statInfo->Add(5).name   = "Stat min";
		statInfo->Add(25).name  = "Stat max";
		statInfo->Add(10).name  = "max Lvl";
		statInfo->Add(0.01f).name = "w S.D.R";
		statInfo->Add(0.4f).name = "j S.D.R";
		statInfo->Add(0.1f).name = "r S.D.R";


		//Crafting
		//M = multiplier
		craftingInfo =new gorgon::DataArray;
		craftingInfo->SetCaption("Crafting");
		craftingInfo->Add(100.f).name = "base";
		craftingInfo->Add(25.f).name  = "str M.";
		craftingInfo->Add(10.f).name  = "dex M.";
		craftingInfo->Add(3.f).name   = "intl M.";
		craftingInfo->Add(3.f).name   = "lvl M.";

		//Gold
		goldInfo =new gorgon::DataArray;
		goldInfo->SetCaption("Gold");
		goldInfo->Add(100.f).name = "base";
		goldInfo->Add(3.f).name   = "lvl M.";
		goldInfo->Add(3.f).name   = "lvl^2 M.";
		goldInfo->Add(200.f).name   = "Soldier Gold Cost";
		goldInfo->Add(200.f).name   = "Artisan Gold Cost";

		//Happiness
		happinessInfo =new gorgon::DataArray;
		happinessInfo->SetCaption("Happiness");
		happinessInfo->Add(25.f).name = "base";
		happinessInfo->Add(2.f).name  = "tax rate mul";
		happinessInfo->Add(2.f).name  = "pop mul";
		happinessInfo->Add(100.f).name = "diff denom.";
		happinessInfo->Add(75.f).name  = "time mul 1";
		happinessInfo->Add(80.f).name  = "time mul 2";
		happinessInfo->Add(100.f).name = "pop lim";
		happinessInfo->Add(25.f).name  = "curretn hap mod";
		happinessInfo->Add(1.f).name  = "curretn hap mul";
		happinessInfo->Add(5.f).name  = "TB Killed mod";




		//Combat
		// D = dodge, P = Parry, M = Modifier, S = Stagger
		// B = Block, Dnm = denominator, AP = Armor Pierce
		// OS = Over Shoot, R = Range, RA = Ranged Attack
		// RMC = Ranged Miss Chance
		combatInfo =new gorgon::DataArray;
		combatInfo->SetCaption("Combat");
		combatInfo->Add(20.f).name = "D. chance M.";
		combatInfo->Add(50.f).name  = "P CD M.";
		combatInfo->Add(20.f).name  = "B. Chance M.";
		combatInfo->Add(5.f).name  = "S. str Dnm.";
		combatInfo->Add(5.f).name  = "S. Vit Dnm.";
		combatInfo->Add(1.f).name  = "S. Lvl M.";
		combatInfo->Add(10.f).name  = "S. Stam. Dnm.";
		combatInfo->Add(100.f).name  = "S. Atck. CD. Dnm.";
		combatInfo->Add(50.f).name  = "S. Effct. M.";
		combatInfo->Add(50.f).name  = "AP. Effct. M.";
		combatInfo->Add(1.5f).name  = "OS. Time M.";
		combatInfo->Add(2).name    = "Archer Min R.";
		combatInfo->Add(50.f).name  = "RA. Effct. M.";
		combatInfo->Add(10.f).name  = "RMC. Dnm.";
		combatInfo->Add(1.f).name  = "RMC. Acc M.";
		combatInfo->Add(2.f).name  = "RMC. Lvl M.";

		//Human
		// DS = Day Sight, NS = Night Sight
		humanInfo =new gorgon::DataArray;
		humanInfo->SetCaption("Human");
		humanInfo->Add(100.f).name = "HP Base";
		humanInfo->Add(1.f).name   = "HP vit M.";
		humanInfo->Add(1.f).name   = "HO lvl M.";
		humanInfo->Add(50.f).name   = "Stam Base";
		humanInfo->Add(1.f).name   = "Stam Base vit M.";
		humanInfo->Add(1.f).name   = "Stam Base str M.";
		humanInfo->Add(3.f).name   = "Stam Base lvl M.";
		humanInfo->Add(20.f).name   = "Mvmnt Base";
		humanInfo->Add(1.f).name   = "Mvmnt Base spe M.";
		humanInfo->Add(1.f).name   = "Mvmnt Base lvl M.";
		humanInfo->Add(2000.f).name   = "DS Base";
		humanInfo->Add(20.f).name   = "DS Base vit M.";
		humanInfo->Add(1.f).name   = "DS Base intl M.";
		humanInfo->Add(1.f).name   = "DS Base lvl M.";
		humanInfo->Add(150.f).name   = "NS Base";
		humanInfo->Add(1.f).name   = "NS Base vit M.";
		humanInfo->Add(1.f).name   = "NS Base Intl M.";
		humanInfo->Add(2.f).name   = "NS Base lvl M.";
		humanInfo->Add(12.f).name  = "FML str";
		humanInfo->Add(18.f).name  = "FML dex";
		humanInfo->Add(15.f).name  = "FML acc";
		humanInfo->Add(15.f).name  = "FML spe";
		humanInfo->Add(18.f).name  = "FML intl";
		humanInfo->Add(12.f).name  = "FML vit";
		humanInfo->Add(18.f).name  = "ML str";
		humanInfo->Add(12.f).name  = "ML dex";
		humanInfo->Add(15.f).name  = "ML acc";
		humanInfo->Add(15.f).name  = "ML spe";
		humanInfo->Add(12.f).name  = "ML intl";
		humanInfo->Add(18.f).name  = "ML vit";
		humanInfo->Add(25.f).name  = "Stat Denom.";
		humanInfo->Add(1.f).name  = "dodge base";
		humanInfo->Add(1.f).name  = "dodge acc m";
		humanInfo->Add(1.f).name  = "dodge intl m";
		humanInfo->Add(1.f).name  = "dodge lvl m";

		//Leveling
		levelingInfo =new gorgon::DataArray;
		levelingInfo->SetCaption("Leveling");
		levelingInfo->Add(5.f).name = "XP intl M.";
		levelingInfo->Add(40.f).name   = "XP intl Dmn.";
		levelingInfo->Add(10).name    = "Sldr lvl Cap";
		levelingInfo->Add(10).name    = "Artsn lvl Cap";
		levelingInfo->Add(100.f).name  = "nxt lvl Base";
		levelingInfo->Add(50.f).name  = "nxt lvl Incre";
		levelingInfo->Add(1.2f).name  = "nxt lvl M.";
		levelingInfo->Add(0.35f).name  = "XP M.";
		//...

		CurrentFile.Root().Add(generalInfo);
		CurrentFile.Root().Add(statInfo);
		CurrentFile.Root().Add(craftingInfo);
		CurrentFile.Root().Add(goldInfo);
		CurrentFile.Root().Add(happinessInfo);
		CurrentFile.Root().Add(combatInfo);
		CurrentFile.Root().Add(humanInfo);
		CurrentFile.Root().Add(levelingInfo);

		LoadFileData();
	}

	void LoadFileData() {
		// first index is info DataArray
		// actual game data contained in DataArrays starting from index 1
		int index = 1;
		generalInfo   = &CurrentFile.Root().Get<gorgon::DataArray>(index++);
		statInfo      = &CurrentFile.Root().Get<gorgon::DataArray>(index++);
		craftingInfo  = &CurrentFile.Root().Get<gorgon::DataArray>(index++);
		goldInfo	  = &CurrentFile.Root().Get<gorgon::DataArray>(index++);
		happinessInfo = &CurrentFile.Root().Get<gorgon::DataArray>(index++);
		combatInfo	  = &CurrentFile.Root().Get<gorgon::DataArray>(index++);
		humanInfo	  = &CurrentFile.Root().Get<gorgon::DataArray>(index++);
		levelingInfo  = &CurrentFile.Root().Get<gorgon::DataArray>(index++);
		//...


		//general
		index = 0;
		TBCapDnm.Value = generalInfo->getFloat(index++);
		wildlingDS.Value = generalInfo->getFloat(index++);
		wildlingNS.Value = generalInfo->getFloat(index++);
		wildlingWRDnm.Value = generalInfo->getFloat(index++);
		wildlingWDRMul.Value = generalInfo->getFloat(index++);
		retryDelay.Value = generalInfo->getFloat(index++);
		maleTitle.Text = generalInfo->getString(index++);
		femaleTitle.Text = generalInfo->getString(index++);
		WRValue.Value = generalInfo->getFloat(index++);
		WRRange.Value = generalInfo->getFloat(index++);
		townCenterSight.Value = generalInfo->getFloat(index++);
		townCenterBuildRange.Value = generalInfo->getFloat(index++);
		denRage.Value = generalInfo->getFloat(index++);
		pathingLimitMargin.Value = generalInfo->getFloat(index++);
		// stats
		index = 0;
		minStat.Value = statInfo->getInt(index++);
		maxStat.Value = statInfo->getInt(index++);
		maxLvl.Value  = statInfo->getInt(index++);
		wSDR.Value	  = statInfo->getFloat(index++);
		jSDR.Value    = statInfo->getFloat(index++);
		rSDR.Value    = statInfo->getFloat(index++),
		
		// crafting
		index = 0;
		craftingBase.Value  = craftingInfo->getFloat(index++);
		craftingStrM.Value  = craftingInfo->getFloat(index++);
		craftingDexM.Value  = craftingInfo->getFloat(index++);
		craftingIntlM.Value = craftingInfo->getFloat(index++);
		craftingLvlM.Value  = craftingInfo->getFloat(index++);
		
		// gold
		index = 0;
		goldBase.Value    = goldInfo->getFloat(index++);
		goldLvlM.Value    = goldInfo->getFloat(index++);
		goldLvlSqrM.Value = goldInfo->getFloat(index++);
		soldierGoldCost.Value    = goldInfo->getFloat(index++);
		artisanGoldCost.Value = goldInfo->getFloat(index++);

		// happiness
		index = 0;
		happinessBase.Value		  = happinessInfo->getFloat(index++);
		happinessTaxRateMul.Value		  = happinessInfo->getFloat(index++);
		happinessPopMul.Value = happinessInfo->getFloat(index++);
		happinessDiffDenominator.Value = happinessInfo->getFloat(index++);
		happinessTimeMul1.Value		  = happinessInfo->getFloat(index++);
		happinessTimeMul2.Value		  = happinessInfo->getFloat(index++);
		popLim.Value = happinessInfo->getFloat(index++);
		currentHapMod.Value		  = happinessInfo->getFloat(index++);
		currentHapMul.Value		  = happinessInfo->getFloat(index++);
		happinessDeathMod.Value		  = happinessInfo->getFloat(index++);




		// combat
		index = 0;
		dodgeChanceMod.Value	  = combatInfo->getFloat(index++);
		parryCDMod.Value		  = combatInfo->getFloat(index++);
		blockChanceMod.Value	  = combatInfo->getFloat(index++);
		staggerStrDnm.Value		  = combatInfo->getFloat(index++);
		staggerVitDnm.Value		  = combatInfo->getFloat(index++);
		staggerLvlMul.Value		  = combatInfo->getFloat(index++);
		staggerStamDnm.Value	  = combatInfo->getFloat(index++);
		staggerAtckCDDnm.Value	  = combatInfo->getFloat(index++);
		staggerEffctMod.Value	  = combatInfo->getFloat(index++);
		APEffectMod.Value		  = combatInfo->getFloat(index++);
		OSTimeM.Value			  = combatInfo->getFloat(index++);
		archerMinRange.Value	  = combatInfo->getInt(index++);
		rngdAttckEffectMod.Value  = combatInfo->getFloat(index++);
		rngedMissChanceDnm.Value  = combatInfo->getFloat(index++);
		rngedMissChanceAccM.Value = combatInfo->getFloat(index++);
		rngedMissChanceLvlM.Value = combatInfo->getFloat(index++);

		// human
		index = 0;
		HPBase.Value	= humanInfo->getFloat(index++);
		HPVitM.Value	= humanInfo->getFloat(index++);
		HPLvlM.Value	= humanInfo->getFloat(index++);
		stamBase.Value	= humanInfo->getFloat(index++);
		stamVitM.Value	= humanInfo->getFloat(index++);
		stamStrM.Value	= humanInfo->getFloat(index++);
		stamLvlM.Value	= humanInfo->getFloat(index++);
		mvmntBase.Value = humanInfo->getFloat(index++);
		mvmntSpeM.Value = humanInfo->getFloat(index++);
		mvmntLvlM.Value = humanInfo->getFloat(index++);
		DSBase.Value    = humanInfo->getFloat(index++);
		DSVitM.Value	= humanInfo->getFloat(index++);
		DSIntlM.Value	= humanInfo->getFloat(index++);
		DSLvlM.Value	= humanInfo->getFloat(index++);
		NSBase.Value	= humanInfo->getFloat(index++);
		NSVitM.Value	= humanInfo->getFloat(index++);
		NSIntlM.Value	= humanInfo->getFloat(index++);
		NSLvlM.Value	= humanInfo->getFloat(index++);
		fmlStr.Value	= humanInfo->getFloat(index++);
		fmlDex.Value	= humanInfo->getFloat(index++);
		fmlAcc.Value	= humanInfo->getFloat(index++);
		fmlSpe.Value	= humanInfo->getFloat(index++);
		fmlInlt.Value	= humanInfo->getFloat(index++);
		fmlVit.Value	= humanInfo->getFloat(index++);
		mlStr.Value		= humanInfo->getFloat(index++);
		mlDex.Value		= humanInfo->getFloat(index++);
		mlAcc.Value		= humanInfo->getFloat(index++);
		mlSpe.Value		= humanInfo->getFloat(index++);
		mlIntl.Value	= humanInfo->getFloat(index++);
		mlVit.Value		= humanInfo->getFloat(index++);
		statDenominator.Value=humanInfo->getFloat(index++);
		dodgeBase.Value=humanInfo->getFloat(index++);
		dodgeAccMul.Value=humanInfo->getFloat(index++);
		dodgeIntlMul.Value=humanInfo->getFloat(index++);
		dodgeLvlMul.Value=humanInfo->getFloat(index++);

		// leveling
		index = 0;
		XPIntlMod.Value	  = levelingInfo->getFloat(index++);
		XPIntlDnm.Value   = levelingInfo->getFloat(index++);
		sldrLvlCap.Value  = levelingInfo->getInt(index++);
		artsnLvlCap.Value = levelingInfo->getInt(index++);
		nxtLvlBase.Value  = levelingInfo->getFloat(index++);
		nxtLvlIncre.Value = levelingInfo->getFloat(index++);
		nxtLvlM.Value     = levelingInfo->getFloat(index++);
		XPMul.Value     = levelingInfo->getFloat(index++);

	}

	widgets::FullscreenPanel toplevel;
	widgets::Tabpanel navigation;
	FileHandler file;



	widgets::LinearOrganizer editororganizer;

	// SDR = Stamina Drain Rate
	// w = walking, j = jogging, r = running
	// M = Multiplier
	// Mod = Modifier
	// Dnm = Denominator
	// AP = Armor Pierce
	// DS = Day Sight, NS = Night Sight
	// WR = Wander Range

	widgets::Numberbox<int> // stats
						    minStat, 
							maxStat,
							maxLvl, 

							// combat 
							archerMinRange, 

							// leveling
							sldrLvlCap, 
							artsnLvlCap;

	widgets::Textbox //general
		             maleTitle,
					 femaleTitle;

	widgets::Numberbox<float> //general
							  TBCapDnm,
							  wildlingDS,
							  wildlingNS,
							  wildlingWRDnm,
							  wildlingWDRMul,
							  retryDelay,
							  WRValue,
							  WRRange,
							  townCenterSight,
							  townCenterBuildRange,
							  denRage,
							  pathingLimitMargin,

							  //stats
							  wSDR,
							  jSDR,
							  rSDR, 

							  //crafting
							  craftingBase, 
							  craftingStrM,
							  craftingDexM, 
							  craftingIntlM,
							  craftingLvlM, 

							  // gold
							  goldBase, 
							  goldLvlM, 
							  goldLvlSqrM, 
							  soldierGoldCost,
							  artisanGoldCost,

							  // happiness
							  happinessBase, 
							  happinessTaxRateMul,
							  happinessPopMul,
							  happinessDiffDenominator,
							  happinessTimeMul1,
							  happinessTimeMul2,
							  popLim,
							  currentHapMod, 
							  currentHapMul,
							  happinessDeathMod,

							  // combat
							  dodgeChanceMod,
							  parryCDMod, 
							  blockChanceMod, 
							  staggerVitDnm, 
							  staggerStrDnm, 
							  staggerLvlMul, 
							  staggerStamDnm,
							  staggerAtckCDDnm, 
							  staggerEffctMod, 
							  APEffectMod, 
							  OSTimeM,
							  rngdAttckEffectMod,
							  rngedMissChanceDnm,
							  rngedMissChanceAccM,
							  rngedMissChanceLvlM, 

							  // human
							  HPBase,
							  HPVitM, 
							  HPLvlM, 
							  stamBase,
							  stamVitM,
							  stamStrM, 
							  stamLvlM, 
							  mvmntBase,
							  mvmntSpeM,
							  mvmntLvlM,
							  DSBase, 
							  DSVitM,
							  DSIntlM,
							  DSLvlM,
							  NSBase,
							  NSVitM,
							  NSIntlM,
							  NSLvlM,
							  fmlStr,
							  fmlDex,
							  fmlAcc,
							  fmlSpe, 
							  fmlInlt, 
							  fmlVit,
							  mlStr,
							  mlDex,
							  mlAcc,
							  mlSpe,
							  mlIntl,
							  mlVit,
							  statDenominator,
							  dodgeBase,
							  dodgeAccMul,
							  dodgeIntlMul,
							  dodgeLvlMul,

							  // leveling
							  XPIntlMod, 
							  XPIntlDnm,
							  nxtLvlBase,
							  nxtLvlIncre, 
							  nxtLvlM,
							  XPMul;
	//...

	gorgon::File CurrentFile;
	gorgon::DataArray *generalInfo;
	gorgon::DataArray *statInfo;
	gorgon::DataArray *craftingInfo;
	gorgon::DataArray *goldInfo;
	gorgon::DataArray *happinessInfo;
	gorgon::DataArray *combatInfo;
	gorgon::DataArray *humanInfo;
	gorgon::DataArray *levelingInfo;

	bool changed;
	enum {
		action_none,
		action_newfile,
		action_loadfile,
		action_quit
	} actionafter;
};
