#include "../Framework/Util/OpenGLModel.h"
#include "../Framework/Renderer.h"

enum PIECE { NONE = 0, PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6 };
enum COLOR { BLACK = 0, WHITE = 1 };

struct Square {
	PIECE piece;
	COLOR color;
};

struct Move {
	unsigned int fromX, fromY, toX, toY;
	PIECE piece;
	int gain;
	int threatBefore;
	int threatAfter;
	int counterThreatBefore;
	int counterThreatAfter;
	int nHistory;
	
	Move(){};
	Move(unsigned int fX, unsigned int fY, unsigned int tX, unsigned int tY, PIECE p){
		piece = p;
		fromX = fX;
		fromY = fY;
		toX = tX;
		toY = tY;
	}
};

bool operator == (const Move &m0, const Move &m1);

enum Action { BEGIN, WAIT, MOVE, END };
enum DrawMode { NORMAL, DEPTH, BLANK };

class Chess {
private:
	OpenGLModel pieces[6];
//	static float radius[6];
	static float height[6];

	Square board[8][8];

	TextureID noise;
	ShaderID lightingVS, lightingFS;
	ShaderID depthVS, depthFS;
	ShaderID projShadowVS, projShadowFS;

	float time, lastTime, timeDelta;
	COLOR currColor;
	Move currMove;
	Action currAction;

	Set <Move> history;

public:
	Chess();

	void reset();

	void makeMove(Move &move);

	void findAllMoves(Set <Move> &moves, COLOR color);
	void findPawnMoves(Set <Move> &moves, unsigned int x, unsigned int y, COLOR color);
	void findKnightMoves(Set <Move> &moves, unsigned int x, unsigned int y, COLOR color);
	void findOtherMoves(Set <Move> &moves, unsigned int x, unsigned int y, int *dirX, int *dirY, unsigned int nDir, unsigned int maxLength, COLOR color);

	unsigned int getRemainingPieces() const;

	int evaluateThreat(COLOR color, int threatValues[7][7]);
	void evaluateMoves(Set <Move> &moves);

	bool load();
	bool initialize(Renderer *renderer);

	void update(const float currTime);
	void draw(Renderer *renderer, DrawMode drawMode, TextureID shadowMap = TEXTURE_NONE);

};
