//antonior.software@gmail.com
//https://antonior-software.blogspot.com/

#include "Windows.h"

#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
#include <vector>
#include <iomanip>

using namespace std;

bool _Find(std::string find_me, std::string text)
{
	if(text.find(find_me)!=std::string::npos) return true;
	else return false;
}

int _Find_I(std::string find_me, std::string text)
{
	int i = text.find(find_me);

	if(i==std::string::npos) return -1;
	else return i;
}

int GetValue(std::string text)
{
	//fog_far_dist		= 49.0f;
	//f fog_far_dist = 2.000000;

	int i = _Find_I("=",text);

	if(i>=0)
	{
		std::stringstream stream(text.substr(i+1,text.size()-(i+1)));

		//cout << stream.str() << std::endl;
		
		int value;

		if(stream >> value)
		{
			//cout << "value - " << value << std::endl;
			return value;
		}
	}	

	return -1;
}

float fog_near_dist	= 1.0f;
float fog_far_dist = 1.0f;

float fog_lowdetail_near_dist = 1.0f;
float fog_lowdetail_far_dist = 1.0f;

float frustum_width	= 1.0f;
float frustum_height = 1.0f;

float fog_pp = 0.0f;//compensate camera max distance moving fog

std::string format = "old";//float value formating differs between original and LOA, probably not important

