#include "SaveLoad.h"
#include "Main.h"
#include <time.h>
#include <ctime>
#include <iomanip>

using namespace std;

SaveLoad::SaveLoad()
{
	ResetVariables();
}

void SaveLoad::SaveGame(std::string& aFileName)
{
	//Make sure fileName is valid
	if(aFileName.length() > 0)
	{
		fstream file(aFileName, ios::out);
		file.clear();

		//Upadates playing time/last time played
		string strElapsedTime = GetTimes();
		string strScoreAndMax;
		//Gets score / maxScore
		strScoreAndMax = to_string((long long)Main::Get()->GetScore());
		strScoreAndMax.append(" / " + to_string((long long)Main::Get()->GetMaxScore()));

		file << strElapsedTime << endl
			 << mDateTime //Don't need endl here for some reason
			 << strScoreAndMax << endl
			 << mElapsedTime << endl
			 << mSeed << endl
			 << mActionCount << endl;
			 

		for (list<string>::iterator i = mActions.begin(); i != mActions.end(); ++i)
		{
			file << *i << endl;
		}

	}
}

void SaveLoad::LoadGame(const std::string& aFileName)
{
	if(aFileName.length() > 0)
	{
		in.open(aFileName);

		//Reset game to inital state
		Main* main = Main::Get();
		main->Reset(false);
		ResetVariables();

		//Turn off input/output
		main->mOut.ClearScreen();
		main->mOut.Text("Loading... Please Wait.");
		main->mIn.Disable();
		main->mOut.Disable(true);

		//Get past stuff I dont need (should figure out how to move the buffer down 3 lines)
		in.get(str, length);
		in.get();
		in.get(str, length);
		in.get();
		in.get(str, length);
		in.get();

		in >> mElapsedTime;
		in >> mSeed;
		in >> loadActionCount;
		in.get();
	}
}

void SaveLoad::AddAction(std::string aInput)
{
	//Don't need to check aInput, because AddAction is only called (from ActionList) when we hit a valid action
	
	//Don't want to re-save or re-load actions
	//If loading is slow, add more actions don't impact the load here
	if (aInput != "save" &&
		aInput != "load") 
	{
		mActions.push_back(aInput);
		++mActionCount;
	}
}

void SaveLoad::LoadSaveSlot(const std::string& aFileName)
{
	Main* main = Main::Get();
	string tempPlayTime;
	string tempLastPlayed;
	string tempScore;

	string fileName;
	char fileNumb;

	const int length = 100;
	char str[length];

	for (int i = 1; i < 4; ++i)
	{
		//Get the file, must have 1 2 3... at the end of name
		fileNumb = i + '0';
		fileName = aFileName;
		fileName += fileNumb;

		ifstream in(fileName);

		//Get the temp values
		in.get(str, length);
		in.get();
		tempPlayTime = str;

		in.get(str, length);
		in.get();
		tempLastPlayed = str;

		in.get(str, length);
		in.get();
		tempScore = str;

		//Spit them out, with some nice formatting
		//Note: I'm not using main's mOut for text. Saving and loading aren't used in loading so it isn't a problem.

		cout << "*----------------Slot" << i << "----------------*" << endl
			 << setw(13) << left << "|Play Time  : " << setw(24) << left << tempPlayTime << "|" << endl
			 << setw(13) << left << "|Last Played: " << setw(24) << left << tempLastPlayed << "|" << endl
			 << setw(13) << left << "|Score      : " << setw(24) << left << tempScore << "|" << endl
			 << "*-------------------------------------*" << endl << endl << endl;
	}
}

string SaveLoad::GetTimes()
{
	string elapsedTime;

	//Get date and time
	time_t now = time(0);
	mDateTime = ctime(&now);

	//Get elapsed Time
	time(&mEndTime);
	mElapsedTime += difftime(mEndTime, mStartTime);

	//Hours
	if (mElapsedTime / (60 * 60) < 10)
		elapsedTime.append("0");
	elapsedTime.append(to_string(static_cast<long long>(mElapsedTime / (60 * 60))));
	elapsedTime.append(":");

	//Minutes
	if (mElapsedTime / 60 < 10)
		elapsedTime.append("0");
	elapsedTime.append(to_string(static_cast<long long>(mElapsedTime / 60)));
	elapsedTime.append(":");

	//Seconds
	if ((int)mElapsedTime % 60 < 10)
		elapsedTime.append("0");
	elapsedTime.append(to_string(static_cast<long long>((int)mElapsedTime % 60)));

	return elapsedTime;
}

void SaveLoad::ResetVariables()
{
	currentActionCount = 0;
	loadActionCount = 0;
	mActionCount = 0;
	mSeed = unsigned int(time(0));
	srand(mSeed);

	time(&mStartTime);
	mElapsedTime = 0;

	mActions.clear();
}

void SaveLoad::GetNextInput()
{
	Main* main = Main::Get();

	//Run all of the actions, but not last 5
	if(in.get(str, length) && currentActionCount < loadActionCount - 5)
	{
		in.get();
		main->mInput = str;
		++currentActionCount;
	}

	//Run through last 5 actions, showing them
	else
	{
		if (in.eof())
		{
			//Turn input/output on for the last time to get back to play
			main->mIn.Enable();
			main->mOut.Enable(true);
			main->mOut.EndLines(1);
			main->mIn.WaitForKey();
			main->mOut.ClearScreen();

			in.close();

			//Start the game up
			main->Run();
		}
		else if (currentActionCount == loadActionCount - 5)
		{
			main->mIn.Enable();
			main->mOut.Enable(true);

			main->mOut.EndLines(1);
			main->mOut.Text("Game Loaded!");
		}

		LoadLastFive();
	}
}

void SaveLoad::LoadLastFive()
{
	Main* main = Main::Get();

	main->mIn.Enable();
	main->mOut.Enable(true);
	main->mOut.EndLines(1);
	main->mIn.WaitForKey();
	main->mOut.ClearScreen();

	main->mOut.Text("*-- Previously on Nazi Jones Episode 1! --*");
	main->mOut.EndLines(2);

	in.get();

	//Show last moves
	main->mCurrentRoom->ShowDescription();
	main->mOut.EndLines(2);
	main->mOut.Text("> ");
	main->mOut.Text(str);
	main->mOut.EndLines(1);

	//Disable input and clear screen (problem when going to different rooms)
	main->mIn.Disable();
	main->mOut.Disable(true);
	main->mOut.Enable(false);

	//Input last moves
	main->mInput = str;

	++currentActionCount;
}