/* maze.h: Class that implements the creation and management of a maze. Uses a Recursive backtracking algorithm

   Copyright (C) 2008  Stuart William Coulson

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

// Because the maze is 2D but drawn in 3D, all dimensions and positions are given names with regards to x and y. In 3D this should be x and z.

#ifndef _MAZE_H_
#define _MAZE_H_

#include <bitset>
#include "texture.h"
#include "terrain.h"

#define wallHeight 50			// Value used to control the size of walls in the maze

enum mazeDirection {none, up, down, left, right};				//Enumeration type of the directions objects can move in the maze. None needed for Beast AI

class mazePosition {							//A class used to hold the position of objects in  the maze
	public:
		mazePosition();							// Non-parameterised constructor
		mazePosition(int posX, int posY);		// Parameterised constructor which takes in two values, an x and y position
		int x;									// X position
		int y;									// Y position
		bool operator== (mazePosition param);	// An operator to compare two mazePosition object
		void operator= (mazePosition param);	// A assignment operator for mazePosition objects	
};

class maze {									// A class used to create and manage a maze
	private:
		bitset<5>* mazeArray;										// Pointer to the position in memory of the representation of the maze. Use bitset to reduce size of maze in memory.
		int mazeWidth, mazeHeight, numberWalls, mazeWallPointer;	// Variables holding statistics of the maze plus mazeWallPointer which is a pointer to Static memory where the mesh to draw the walls is stored.
		CTerrain groundTerrain;										// A terrain object used to draw the floor of the maze
		CTexture groundTex, wallTex;								// Texture objects to hold the texture of the ground and the walls.
	
	public:
		maze(int xSize, int ySize);													//Constructor takes two arguments defining the width and height in terms of cells to make the maze
		~maze();																	//Destructor
		bool moveDirection(int xCell, int yCell, mazeDirection direction);			// Test to see if there is a wall in a particular direction. Returns a bool based on success.
		int getWidth() {return mazeWidth;};											// Return mazeWidth
		int getHeight() {return mazeHeight;};										// Return mazeHeight
		float getTopLeftCornerX() {return (-(tileSize * mazeWidth) / 2);}			// Get the x-coordinate of the top left corner
		float getTopLeftCornerY() {return (-(tileSize * mazeHeight) / 2);}			// Get the y/z-coordinate of the top left corner
		void render(const Matrix4x4 & matWorld);									// Render the entire maze, floor and walls
		bool uploadTextures(const char * floorTexure, const char * wallTexture);	// Upload the floor and wall textures into memory
		void outputMaze();															// For debugging - print out a representation of the maze on the standard output.
		
	private:
		void generateMaze();								// Function used to generate a maze using the required algorithm
		void createWalls();									// Create the 3D mesh that represents the walls of the maze
		void renderFloor(const Matrix4x4 & matWorld);		// Render the floor of the maze
		void renderWalls();									// Render the walls of the maze
};

#endif