bool ProcessFile(std::string file, int i)
{
	std::cout << i << " : " << file << std::endl;

	int moods_opened = 0;
	int moods_closed = 0;
	
	std::ifstream file_in(file.c_str());
	if(!file_in.is_open())
	{
		cout << "Failed to open " << file << "." << std::endl;
		return false;
	}	

	std::stringstream out;	
	std::string line;

	int line_count = 0;

	bool ms_open = false;
	bool frustum = false;

	std::vector<std::string> mood_setting;//store values here for current mood

	while(std::getline(file_in,line))
	{
		std::string mood_name = "#";

		if(_Find("mood_name",line)) mood_name = line;

		if(_Find("[mood_setting*]",line))
		{
			if(!ms_open)
			{
				ms_open = true;
				moods_opened++;
			}
			else
			{
				cout << "ERROR - [mood_setting*] not closed. " << line_count << "/" << mood_name << std::endl;
				return false;
			}
		}
		else if(!line.empty() && line[0]=='}' && ms_open)//WARNING: this is not bulletproof, so it should stop if something is wrong
		{
			//finished reading mood settings -> save
			for(unsigned int i=0;i<mood_setting.size();i++)
			{
				if(!frustum && i==1)
				{
					if(mood_setting[i]!="{\n")
					{
						cout << "ERROR - " << line_count << "/" << mood_name << std::endl;
						return false;
					}

					//{
					out << mood_setting[i];

					//add default (45,60) values at beginning of mood_settings if there were none originally
					out << "\t[frustum]" << std::endl;
					out << "\t{" << std::endl;
					if(format=="old")
					{
						out << "\t\tfrustum_height =\t" << (int)(60*frustum_height) << ".0f;" << std::endl;
						out << "\t\tfrustum_width =\t\t" << (int)(45*frustum_width) << ".0f;" << std::endl;
					}
					else
					{
						out << "\t  f frustum_height =\t\t" << (int)(60*frustum_height) << ".000000;" << std::endl;
						out << "\t  f frustum_width =\t\t" << (int)(45*frustum_width) << ".000000;" << std::endl;
					}
					out << "\t}" << std::endl;
					out << std::endl;
				}
				else
					out << mood_setting[i];
			}

			//reset
			mood_setting.clear();
			ms_open = false;
			frustum = false;

			moods_closed++;
		}

		//LOA
		//f fog_far_dist = 2.000000;
		//f fog_lowdetail_far_dist = 1.000000;
		//f fog_lowdetail_near_dist = 0.000000;
		//f fog_near_dist = 0.000000;

		//f frustum_height = 60.000000;
		//f frustum_width = 45.000000;
		if(
			_Find("f fog_near_dist",line) ||
			_Find("f fog_far_dist",line) ||
			_Find("f fog_lowdetail_near_dist",line) ||
			_Find("f fog_lowdetail_far_dist",line) ||
			_Find("f frustum_width",line) ||
			_Find("f frustum_height",line)
			)
		{
			format = "new";

			int i = _Find_I("=",line);			

			if(i>0)
			{
				std::string left = line.substr(0,i+1);

				//cout << left << "|" << std::endl;

				int value = GetValue(line);

				if(value>=0)
				{
					float result = value;

					if(_Find("fog_near_dist",line))					result = value*fog_near_dist + fog_pp;
					else if(_Find("fog_far_dist",line))				result = value*fog_far_dist + fog_pp;
					else if(_Find("fog_lowdetail_near_dist",line))	result = value*fog_lowdetail_near_dist + fog_pp;
					else if(_Find("fog_lowdetail_far_dist",line))	result = value*fog_lowdetail_far_dist + fog_pp;
					else if(_Find("frustum_width",line))
					{
						result = value*frustum_width;
						frustum = true;
					}
					else if(_Find("frustum_height",line))
					{
						result = value*frustum_height;
						frustum = true;
					}

					if(ms_open)
					{
						std::stringstream tmp;
						tmp << left << " " << (int)result << ".000000;" << std::endl;
						mood_setting.push_back(tmp.str());
					}
					else
					{
						cout << "#ERROR:ms_open - " << line_count << "/" << mood_name << std::endl;
						return false;
					}
				}
				else
				{
					cout << "#ERROR:1 - " << line_count << "/" << mood_name << std::endl;
					return false;
				}
			}
			else
			{
				cout << "#ERROR:2 - " << line_count << "/" << mood_name << std::endl;
				return false;
			}
		}
		//DS
		//fog_near_dist		= 30.0f;
		//fog_far_dist		= 49.0f;
		//fog_lowdetail_near_dist	= 30.0f;
		//fog_lowdetail_far_dist	= 45.0f;

		//frustum_width		= 45.0f;
		//frustum_height	= 60.0f;
		else if(
			_Find("fog_near_dist",line) ||
			_Find("fog_far_dist",line) ||
			_Find("fog_lowdetail_near_dist",line) ||
			_Find("fog_lowdetail_far_dist",line) ||			
			_Find("frustum_width",line) ||
			_Find("frustum_height",line)
			)
		{
			format = "old";

			int i = _Find_I("=",line);			

			if(i>0)
			{
				std::string left = line.substr(0,i+1);

				//cout << left << "|" << std::endl;

				int value = GetValue(line);

				if(value>=0)
				{
					float result = value;

					if(_Find("fog_near_dist",line))					result = value*fog_near_dist + fog_pp;
					else if(_Find("fog_far_dist",line))				result = value*fog_far_dist + fog_pp;
					else if(_Find("fog_lowdetail_near_dist",line))	result = value*fog_lowdetail_near_dist + fog_pp;
					else if(_Find("fog_lowdetail_far_dist",line))	result = value*fog_lowdetail_far_dist + fog_pp;
					else if(_Find("frustum_width",line))
					{
						result = value*frustum_width;
						frustum = true;
					}
					else if(_Find("frustum_height",line))
					{
						result = value*frustum_height;
						frustum = true;
					}

					if(ms_open)
					{
						std::stringstream tmp;
						tmp << left << " " << (int)result << ".0f;" << std::endl;
						mood_setting.push_back(tmp.str());
					}
					else
					{
						cout << "#ERROR:ms_open - " << line_count << "/" << mood_name << std::endl;
						return false;
					}
				}
				else
				{
					cout << "#ERROR:11 - " << line_count << "/" << mood_name << std::endl;
					return false;
				}
			}
			else
			{
				cout << "#ERROR:22 - " << line_count << "/" << mood_name << std::endl;
				return false;
			}
		}
		else
		{
			if(ms_open)
			{
				std::stringstream tmp;
				tmp << line << std::endl;
				mood_setting.push_back(tmp.str());
			}
			else out << line << std::endl;
		}

		line_count++;
	}

	file_in.close();

	std::ofstream file_out(file.c_str());
	if(!file_out.is_open())
	{
		cout << "Failed to create " << file << "." << std::endl;
		return false;
	}

	file_out << out.str();
	file_out.close();

	std::cout << "Moods opened/closed - " << moods_opened << "/" << moods_closed  << std::endl;

	std::cout << "...OK" << std::endl;

	return true;
}

