#pragma once

#include "stdafx.h"

#include "Includes.h"

#include "Defines.h"

#include "BringUp.h"

#include "GUI_DefineFunctions.cpp"

using namespace std;

int WriteLableRules(ofstream& Rules,char* label)
{
   Rules.put('[');
   Rules.write(label,strlen(label));
   Rules.put(']');
   Rules.put('\n');
   
   return 0;
}

int WriteNameRules(ofstream& Rules,char* Name,int i,int j,int Step,int Last_Entry = 0)
{
   Debug << " WriteNameRules ********************** " << Name << " section " << directive[i] << '\n';  
   Rules.put('"');
   Rules.write(Name,strlen(Name));
   Rules.put('"');
   for (unsigned int k = 0;k < (50 - strlen(Name));k++) {
         Rules.put(' ');
   }
   if (Last_Entry == 0) {
      Rules.put(',');
   } else {
      Rules.put(';');
      Rules.put('\n');
   }
	SetArrayValue(i,j,Step,Name);
   return 0;
}

string Get8BitBinaryFlags(ifstream& InputFile,int Hex)
{
   InputFile.seekg(Hex,ios_base::beg);
   int offs1 = InputFile.get();
	string TotalString = BitFlagToString(offs1);

	Debug << " Get8BitBinaryFlags Fired TotalString-offs1 " << TotalString << " " << offs1 << " Hex -> " << Hex << endl;

	return TotalString;
}

string GetBYTE(ifstream& InputFile,int Hex)
{
   int offs1 = 0;
   string TotalString = "0";
	InputFile.seekg(Hex,ios_base::beg);
	offs1 = InputFile.get();
   TotalString = Int2Str(offs1);

	Debug << "GetBYTE Fired Return Value " << TotalString << endl;
   return TotalString;
}

string GetDWORD(ifstream& InputFile,int Hex)
{
   int offs1 = 0;
   int offs2 = 0;
   string ByteOneHex = "0";
   string ByteTwoHex = "0";
   string TotalString = "0";
   InputFile.seekg(Hex,ios_base::beg);
   offs1 = InputFile.get();
   InputFile.seekg(Hex + 1,ios_base::beg);
   offs2 = InputFile.get();
   ByteOneHex = IntToHex(offs1);
   ByteTwoHex = IntToHex(offs2);
   if (offs2 > 0 && offs1 == 0) {
      ByteTwoHex.append("00");
   } else {
      ByteTwoHex.append(ByteOneHex);
      if (offs1 > 0 && offs1 < 16 && offs2 > 16) {
         ByteTwoHex.insert(2,1,'0');
		} else if (offs1 > 0 && offs1 < 16 && offs2 > 0 && offs2 < 16) {
         ByteTwoHex.insert(1,1,'0');
      }
	}
   TotalString = Int2Str(HexToInt(ByteTwoHex));
	Debug << "GetDWORD Fired Return Value " << TotalString << endl;
   return TotalString;
}

int Get_Name_Offset(int i,int j,int Step,ifstream& InputFile,ofstream& Rules)
{
	int Value = 169120 + Str2Int(GetDWORD(InputFile,Get_Hex_Offset(i,j,Step)));
	Debug << Int2Str(Value) << " Int2Str(Value) " << Get_Hex_Offset(i,j,Step) << " Get_Hex_Offset(i,j,Step) " << " .................................................................................. Unit Name" << '\n';
	return Value;
}

