#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include "Player.h"
#include <Windows.h>

using namespace std;

// The Main Game
int Game(Player* myne);

// Necessary Evil to Break Out the Commands given into a vector
void SplitString(string* s, vector<string>* v);

// Sub-Functions to Clean-up the Game Function
bool deliverPaper(string* item, Player* p);
void printInventory(Player* p);
void eatFood(string* item, Player* p);
void branchDrop(string* item, Player* p);
void barkDrop(string* item, Player* p);
void fillBucket(string* item, Player* p);
void fillPot(string* item, Player* p);
void peelBranches(string* item, Player* p);
void readSlate(string* item, Player* p);

int main() {
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	
	HWND hwnd = GetConsoleWindow(); RECT rect = { 0, 0, 960, 480 };
	MoveWindow(hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
	
	SetConsoleTextAttribute(hConsole, 10);
	std::cout << "Welcome to my knock-off game dealing with the Anime & Light Novel 'Ascendance of A Bookworm.'\n" 
		<< "You are Myne, a young girls who was born and died in our world.\n" 
		<< "She was on her path to be a librarian, but was reincarnated in a world where only the wealthy have books.\n\n"
		<< "Goal: Make some paper and begin a path to printing books for everyone!\n";

	SetConsoleTextAttribute(hConsole, 15);
	// Map GameMap; // Create the GameWorld	-- But Do I need to, if the map is already being created as part of Player?
	Player* WelcomePlayerOne = new Player(); //Create standard Player class
	
	int turn = Game(WelcomePlayerOne);

	cout << "\n\nYou played the game for a total of " << turn << " turns.\n\n";

	std::system("pause");
	return 0;
}

void SplitString(string* s, vector<string>* v) {
	string temp = "";
	for (int i = 0; i < s->length(); i++) {
		if ((*s)[i] == ' ') {
			v->push_back(temp);
			temp = "";
		} else { temp.push_back((*s)[i]); }
	}
	v->push_back(temp);
}

int Game(Player* myne) {
	vector<string> commandList = { "LOOK", "READ", "TAKE", "PICKUP", "PEEL", "FILL", "PLACE", "PUT", "DROP", "EAT", "DELIVER", "INVENTORY" };
	vector<string> movementList = { "NORTH", "SOUTH", "EAST", "WEST" };
	vector<string> playerEntry;
	string uCommand = "F";
	int turn = 1;
	
	
	while (uCommand != "QUIT") {
		playerEntry.clear();
		string pathBlocked = "\n\nThat path is blocked.\n\n";
		
		std::cout << "\n\n\nTurn: " << turn << endl;
		std::cout << "You are located in the "; myne->pLoc->pRoomName();
		if (!myne->pLoc->descriptionProvided()) {
			myne->pLoc->pRoomDesc();
			myne->pLoc->publishRoomItemList();
		}
		std::cout << "What are you going to do?\t(QUIT to exit) > ";

		getline(cin, uCommand);
		transform(uCommand.begin(), uCommand.end(), uCommand.begin(), ::toupper);
		SplitString(&uCommand, &playerEntry);
		
		// Movement commands
		if (uCommand.find("NORTH") == 0) { if (myne->pLoc->pNorth != 0) { myne->pLoc = myne->pLoc->pNorth; } else { std::cout << pathBlocked; } }
		else if (uCommand.find("EAST") == 0) { if (myne->pLoc->pEast != 0) { myne->pLoc = myne->pLoc->pEast; } else { std::cout << pathBlocked; } }
		else if (uCommand.find("SOUTH") == 0) { if (myne->pLoc->pSouth != 0) { myne->pLoc = myne->pLoc->pSouth; } else { std::cout << pathBlocked; } }
		else if (uCommand.find("WEST") == 0) { if (myne->pLoc->pWest != 0) { myne->pLoc = myne->pLoc->pWest; } else { std::cout << pathBlocked; } }
		
		// Item Manipulation -- {"LOOK", "READ", "TAKE", "PICKUP", "PEEL", "FILL", "PLACE", "PUT", "DROP", "EAT", "DELIVER", "INVENTORY"}
		else if (uCommand.find("LOOK") == 0) {
				myne->pLoc->pRoomDesc();
				myne->pLoc->publishRoomItemList(); }
		
		else if (uCommand.find("READ") == 0) {
			if (playerEntry[1] == "SLATE") { readSlate(&playerEntry[1], myne); }
			else { std::cout << "\nYou cannot read that.\n"; } }
		
		else if ((uCommand.find("TAKE") == 0) || (uCommand.find("PICKUP") == 0)) { myne->pPickup(&playerEntry[1]); }
		
		else if (uCommand.find("PEEL") == 0) {
			if (playerEntry[1] == "STEAMED_BRANCHES") { peelBranches(&playerEntry[1], myne); }
			else if (playerEntry[1] == "BRANCHES") { std::cout << "\nYou must steam the branches first in a pot of water.\n"; }
			else { std::cout << "\nYou cannot peel that.\n"; } }
		
		else if (uCommand.find("FILL") == 0) {
			if (playerEntry[1] == "BUCKET") { fillBucket(&playerEntry[1], myne); }
			else if (playerEntry[1] == "POT") { fillPot(&playerEntry[1], myne); }
			else { std::cout << "\nYou cannot fill that.\n"; } }

		else if ((uCommand.find("PLACE") == 0) || (uCommand.find("PUT") == 0) || (uCommand.find("DROP") == 0)) {
			if (playerEntry[1] == "BRANCHES") { branchDrop(&playerEntry[1], myne); } 
			else if (playerEntry[1] == "BARK") { barkDrop(&playerEntry[1], myne); } 
			else { 
				myne->pDrop(&playerEntry[1]);
				std::cout << "\nYou've placed " << playerEntry[1] << " on the ground.\n";
			} }
		
		else if (uCommand.find("EAT") == 0) {
			if ((playerEntry[1] == "POUNDCAKE") || (playerEntry[1]  == "MUSHROOMS")) { eatFood(&playerEntry[1], myne);
			} else { std::cout << "\nYou cannot eat " << playerEntry[1] << "\n"; } }
		
		else if (uCommand.find("DELIVER") == 0) {
			if (playerEntry[1] == "PAPER") { if (deliverPaper(&playerEntry[1], myne)) { return turn; } 
			} else { "\n\nYou don't have any paper to deliver!\n"; } }
		
		else if (uCommand.find("INVENTORY") == 0) { printInventory(myne); }			

		// Quit Commands
		else if (uCommand == "QUIT" || uCommand == "Q") { return turn; }

		// Help Command
		else if (uCommand == "help") {
			for (int i = 0; i < commandList.size(); i++) { std::cout << commandList[i] << endl; }
			for (int j = 0; j < movementList.size(); j++) { std::cout << movementList[j] << endl; } }
		
		// Invalid entry, tell the player about help command
		else { std::cout << "\nInvalid Input\n" <<  "If you need help, type help\n\n"; }

		turn++;
	}
}

bool deliverPaper(string* item, Player* p) {
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (p->pLoc->DeliverPaper() && (p->pItemPresent(item) || p->pLoc->pRoomItemPresent(item))) { 
		SetConsoleTextAttribute(hConsole, 10);
		std::cout << "\n\n\nCongratulations! You've won the game!\n\n"; 
		SetConsoleTextAttribute(hConsole, 15);
		return true; }
	else if (!p->pLoc->DeliverPaper()) { std::cout << "\n You cannot deliver the paper here!\n"; return false; }
	else if (!p->pLoc->pRoomItemPresent(item)) { std::cout << "\n You do not have paper to deliver!\n"; return false; }
	else if (!p->pItemPresent(item)) { std::cout << "\n You do not have paper to deliver!\n"; return false; }
	else { return false; }
}

void printInventory(Player* p) {
	if (p->pInventory.size() == 0) { std::cout << "\nYou have no items in your inventory.\n"; }
	else if (p->pInventory.size() == 1) { std::cout << "\nYou have one item in your inventory: " << p->pInventory[0] << endl; }
	else {
		std::cout << "\nYou have the following items in your inventory:\n";
		for (int i = 0; i < p->pInventory.size(); i++) { std::cout << p->pInventory[i] << endl; }
	}
}

void eatFood(string* item, Player* p) {
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if ((*item == "POUNDCAKE") || (*item == "MUSHROOMS")) {
		if (*item == "POUNDCAKE") {
			if (p->pItemPresent(item) || p->pLoc->pRoomItemPresent(item)) { 
				p->Consume(item); 
				SetConsoleTextAttribute(hConsole, 10);
				std::cout << "The pound cake tasted amazing.";
				SetConsoleTextAttribute(hConsole, 15); }
			else { std::cout << "You don't have the item to eat."; }
		} else if (*item == "MUSHROOMS") {
			if (p->pItemPresent(item) || p->pLoc->pRoomItemPresent(item)) { 
				p->Consume(item); 
				SetConsoleTextAttribute(hConsole, 11); 
				std::cout << "The mushrooms tasted delicious.";
				SetConsoleTextAttribute(hConsole, 15); }
			else { std::cout << "You don't have the item to eat."; } } } }

void branchDrop(string* item, Player* p) {
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 
	if (*item == "BRANCHES") {
		string requiredItem = "WATER_POT";
		string createdItem = "STEAMED_BRANCHES";
		if (p->pItemPresent(&requiredItem) || p->pLoc->pRoomItemPresent(&requiredItem)) {
			p->Consume(&requiredItem); // Destroy WATER_POT
			p->Consume(item); // Destroy BRANCHES
			p->AddItem(&createdItem); // Create STEAMED_BRANCHES
			SetConsoleTextAttribute(hConsole, 10);
			std::cout << "\nThe Branches have been streamed. You now have STREAMED_BRANCHES in your inventory.\n";
			SetConsoleTextAttribute(hConsole, 15);
		}
		else { p->pDrop(item); } } }

void barkDrop(string* item, Player* p) {
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (*item == "BARK") {
		string requiredItem = "BOARD";
		string createdItem = "PAPER";
		if (p->pItemPresent(&requiredItem) || p->pLoc->pRoomItemPresent(&requiredItem)) {
			p->Consume(&requiredItem); // Destroy BOARD
			p->Consume(item); // Destroy BARK
			p->AddItem(&createdItem); // Create PAPER
			SetConsoleTextAttribute(hConsole, 10);
			std::cout << "\nYou now have made paper. It is in your inventory.\n";
			SetConsoleTextAttribute(hConsole, 15);
		} else { p->pDrop(item); }
	} else {
		p->pDrop(item);
		std::cout << "\nYou've placed " << item << " on the ground.\n"; } }

void fillBucket(string* item, Player* p) {
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (*item == "BUCKET") {
		if (p->pLoc->fillWater()) {
			string createdItem = "WATER_BUCKET";
			if (p->pItemPresent(item) || p->pLoc->pRoomItemPresent(item)) {
				p->Consume(item); // No longer need the bucket, destroying...
				p->AddItem(&createdItem);
				SetConsoleTextAttribute(hConsole, 10);
				std::cout << "\nYou've filled the bucket with water and now have WATER_BUCKET, it is in your inventory.\n";
				SetConsoleTextAttribute(hConsole, 15);
			}
			else if (!p->pItemPresent(item) || !p->pLoc->pRoomItemPresent(item)) {
				std::cout << "\nYou do not have a bucket to fill.\n";
			}
		}
		else if (!p->pLoc->fillWater()) {
			if (p->pItemPresent(item) || p->pLoc->pRoomItemPresent(item)) {
				std::cout << "\nYou cannot fill the bucket here.\n";
			}
		}
	}
}

void fillPot(string* item, Player* p) {
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (*item == "POT") {
		string requiredItem = "WATER_BUCKET";
		string createdItem = "WATER_POT";
		if (p->pItemPresent(item) || p->pLoc->pRoomItemPresent(item)) {
			if (p->pItemPresent(&requiredItem) || p->pLoc->pRoomItemPresent(&requiredItem)) {
				p->Consume(&requiredItem); // No longer need the WATER_BUCKET, destroying...
				p->Consume(item); // No longer need the POT, destroying...
				p->AddItem(&createdItem);  // Created WATER_POT...
				p->pDrop(&createdItem); // Place WATER_POT on ground...
				SetConsoleTextAttribute(hConsole, 10);
				std::cout << "\nThe Pot is now filled with water. The WATER_POT is on the ground and filled with water. The water is boiling, as if from magic.\n";
				SetConsoleTextAttribute(hConsole, 15);
			}
			else if (!p->pItemPresent(&requiredItem) || !p->pLoc->pRoomItemPresent(&requiredItem)) {
				std::cout << "\nYou don't have a bucket filled with water.\n";
			}
		}
		else if (!p->pItemPresent(item) || !p->pLoc->pRoomItemPresent(item)) {
			std::cout << "\nYou don't have a pot to fill with water.\n";
		}
	}
}

void peelBranches(string* item, Player* p) {
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (*item == "STEAMED_BRANCHES") {
		string requiredItem1 = "KNIFE";
		if ((p->pItemPresent(&requiredItem1) || p->pLoc->pRoomItemPresent(&requiredItem1))) {
			if ((p->pItemPresent(item) || p->pLoc->pRoomItemPresent(item))) {
				string createItem = "BARK";
				p->Consume(item); // No longer need the steamed branches, destroying...
				p->Consume(&requiredItem1); // No longer need the knife, destroying...
				p->AddItem(&createItem);
				SetConsoleTextAttribute(hConsole, 10);
				std::cout << "\nYou've peeled the branches and now have bark, it is in your inventory.\n";
				SetConsoleTextAttribute(hConsole, 15);
			}
			else { std::cout << "You don't have any Steamed Branches.\n"; }
		}
		else { std::cout << "\nYou cannot peel the branches.\n"; }
	}
}

void readSlate(string* item, Player* p) {
	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	if (p->pItemPresent(item) || p->pLoc->pRoomItemPresent(item)) {
		SetConsoleTextAttribute(hConsole, 10);
		std::cout << "\n\nThat is right! I am not originally from this world. And in order for me to read books, I need paper. So I have to make it.\n\n";
		std::cout << "If I can make some, maybe Benno will buy some from me, so that I can afford to make more paper.\n";
		SetConsoleTextAttribute(hConsole, 12);
		std::cout << "\n\nNeeded items: knife, bucket, pot, branches, board\n";
		SetConsoleTextAttribute(hConsole, 14);
		std::cout << "The process to make paper should be as follows:\n"
				<< "\t1. Take items to river or forest\n"
				<< "\t2. Fill Bucket with water at river\n"
				<< "\t3. Fill Pot with water\n"
				<< "\t4. Put branches in pot\n"
				<< "\t5. Take steamed branches from pot\n"
				<< "\t6. Peel branches to get bark\n"
				<< "\t7. Put bark on board to dry\n"
				<< "\t8. Pickup paper and deliver to Mr. Benno in his office at the Gilberta Company\n";
		SetConsoleTextAttribute(hConsole, 15);
	} else { std::cout << "\nYou need to have access to the slate board in order to read it.\n"; }
}
