function gameClass(name, unitTypes, buildingTypes, terrainTypes) {
/*==============================================================================
shipClass
requires: createLayer() function

name
baseName
numberOfPlayers
activePlayer
unitAtive
buildingActive
player[]
player[].funds
player[].colour
player[].units[]
player[].uniqueCount
building[]
mapArray[][]
mapWidth
mapHeight

==============================================================================*/
	this.name = name;
	this.baseName = name.replace(/([^a-zA-Z0-9])/g, "", name);
	
	//Player info
	this.numberOfPlayers = 0;
	this.activePlayer = 0;
	this.unitActive = false;
	this.buildingActive = false;
	this.day = 1;
	this.player = new Array();
	this.building = new Array();
	
	//Unit info
	this.unitTypes = unitTypes;
	this.buildingTypes = buildingTypes;
	
	//Map info
	this.mapTypes = terrainTypes;
	this.mapArray = null;
	this.mapWidth = 0;
	this.mapHeight = 0;
	this.statusDisplay = null;
	
	//Status display
	this.statusDisplay = createLayer('statusDiv',null,1,120,95,(TerrainArray[0].length*32),'',null,null,2);
	this.playerDisplay = createLayer('playerDiv','statusDiv',0,0,90,50,'',null,null,3); 
	this.selectedUnitDisplay = createLayer('selectedDiv','statusDiv',0,57,90,50,'',null,null,3);
	this.selectedUnitDisplay.className = "status";
	this.selectedUnitOptions = createLayer('unitOptionsDiv','statusDiv',0,114,90,100,'',null,null,3);
	this.selectedUnitOptions.className = "status";
	this.playerOptions = createLayer('playerOptionsDiv','statusDiv',0,221,90,40,'',null,null,3);
	this.playerOptions.innerHTML = '<a href="javascript:'+this.name+'.nextPlayer();">End Turn</a><br><a href="javascript:'+this.name+'.makeXML();">Make XML</a><br><a href="javascript:'+this.name+'.makeJSON();">Make JSON</a>';
	
	this.setPlayer = function(playerColour) { 
		var playerTmp = {};
		playerTmp.funds = 0;
		playerTmp.colour = playerColour;
		playerTmp.units = new Array();
		playerTmp.uniqueCount = 0;
		this.player.push(playerTmp);
		this.numberOfPlayers++;
	};
	
	this.setUnit = function( playerNumber, unitType, unitX, unitY ) {
		var newIndex = this.player[playerNumber].units.length;
		this.player[playerNumber].units[newIndex] = new unitClass(this, playerNumber, "p"+playerNumber+"u"+this.player[playerNumber].uniqueCount, unitType);
		this.player[playerNumber].units[newIndex].setPosition(unitX, unitY);
		this.player[playerNumber].uniqueCount++;
	};
	
	this.setBuilding = function( owned, playerNumber, buildingType, buildingX, buildingY ) {
		var newIndex = this.building.length; 
		this.building[newIndex] = new buildingClass(this, "b"+newIndex, buildingType, buildingX, buildingY, owned, playerNumber);
	};
	
	this.setMap = function( terrainArray ) {  
		this.mapArray = terrainArray;
		this.mapWidth = terrainArray[0].length;
		this.mapHeight = terrainArray.length;
		createMap(this.mapArray, 'mapTerrain', 'mapTerrainDiv');
		//Layer for units
		createLayer('unitsDiv',null,100,120,TerrainArray[0].length*32,TerrainArray.length*32,'',null,null,2);
	};
	
	this.setStatusDisplay = function( playerNumber ) { 
		this.playerDisplay.innerHTML = "Day: " + this.day + "<br>Player: " + (playerNumber+1) + "<br>Funds: " + this.player[playerNumber].funds;
		this.playerDisplay.className = "status" + this.player[playerNumber].colour;
		this.playerOptions.className = "status" + this.player[playerNumber].colour;
	} 
	
	this.nextPlayer = function() { 
		this.activePlayer++;
		this.unitActive = false;
		if (this.activePlayer == this.player.length) {
			this.activePlayer = 0;
			this.day++;
		}
		// Start the new active players turn
		this.startPlayerTurn();
	}
	
	this.startPlayerTurn = function() {
		// Announce Day
		// Go trough buildings
		for (var i=0; i<this.building.length; i++) {
			if (this.building[i].owned && this.building[i].owner == this.activePlayer) this.player[this.activePlayer].funds += this.buildingTypes[this.building[i].type].funds;
			this.building[i].unactivate();
		};
		// Repair & Ready Units
		for (var i=0; i<this.player.length; i++) {
			for (var j=0; j<this.player[i].units.length; j++) {
				// Ready
				this.player[i].units[j].ready();
				// Repair
				if (i == this.activePlayer) {
					for (var k=0; k<this.building.length; k++) {
						if (this.building[k].owned && this.building[k].owner == this.activePlayer && this.building[k].x == this.player[i].units[j].x && this.building[k].y == this.player[i].units[j].y) {
							if (this.player[i].units[j].health <= 80) {
								this.player[i].funds -= Math.ceil(this.unitTypes[this.player[i].units[j].type].cost * 0.2);
								this.player[i].units[j].setHealth(this.player[i].units[j].health+20);
							} else if (this.player[i].units[j].health < 100) {
								this.player[i].funds -=  Math.ceil(this.unitTypes[this.player[i].units[j].type].cost * (100 - this.player[i].units[j].health)/100);
								this.player[i].units[j].setHealth(100);
							};
							break;
						};
					};
				};
			};
		};
		// Set up status display
		this.setStatusDisplay(this.activePlayer);
		this.selectedUnitDisplay.innerHTML = "";
	}
	
	this.elementAction = function( action ) {
		if (this.unitActive) {
			for (var j=0; j<this.player[this.activePlayer].units.length; j++) {
				if (this.player[this.activePlayer].units[j].state != 0 && this.player[this.activePlayer].units[j].state != 7) {
					switch(action) {
						case 'undo': this.player[this.activePlayer].units[j].unitUndo(); break;
						case 'wait': this.player[this.activePlayer].units[j].exhaust(); break;
						case 'capture': this.player[this.activePlayer].units[j].capture(); break;
						//default: this.game.selectedUnitOptions = "";
					};
				};
			};
		} else if (this.buildingActive) {
			for (var j=0; j<this.building.length; j++) {
				if (this.building[j].active && action == "undo") { this.building[j].unactivate(); break; };
			};
		};
	};
	
	this.buildUnit = function( unitToBuild ) {
		if (this.buildingActive) {
			for (var i=0; i<this.building.length; i++) {
				if (this.building[i].active) this.building[i].unitConstruct( unitToBuild );
			}
		}
	}
	
	this.makeXML = function() {
		var xmlString = '<?xml version="1.0"?>\n<?xml-stylesheet type="text/css" href="blank.css"?>\n';
		xmlString += '<game day="'+this.day+'" activePlayer="'+this.activePlayer+'">\n';
		for (var i=0; i<this.player.length; i++) {
			xmlString += '<player id="'+i+'" colour="'+this.player[i].colour+'" funds="'+this.player[i].funds+'">\n';
			for (var j=0; j<this.player[i].units.length; j++) {
				this.player[i].units[j];
				xmlString += '<unit type="'+this.player[i].units[j].type+'" x="'+this.player[i].units[j].x+'" y="'+this.player[i].units[j].y+'" health="'+this.player[i].units[j].health+'" state="'+this.player[i].units[j].state+'"   />\n';
			}
			xmlString += '</player>\n';
		}
		for (i=0; i<this.building.length; i++) {
			xmlString += '<building id="'+i+'" owned="'+this.building[i].owned+'" owner="'+this.building[i].owner+'" />\n';
		}
		xmlString += '</game>\n';
		alert(xmlString);
	}
	
	this.makeJSON = function() {
		var jsonStr = '{ ';
		jsonStr += '"day":'+this.day+', ';
		jsonStr += '"activePlayer":'+this.activePlayer;
		
		// Players 
		if (this.player.length) { 
			jsonStr += ',\n "player":[\n';
			for (var i=0; i<this.player.length; i++) {
				if (i) jsonStr += ',\n';
				jsonStr += '{ "id":'+i+', "colour":"'+this.player[i].colour+'", "funds":'+this.player[i].funds;
				if (this.player[i].units.length) {
					jsonStr += ',\n "units":[ \n';
					for (var j=0; j<this.player[i].units.length; j++) {
						if (j) jsonStr += ',\n';
						jsonStr += '{ "name":"'+this.player[i].units[j].name+'", "type":'+this.player[i].units[j].type+', "x":'+this.player[i].units[j].x+', "y":'+this.player[i].units[j].y+', "health":'+this.player[i].units[j].health+', "state":'+this.player[i].units[j].state+' }';
					}
					jsonStr += ']';
				}
				jsonStr += '}';
			}
			jsonStr += ']';
		}
		if (this.building.length) { 
			jsonStr += ',\n "building":[\n';
			for (i=0; i<this.building.length; i++) {
				if (i) jsonStr += ',\n';
				jsonStr += '{ "id":'+i+', type:'+this.building[i].type+', "owned":'+this.building[i].owned+', "owner":'+this.building[i].owner+' }';
			}
			jsonStr += ']';
		}
		jsonStr += '}';
		alert(jsonStr);
	}
	
} // End gameClass

function keyPressHandler(evt) {
	var key;
	var e = evt || window.event;
	if (e.keyCode) key = e.keyCode;
	if (e.which) key = e.which;
    if(key==27) game.elementAction("undo");
};

addEvent(document, "keypress", keyPressHandler);

//var json = new JSON();