int DataRules(int i,int j,int Step,ifstream& InputFile,ofstream& Rules,int Hex)
{
   Debug << " DataRules(int i,int j,int Step,fstream& InputFile,ofstream& Rules) " << '\n';
	string TotalString = "";
   size_t Distance = GetSpaces(i,j,Step);
   int Bytes = GetByteParameters(i,j,Step);
   if (Bytes == 3) {
      TotalString = Get8BitBinaryFlags(InputFile,Hex);
		Debug  << StringToBitFlag(BitFlagToString(StringToBitFlag(TotalString))) << "  " << BitFlagToString(StringToBitFlag(TotalString)) << '\n';
   } else if (Bytes == 1) {
      TotalString = GetDWORD(InputFile,Hex);
   } else if (Bytes == 0) {
      TotalString = GetBYTE(InputFile,Hex);
	}
   if (Bytes == 0 && Str2Int(TotalString) > 240) {
      Debug << TotalString << " Before 0 " << '\n';
      int ValueInt = 256 - Str2Int(TotalString);
      TotalString = "-";
      TotalString.append(Int2Str(ValueInt));
      Debug << TotalString << " After 0 " << '\n';
   }
   if (Bytes == 1 && Str2Int(TotalString) > 60000) {
      Debug << TotalString << " Before 1 " << '\n';
      int ValueInt = 65536 - Str2Int(TotalString);
      TotalString = "-";
      TotalString.append(Int2Str(ValueInt));
      Debug << TotalString << " After 1 " << '\n';
   }
	if (i == 33) {
		TotalString = GetDWORD(InputFile,Hex);
		Debug << TotalString << " i == 33 TotalString " << '\n'; 
		if (Str2Int(TotalString) == 49707) TotalString = "50";
		if (Str2Int(TotalString) == 63697) TotalString = "25";
		Debug << Distance << " <- Distance " << TotalString.length() << " <- TotalString.length()  spaces" << '\n';
		for (unsigned int k = 0;k < (Distance - TotalString.length());k++) {
			Rules.put(' ');
			Debug << k << '\n';
		}
		Rules << TotalString;
		Debug << TotalString << " <- TotalString <--< " << '\n';
		SetArrayValue(i,j, Step,Str2CharArray(TotalString));
	} else {
		Debug << Distance << " <- Distance " << TotalString.length() << " <- TotalString.length()  spaces" << '\n';
		for (unsigned int k = 0;k < (Distance - TotalString.length());k++) {
			Rules.put(' ');
			Debug << k << '\n';
		}
		Debug << TotalString << '\n';
		Debug << Distance << " <- Distance " << TotalString.length() << " <- TotalString.length() after spaces" << '\n';
		Rules << TotalString;
		SetArrayValue(i,j, Step,Str2CharArray(TotalString));
		Debug << TotalString << " <- TotalString <--<" << '\n';
	}
	TotalString = "";
   return 0;
}

int DataRulesInputFile(int i,int j,int Step,ifstream& Item,ifstream& Build,ifstream& Spell,ifstream& Magic,ifstream& Wizard,ifstream& Itemmake,ofstream& Rules)
{
	if (i == 0) {
		DataRules(i,j,Step,Item,Rules,Get_Hex_Offset(i,j,Step));
	} else if (i == 1) {
		DataRules(i,j,Step,Build,Rules,Get_Hex_Offset(i,j,Step));
	} else if (i == 2) {
		DataRules(i,j,Step,Spell,Rules,Get_Hex_Offset(i,j,Step));
	} else if (i == 22 || i == 26 || i == 34 || i == 35 || i == 36) {
		DataRules(i,j,Step,Magic,Rules,Get_Hex_Offset(i,j,Step));
	} else if (i == 30) {
		DataRules(i,j,Step,Itemmake,Rules,Create_Spell_Charges_Costs_Additives[1]);
	} else if (i == 31) {
		DataRules(i,j,Step,Itemmake,Rules,Create_Base_Costs_Additives[1] + Create_Base_Costs_Steps_Additives[Step]);
	} else {
		DataRules(i,j,Step,Wizard,Rules,Get_Hex_Offset(i,j,Step));
	}

	return 0;
}