int main(int argc, char** argv)
{
	//open file list for reading

	std::ifstream file_list("file_list.txt");
	if(!file_list.is_open())
	{
		cout << "Failed to open \"file_list.txt\"." << std::endl;
		return 1;
	}	

	int i = 1;
	std::string line;
	
	while(std::getline(file_list,line))
	{
		if(line.size()>0 && line[0]==';')
		{
			//comment
		}
		else if(_Find("fog_near_dist",line))
		{
			std::string name;
			std::stringstream stream(line);

			if(!(stream >> name >> fog_near_dist))
			{
				cout << "#ERROR:variable" << std::endl;
				break;
			}
		}
		else if(_Find("fog_far_dist",line))
		{
			std::string name;
			std::stringstream stream(line);

			if(!(stream >> name >> fog_far_dist))
			{
				cout << "#ERROR:variable" << std::endl;
				break;
			}
		}
		else if(_Find("fog_lowdetail_near_dist",line))
		{
			std::string name;
			std::stringstream stream(line);

			if(!(stream >> name >> fog_lowdetail_near_dist))
			{
				cout << "#ERROR:variable" << std::endl;
				break;
			}
		}
		else if(_Find("fog_lowdetail_far_dist",line))
		{
			std::string name;
			std::stringstream stream(line);

			if(!(stream >> name >> fog_lowdetail_far_dist))
			{
				cout << "#ERROR:variable" << std::endl;
				break;
			}
		}
		else if(_Find("frustum_width",line))
		{
			std::string name;
			std::stringstream stream(line);

			if(!(stream >> name >> frustum_width))
			{
				cout << "#ERROR:variable" << std::endl;
				break;
			}
		}
		else if(_Find("frustum_height",line))
		{
			std::string name;
			std::stringstream stream(line);

			if(!(stream >> name >> frustum_height))
			{
				cout << "#ERROR:variable" << std::endl;
				break;
			}
		}
		else if(_Find("fog++",line))
		{
			std::string name;
			std::stringstream stream(line);

			if(!(stream >> name >> fog_pp))
			{
				cout << "#ERROR:variable" << std::endl;
				break;
			}
		}
		else if(line.substr(line.size()-4,4)==".gas")
		{
			if(!ProcessFile(line,i)) break;

			i++;
		}		
	}

	file_list.close();

	system("pause");

	return 1;
}

//GUI SCALE

/*
std::string Space(std::string text)
{
	//rect = 228,278,250,323;
	//rect   228 278 250 323

	for(unsigned int i=0;i<text.size();i++)
		if(text[i]=='=' || text[i]==',' || text[i]==';')
			text[i] = ' ';

	return text;
}

bool ProcessFile(std::string file, int i)
{
	std::cout << i << " : " << file << std::endl;	
	
	std::ifstream file_in(file.c_str());
	if(!file_in.is_open())
	{
		cout << "Failed to open " << file << "." << std::endl;
		return false;
	}

	cout << "\"" << file << "\" opened." << std::endl;

	std::stringstream out;	
	std::string line;	

	while(std::getline(file_in,line))
	{
		if(_Find("rect = ",line) && !_Find("//",line))
		{
			std::stringstream stream(Space(line));

			std::string rect;
			int n1, n2, n3, n4;

			if(stream >> rect >> n1 >> n2 >> n3 >> n4)
			{
				out << "\t\trect = " << n1*2 << "," << n2*2 << "," << n3*2 << "," << n4*2 << ";" << std::endl;
			}
			else
			{
				cout << "#ERROR:stream" << std::endl;
				return false;
			}

		}
		else
		{
			out << line << std::endl;
		}
	}

	file_in.close();

	std::ofstream file_out(file.c_str());
	if(!file_out.is_open())
	{
		cout << "Failed to create " << file << "." << std::endl;
		return false;
	}

	file_out << out.str();
	file_out.close();

	std::cout << "...OK" << std::endl;

	return true;
}

int main(int argc, char** argv)
{
	//open file list for reading

	std::ifstream file_list("ui_file_list.txt");
	if(!file_list.is_open())
	{
		cout << "Failed to open \"file_list.txt\"." << std::endl;
		return 1;
	}

	cout << "\"ui_file_list.txt\" opened." << std::endl;

	int i = 1;
	std::string file;

	while(std::getline(file_list,file))
	{
		if(file.size()>4 && file.substr(file.size()-4,4)==".gas")
		{
			if(!ProcessFile(file,i)) break;

			i++;
		}		
	}

	file_list.close();

	system("pause");

	return 1;
}
*/