//We use #pragma once to tell the compiler that we onlt want this
//header compiled once and not every time it is included in something
//We dont need to do this for this particular header because its only
//ever included once, but we do it anyways because it could become an
//issue at a later point.
#pragma once
#include <windows.h>
//We need to include CCharacter.h so that some of our functions that
//take the Character class as a parameter know what they're accepting
#include "CCharacter.h"
//Yeah. Dito.
#include "CWorld.h"
//NOTE: Go away and read CWorld.h first if you dont understand classes
//		or anything else I'm talking about.
#define MAXITEMS 6 //Maximum items allowed
//*** This is our 'CGame' class ***
//This struct will hold all of our data pertaining to game play
//It is simular in design to our structs we used in Version 3.0 but
//there are several key differences.
//1) The structs were defined and acted just as normal variables.
//	 Here we have only the definition of the class. Until we create
//	 an 'instance' of it, we cant do anything with it. You'll see more
//	 about this in main when it happens.
//2) Constructors and Destructors. These are functions that are called
//	 automatically when the class is created and when it is destroyed.
//	 There will be no actual calling of these functions explicitly.
class CGame
{
public:
	//All if the data that is declared as public can be accessed
	//normally just like we did with the structs.
	//I'm going to declare all of the functions 'inline' instead
	//of using a separate file to for the function code. I do this
	//in this case mainly to keep the number of files used to a
	//minimum. In some ways it may be slightly more confusing when
	//trying to understand classes but I hope you can wade through.
	//Try to recognise code snippets from the previous examples here
	//and it will help you determine what is happening.
	//This is the constructor for CGame.
	CGame()
	{
	};
	//Destructor. Boom.
	~CGame()
	{
		//We dont need to do anything when we quit but if we wanted
		//something to happen when CGame went out of scope (which
		//would be when we exit the application) then we would put
		//it in here.
	};
	//************************************************************
	//This function will set the items for the game.
	//************************************************************
	HRESULT LoadItems()
	{
		//Items are loaded the same as always. I strongly suggest that you
		//implement a script loading system for this based on the World
		//description loading one. It would be vastly better.
		strcpy(Item[0].name, "Iron Key");
		Item[0].location_x = 1;
		Item[0].location_y = 2;
		strcpy(Item[1].name, "Book of FireBall");
		Item[1].location_x = 1;
		Item[1].location_y = 1;
		strcpy(Item[2].name, "Bag of Gold");
		Item[2].location_x = 2;
		Item[2].location_y = 0;
		strcpy(Item[3].name, "Whistle");
		Item[3].location_x = 0;
		Item[3].location_y = 1;
		//We're going to use this slot later
		strcpy(Item[4].name, "");
		Item[4].location_x = -2; //We're going to say that -2 is NON-EXISTANT. This is better than
		Item[4].location_y = -2; //   the 0 we had before because 0 is a room... (-1 is the player)
		strcpy(Item[5].name, "Book of PathFinder");
		Item[5].location_x = 0;
		Item[5].location_y = 2;
		return S_OK;
	};
	