char* GetNameString(int i,int j,int Step,ifstream& InputFile,ofstream& Rules)
{
	char ItemName[25]={'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'};
	if (Step == 0 && i <= 2) {
		int k = 0;
		for (k = 0;k < 18;k++) {
			InputFile.seekg(Get_Hex_Offset(i,j,Step)+k,ios_base::beg);
			ItemName[k] = char(InputFile.get());
		}
		WriteNameRules(Rules,CopyCharArray(ItemName),i,j,Step); 
	} else if (Step == 0 && i >= 3 && i <= 20) {
		int Name_Offset = Get_Name_Offset(i,j,Step,InputFile,Rules);
		int k = 0;
		for (k = 0;k < 18;k++) {
			InputFile.seekg(Name_Offset+k,ios_base::beg);
			ItemName[k] = char(InputFile.get());
		}
		WriteNameRules(Rules,CopyCharArray(ItemName),i,j,Step); 
	} else if (Step == 0 && i == 21) {
		WriteNameRules(Rules,Overland_Spell_Names[j],i,j,Step); 
	} else if (Step == 0 && i == 22) {
		WriteNameRules(Rules,Hero_Special_Names[j],i,j,Step); 
	} else if (Step == 0 && i == 23) {
		WriteNameRules(Rules,Healing_Name[j],i,j,Step); 
	} else if (Step == 0 && i == 24) {
		WriteNameRules(Rules,Book_Retort_Max_Name[j],i,j,Step); 
	} else if (Step == 0 && i == 25) {
		WriteNameRules(Rules,Mana_Gold_Max_Name[j],i,j,Step); 
	} else if (Step == 0 && i == 26) {
		WriteNameRules(Rules,Wizard_Picks_Names[j],i,j,Step); 
	} else if (Step == 0 && i == 27) {
		WriteNameRules(Rules,Item_Over_Books_Names[j],i,j,Step); 
	} else if (Step == 0 && i == 28) {
		WriteNameRules(Rules,Minimum_City_Distance_Name[j],i,j,Step); 
	} else if (Step == 0 && i == 29) {
		WriteNameRules(Rules,Retort_Effects_Names[j],i,j,Step); 
	} else if (Step == 0 && i == 30) {
		WriteNameRules(Rules,Create_Spell_Charges_Name[j],i,j,Step); 
	} else if (Step == 0 && i == 31) {
		WriteNameRules(Rules,Create_Base_Costs_Name[j],i,j,Step); 
	} else if (Step == 0 && i == 32) {
		WriteNameRules(Rules,Create_Caps_Name[j],i,j,Step); 
	} else if (Step == 0 && i == 33) {
		WriteNameRules(Rules,Destroy_Items_Name[j],i,j,Step); 
	} else if (Step == 0 && i == 34) {
		WriteNameRules(Rules,Spells_Per_Book_Name[j],i,j,Step); 
	} else if (Step == 0 && i == 35) {
		WriteNameRules(Rules,Random_Events_Name[j],i,j,Step); 
	} else if (Step == 0 && i == 36) {
		WriteNameRules(Rules,Map_Generation_Names[j],i,j,Step); 
	} else if (Step == 0 && i == 37) {
		WriteNameRules(Rules,Research_From_Books_Names[j],i,j,Step); 
	} else if (Step == 0 && i == 38) {
		WriteNameRules(Rules,Hero_Join_Names[j],i,j,Step); 
	} else if (Step == 0 && i == 39) {
		WriteNameRules(Rules,Merc_Join_Names[j],i,j,Step); 
	} else if (Step == 0 && i == 40) {
		WriteNameRules(Rules,Item_Sales_Names[j],i,j,Step); 
	} else if (Step == 0 && i == 41)	 {
		WriteNameRules(Rules,Misc_Names[j],i,j,Step); 
	} else if (Step == 0 && i == 42) {
		WriteNameRules(Rules,Food_Bonuses_Names[j],i,j,Step); 
	}

	return "Error Retrieving Name";
}

int WriteDataRules(int i,int j,ifstream& Item,ifstream& Build,ifstream& Spell,ifstream& Magic,ifstream& Wizard,ifstream& Itemmake,ofstream& Rules)
{
	for (int Step = 0;Step < step_max[i];Step++) {
 		if (Step == 0 && i == 0) {
			GetNameString(i,j,Step,Item,Rules);
		} else if (Step == 0 && i == 1) {
			GetNameString(i,j,Step,Build,Rules);
		} else if (Step == 0 && i == 2) {
			GetNameString(i,j,Step,Spell,Rules);
		} else if (Step == 0) {
			GetNameString(i,j,Step,Wizard,Rules);
		} else if (Step != 0) {
			DataRulesInputFile(i,j,Step,Item,Build,Spell,Magic,Wizard,Itemmake,Rules);
			if (Step < step_max[i] - 1) {
				Rules.put(',');
			} else if (Step == step_max[i] - 1){
				Rules << ';' << '\n';
			}
		}
		Debug << "Step Loop " << Int2Str(Step) << '\n';
	}

   return 0;
}

int WriteDataTable(int i,ifstream& Item,ifstream& Build,ifstream& Spell,ifstream& Magic,ifstream& Wizard,ifstream& Itemmake,ofstream& Rules)
{
   for (int j = 0; j < rec_count[i];j++) {
		Debug << "loop j " << Int2Str(j) << '\n';
		WriteDataRules(i,j,Item,Build,Spell,Magic,Wizard,Itemmake,Rules);
   }
   
   return 0;
}


