// This template code can be used for the initial scaffold for your assignment.
//Feel free to use your own design if you want.
//You are responsible for creating the game play logic and for developing a graphical interface/display.
//You may use the console window to output scores, etc but graphics fonts are desirable.
//Please see assignment for details of the scenario and requirements.
#include <iostream>
using namespace std;
typedef struct {
	int x;
	int y;
}position;
enum move { NONE, UP, DOWN, LEFT, RIGHT, FLIP };
#define WIDTH 3
#define HEIGHT 3
/*******************************Card class************************************************************/
class Card
{
public:
	Card() { facingUp = false; selected = false; image = '0'; };
	Card(char img); //constructor
	void flip(void);
	char getImage(void);
	void setImage(char img);
	void select();
	void unSelect(void);
private:
	bool facingUp;
	char image;
	bool selected;
};
void Card::unSelect(void)
{
	selected = false;
}
void Card::select(void)
{
	selected = true;
}
Card::Card(char img) //constructor sets default attributes
{
	image = img;
	facingUp = false;
	selected = false;
}
char Card::getImage(void)
//depending on the game's state, the image shown could be back of card ('.'), card selected ('*')
//or the card's face value - its img attribute as set by setImage() 
{
	if (facingUp)
		return image;
	else
		if (selected)
			return '*';
		else return '.';
}
void Card::setImage(char img)
//here the card face can be set to be any char
{
	image = img;
}
void Card::flip(void)
{
	facingUp = !facingUp;
}
/*********************************************end Card class*******************************************/

/*********************************************TableTop class*******************************************/
class TableTop
{
public:
	TableTop(); //constructor
	void setDirection(enum move m); //use move enum to specify which way to go left/right/up/down
	void moveFocus();//move focus one place left/right/up/down 
	void display(void); //draw puzzle
	void takeTurn(void);//responsible for revealing cards and matching them, etc
	void turnOver(void); //change state of card 
private:
	enum move myMove;
	Card tiles[3][3]; //puzzle now
	position  CardOne; //Card One position
	position  CardTwo; //Card Two position
	position selectedCard; //Currently selected card. use Card's turnover() to reveal or hide

};
TableTop::TableTop()  //constructor
{
	myMove = NONE; //initialize member attributes
	CardOne.x = 0; //Card One x position
	CardOne.y = 0; //Card One y position
	CardTwo.x = 0; //Card Two x position
	CardTwo.y = 1; //Card Two y position
	selectedCard.x = 0; //currently selected card
	selectedCard.y = 0;
	tiles[selectedCard.x][selectedCard.y].select(); //puts focus on a card at beginning of game
	tiles[0][0].setImage('0'); tiles[1][0].setImage('0'); tiles[2][0].setImage('1'); //set up puzzle tiles
	tiles[0][1].setImage('1'); tiles[1][1].setImage('2'); tiles[2][1].setImage('2');
	tiles[0][2].setImage('3'); tiles[1][2].setImage('3'); tiles[2][2].setImage('4');
}
void TableTop::takeTurn(void)
//put game logic here
{
	if (myMove == FLIP) turnOver(); //this just flips the selected card
}
void TableTop::moveFocus(void)
// select a card by moving over it. An asterix indicates which card is the focus for any further game play
{
	tiles[selectedCard.x][selectedCard.y].unSelect();  //make sure present card is unselected before changing focus
	if (myMove == LEFT) {
		selectedCard.x = (WIDTH + selectedCard.x - 1) % WIDTH; //modular arithmetic used - only positive numbers needed - 0,1,2,...WIDTH;
																//only positive numbers needed - 0,1,2,...HEIGHT;
	}
	if (myMove == RIGHT) {
		selectedCard.x = (WIDTH + selectedCard.x + 1) % WIDTH;
	}
	if (myMove == UP) {
		selectedCard.y = (HEIGHT + selectedCard.y - 1) % HEIGHT;
	}
	if (myMove == DOWN) {
		selectedCard.y = (HEIGHT + selectedCard.y + 1) % HEIGHT;
	}
	tiles[selectedCard.x][selectedCard.y].select();
	cout << "selected card(" << selectedCard.x << "," << selectedCard.y << ")" << endl;
}
void TableTop::turnOver(void) //change state of selected card 
{
	tiles[selectedCard.x][selectedCard.y].flip();
}
void TableTop::display(void)
//This is the render part so we draw the puzzle as it is now
{
	cout << tiles[0][0].getImage() << " " << tiles[1][0].getImage() << " " << tiles[2][0].getImage() << endl;
	cout << tiles[0][1].getImage() << " " << tiles[1][1].getImage() << " " << tiles[2][1].getImage() << endl;
	cout << tiles[0][2].getImage() << " " << tiles[1][2].getImage() << " " << tiles[2][2].getImage() << endl;
	cout << endl;
}
void TableTop::setDirection(enum move m)
//sets which way you want to move
{
	myMove = m;
}
/********************************************end TableTop class ***************************************/

/**********************************************main****************************************************/
int main(void)
//The usual game loop pattern used here
{
	TableTop myPuzzle;//create class and init.
	char d; //keyboard interface valid values a,s,w,d,x 
	cout << "Welcome: a,s,w,d moves the focus from on card to another" << endl;
	cout << "x flips the selected card" << endl;
	cout << "don't forget to press Enter key after pressing a,s,w,d or x" << endl;
	myPuzzle.display(); //draw puzzle
	while (true) //go forever
	{
		//input
		cin >> d;
		if (d == 'a') myPuzzle.setDirection(LEFT);
		if (d == 'd') myPuzzle.setDirection(RIGHT);
		if (d == 'w') myPuzzle.setDirection(UP);
		if (d == 's') myPuzzle.setDirection(DOWN);
		if (d == 'x') myPuzzle.setDirection(FLIP);
		//update game logic based on inputs and rules.
		myPuzzle.moveFocus();
		myPuzzle.takeTurn(); //make your move
		//render
		myPuzzle.display(); //draw puzzle
	}
	return 0;
}//the end