	//************************************************************
	//This function will print any items in the room.
	//************************************************************
	HRESULT ShowItems(int x, int y)
	{
		//Now we check to see if somehow the user has walked outside
		//of the map. If we tried to access our Item struct out of
		//bounds then we would have likely crashed our program.
		//Its not possible to walk out of the world in this example
		//but doing this kind of checking is always a good idea.
		if (x < 0 || y < 0 || x >= MAP_WIDTH || y >= MAP_HEIGHT)
			return E_INVALIDARG;
		//print any items IF the item has the same coordinates as the player
		for(int loop = 0; loop < MAXITEMS; loop ++)
		{
			//If not in column 2, row2 (Because this room is too dark to see in...) You have
			//to search to find the items in this room
			if (Item[loop].location_x == x && Item[loop].location_y == y &&
				(x != 2 || y != 0))
			{
				printf("There is a %s here...\n", Item[loop].name);
			}
		}//end for
		return S_OK;
	};
	//************************************************************
	//This function checks what the user types and gets any items
	//if one fitting the description is found.
	//************************************************************
	//NOTE: We take a pointer to the entire Character class instance
	//		as an argument because we have to modify a few of its
	//		variables and this is easier than passing each one in
	//		individually. I'm only going to skim the top (and theory
	//		not the technical aspect) of what we're doing because to
	//		really explain pointers would take more space and time
	//		than I have here.
	//IMPORTANT: We'll be doing a strange new thing here. Instead of
	//		usual '.' to access members of a struct or class, we've
	//		got this weird '->' thing goin on. Thats because our
	//		pCharacter variable is actually a pointer to out real
	//		Character class instance not the thing itself. The ->
	//		is how you access members of the class that the pointer
	//		points to. When GetItems is called it looks like this:
	//		Game.GetItems(user_input, &Character);
	//		Notice the '&'. That means that we're passing in the
	//		memory _address_ of Character NOT the _value_. Now we're
	//		able to directly use with the variable (Character) instead
	//		of just looking at the values in it.
	HRESULT GetItems(char user_input[30], CCharacter * pCharacter)
	{
		int command = 0;
		//scan through our list of items
		for(int loop = 0; loop < MAXITEMS; loop ++)
		{
			//scan the string from 3 digits left up to 12
			for(int in_loop = 3; in_loop < 12; in_loop ++)
			{
				if (strnicmp(&user_input[in_loop], Item[loop].name, strlen(Item[loop].name)) == 0 &&
					Item[loop].location_x == pCharacter->location_x && Item[loop].location_y == pCharacter->location_y)
				{
					Item[loop].location_x = -1; //Remember that -1 is your characters inventory...
					Item[loop].location_y = -1;
					printf("You get the %s.\n", Item[loop].name);
					if (loop == 2)
					{
						//if the item you get is the BAG OF GOLD then we should just put the
						//money straight into our "gold" variable
						pCharacter->gold += 35; //We're saying there's 35 gold in the bag... Any questions?
						Item[loop].location_x = -2; //Kill Bag of Gold
						Item[loop].location_y = -2;
						strcpy(Item[loop].name, "");
					}//end of if (loop == 2)
					if (loop == 4)
					{
						//if you get the sword of kings, you win! Thats the point of the demo
						printf("\nThe sword shines a glorious white light as you draw it from the floor.\n");
						printf("You now hold the key to defeat the evils that have plagued the land for many\n");
						printf("generations. The power to destroy the foul creatures that slew your brother\n");
						printf("is in you hand. You turn back with a look a vengeance in your eye...\n");
						getch();
						exit(0); //finish, game over, the end
					}//end of if (loop == 4)
					command = 1;
				}//end of: if (user_input equals an item thats in the room) then pick it up
			}//end for
		}//end for
		if (command != 1)
			printf("There is no such thing here.\n");
		return S_OK;
	};
	//************************************************************
	//This function checks what the user types and uses any items
	//if one fitting the description is found on the character.
	//************************************************************
	//NOTE: We take a pointer to the entire Character class instance
	//		as well and the World class instance. We're going to need
	//		to use both of them.
	HRESULT UseItem(char user_input[30], CCharacter * pCharacter, CWorld * pWorld)
	{
		int command = 0;
		for(int loop = 0; loop < MAXITEMS; loop ++) //scan through our list of items
		{
			for(int in_loop = 3; in_loop < 12; in_loop ++) //scan the string from 3 digits left up to 12
			{
				if (strnicmp(&user_input[in_loop], Item[loop].name, strlen(Item[loop].name)) == 0 &&
					Item[loop].location_x == -1 && Item[loop].location_y == -1)
				{
					//---
					//USING THE IRON KEY
					//---
					if (loop == 0 && pCharacter->location_x == 1 && pCharacter->location_y == 2)
					{
						printf("You unlock the door!\n");
						//Open the door! Allow exit to the north from here!
						//We made a function specifically for this. Our function
						//is highly versatile (as it should be) and is able to
						//change the access ON/OFF in any direction from any
						//section of the pWorld-> I like it.
						pWorld->ChangeAccess(1, 2, NORTH, TRUE);
						command = 1;
					}//end of if (loop == 0)
					//---
					//USING THE BOOK OF FIREBALL
					//---
					if (loop == 1)
					{
						pCharacter->LearnSpell("FireBall");
						Item[loop].location_x = -2; //Kill Book
						Item[loop].location_y = -2;
						strcpy(Item[loop].name, "");
						command = 3;
					}//end of if (loop == 1)
					//---
					//USING THE BOOK OF PATHFINDER
					//---
					if (loop == 5)
					{
						pCharacter->LearnSpell("PathFinder");
						Item[loop].location_x = -2; //Kill Book
						Item[loop].location_y = -2;
						strcpy(Item[loop].name, "");
						command = 3;
					}//end of if (loop == 5)
					//---
					//USING THE WHISTLE
					//---
					if (loop == 3 &&
						pCharacter->location_x == 2 &&
						pCharacter->location_y == 2)
					{
						printf("The skeleton king begins to rattle violently!\n");
						printf("The light in his eyes shines brightly for a moment and goes out.\n");
						printf("His bones tremble and then crumble to dust. The sword falls to the floor...\n");
						//We've created a function for setting the description of a room
						//now. It takes the x/y of the section you want to change (in
						//this case its x2, y2) and then it takes 5 pointers to type char,
						//which is the text for each line of description.
						pWorld->SetDescription(
							2,
							2,
							"The air here is unnaturally cold. A pile of dust and bone slivers lies",
							"on a great oaken throne.",
							"",
							"",
							"");
						//Now we use that blank item slot. Now there is a sword on the floor!
						strcpy(Item[4].name, "Sword of Kings");
						Item[4].location_x = 2;
						Item[4].location_y = 2;
						command = 1;
					}//end of if (loop == 3)
					//---
					//IF NOTHING WAS USED...
					//---
					if (command == 0)
					{
						printf("That does nothing!\n");
						command = 3;
					}
				}
			}//end for
		}//end for
		//If it is not an item (or you dont have it) then say...
		if (command == 0)
			printf("You dont have that!\n");
		return S_OK;
	};
	//************************************************************
	//This function checks what the user types and drops any items
	//if one fitting the description is found on the character.
	//************************************************************
	HRESULT DropItem(char user_input[30], int x, int y)
	{
		int command = 0;
		//scan through our list of items
		for(int loop = 0; loop < MAXITEMS; loop ++)
		{
			//scan the string from 3 digits left up to 12
			for(int in_loop = 3; in_loop < 12; in_loop ++)
			{
				if (strnicmp(&user_input[in_loop], Item[loop].name, strlen(Item[loop].name)) == 0 &&
					Item[loop].location_x == -1 && Item[loop].location_y == -1)
				{
					Item[loop].location_x = x;
					Item[loop].location_y = y;
					printf("You drop your %s.\n", Item[loop].name);
					command = 1;
				}
			}//end for
		}//end for
		//If it is not an item (or you dont have it) then say...
		if (command != 1)
			printf("You dont have that!\n");
		return S_OK;
	};
	//************************************************************
	//This function displays what items can be seen in the area
	//************************************************************
	HRESULT Search(int x, int y)
	{
		//This is to tell us whether we found anything in this room so we can
		//display a message after if we found nothing
		BOOL FoundSomething = FALSE;
		for(int loop = 0; loop < MAXITEMS; loop ++)
		{
			if (Item[loop].location_x == x && Item[loop].location_y == y)
			{
				printf("There is a %s here...\n", Item[loop].name);
				//Tell us that an item was found in this room
				FoundSomething = TRUE;
			}
		}//end for
		//If we didnt find anything then display this message
		if (!FoundSomething)
			printf("There is nothing here.\n");
		return S_OK;
	};
	//************************************************************
	//This function displays what items we have in our inventory
	//************************************************************
	HRESULT Inventory(int gold)
	{
		printf("\nYou have:\n");
		printf("%d Gold Pieces\n", gold); //Display our money
		for(int loop = 0; loop < MAXITEMS; loop ++) //scan through our list of items
		{
			if (Item[loop].location_x == -1 && Item[loop].location_y == -1)
				printf("  - %s\n", Item[loop].name);
		}//end for
		printf("\n");
		return S_OK;
	};
private:
	//This struct in turn holds the item struct which contains all the item data
	//for each item in the game. There are '[MAXITEM]' items in the game and thus
	//we give ourselves '[MAXITEM]' elements of our array. One per item.
	struct
	{
		char name[30];
		int location_x,
			location_y;
	} Item[MAXITEMS];
};
