/*
	Javascript Platformer
	by Mr Speaker (2004 and 2009!)
	http://www.mrspeaker.net/
	mrspeaker@gmail.com
*/
var game;
var KEY = { left: 0, right: 1, up: 2, down: 3, jump: 4, unused: 5};
var key = [ 0, 0, 0, 0, 0 ];
var g_tileW = 20;
var g_tileH = 20;

var state_loaded = 0;
var state_initialise = 1;
var state_intro = 2;
var state_startGame = 3;
var state_startLevel = 4;
var state_running = 5;
var state_dead = 6;
var state_finished = 7;
var state_win = 8;

var CHAR_INIT = 0;
var CHAR_START = 1;
var CHAR_RUN = 2;
var CHAR_DYING = 3;
var CHAR_DEAD = 4;

var g_maps;
var g_items;
var g_enemies;
var g_moving;	

function cGame()
{
	this.state;
	this.stateFrame;
	this.stateLength;
	this.lastState;
	
	this.currentMap;
	this.currentMapItems;

	this.tiles;
	this.items;
	this.enemies;
	this.player;
	this.lastDoor;
	
	this.domRef;
	
	this.constructor = function(){
		this.setState( state_loaded );
		this.mainLoop();
	};
	
	this.initGame = function(){
		g_maps = game_maps.clone();// new copyObject( game_maps );
		g_items = game_items.clone();//(new copyObject( game_items )).slice(0);
		g_enemies = game_enemies.clone();//new copyObject( game_enemies );
		g_moving = game_moving_tiles.clone();

		this.player = new cPlayer();
		this.player.hiscore = 0;
		if(localStorage){
			this.player.hiscore = localStorage.hs != null ? parseInt(localStorage.hs, 10) : this.player.hiscore;
			localStorage.hs = this.player.hiscore + "";
			$("hiScore").innerHTML = this.player.hiscore;
		}
				
		this.tiles = new cTileController();
		this.items = new cItemController();
		this.enemies = new cEnemyController();
	};
	
	this.mainLoop = function(){	
		switch( this.state ){
			case state_loaded:
				this.setState( state_initialise );
				break;
				
			case state_initialise:
				this.setUpBoard();
				this.initGame();
				this.setState( state_intro );
				break;
				
			case state_intro:
				if ( this.stateFrame === 0 )
				{
					this.stateLength = 40;
					toggle( "intro" );
				}
				if ( this.stateFrame++ > this.stateLength )
				{
					toggle( "intro" );
					this.setState( state_startGame ); 				
				}
				break;
				
			case state_startGame:
				this.currentMap = 0;
				this.player.lastDoor = new cDoor( 0, 1, 4 );
				this.setState( state_startLevel );
				break;
				
			case state_startLevel:
				if ( this.stateFrame === 0 )
				{
					toggle( "ready" );
					// Set all level start variables
					this.player.xTile = this.player.lastDoor.newCharX;
					this.player.yTile = this.player.lastDoor.newCharY;
					this.player.health = 160;
					this.player.hit();
					this.buildMap( g_maps[ this.currentMap ] );
					this.stateLength = 20;
				}
				if ( this.stateFrame++ > this.stateLength )
				{
					toggle( "ready" );
					this.setState( state_running );
					if(typeof editor !== 'undefined'){ editor.init(); }
				}
				break;
				
			case state_running:
				this.player.update();
				this.enemies.update();
				break;
					
			case state_dead:
				this.setState( state_startLevel );
				break;
				
			case state_finished:
				if ( this.stateFrame++ === 0 )
				{
					toggle( "gameOver" );
					this.stateLength = 20;
					
					this.setHiScore();
				}
				if ( this.stateFrame == this.stateLength )
				{
					toggle( "gameOver" );
					this.setState( state_initialise );						
				}
				break;
			case state_win:
				if( this.stateFrame++ === 0)
				{
					toggle( "winScreen" );
					this.stateLength = 150;
					this.setHiScore();
				}
				
				if ( this.stateFrame == this.stateLength )
				{
					toggle( "winScreen" );
					this.setState( state_initialise );						
				}
				break;
		}
		
		setTimeout( "game.mainLoop()", 80 );
	};
	
	this.setHiScore = function(){
		if(this.player.score > this.player.hiscore){
			this.player.hiscore = this.player.score;
			$("hiScore").innerHTML = this.player.hiscore;
			if(localStorage){
				localStorage.hs = this.player.hiscore + "";
			}
		}	
	};
	
	// Create the divs for display elelments
	this.setUpBoard = function(){
		
		var container = document.getElementById("gameContainer");
		if(container !== null){
			container.parentNode.removeChild( container );
		}
		container = document.createElement( "div" );
		container.setAttribute( "id", "gameContainer" );
		document.body.appendChild( container );
		
		var board = document.createElement( "div" );
		board.setAttribute( "id", "gameBoard" );
		this.domRef = board;
		
		container.appendChild( board );
		
		var introScreen = makeDiv( "intro", 0, 0, 280, 480, false );
		introScreen.className = "message";
		introScreen.innerHTML = "<div><span style='font-size:10pt;margin-top:-10px'>Mr Speaker's</span>\"Some Adventure Guy\"</div>";
		container.appendChild( introScreen );
		
		
		var readyScreen = makeDiv( "ready", 40, 20, 60, 140, false );
		readyScreen.className = "message";
		readyScreen.innerHTML = "<div>Ready...</div>";
		container.appendChild( readyScreen );
		
		var gameOverScreen = makeDiv( "gameOver", 40, 20, 60, 140, false );
		gameOverScreen.className = "message";
		gameOverScreen.innerHTML = "<div style='margin:4px auto;width:80px;'>Game Over</div>";
		container.appendChild( gameOverScreen );
		
		var winScreen = makeDiv( "winScreen", 40, 20, 120, 160, false );
		winScreen.className = "message";
		winScreen.innerHTML = "<div style='margin:4px auto;width:80px;'><blink>Wins the game!!1!</blink></div>";
		container.appendChild( winScreen );
		
		var score = makeDiv( "score", 0, 280, 40, 480, true );
		score.style.position = "relative";
		container.appendChild( score );
		
		var rotateScreen = makeDiv( "rotate", 0, 0, 480, 320, false );
		rotateScreen.className = "message";
		rotateScreen.style.opacity = "0.8";
		rotateScreen.style.verticalAlign = "middle";
		rotateScreen.style.color = "#ff0";
		rotateScreen.innerHTML = "<div style='width:100%;text-align:center;top:50%'>U gotta rotate...</div>";
		container.appendChild( rotateScreen );
						
		var tile =  document.createElement( "div" );
		tile.style.position = "relative";
		tile.setAttribute("id", "p1");
		tile.style.width = "10px";
		tile.style.height = "15px";
		tile.style.marginRight = "2px";
		tile.style.backgroundImage = "url(images/characters.png)";
		tile.style.backgroundPosition = "0px 0px";
		tile.style.backgroundPosition = "-20px 0px";
		tile.style.cssFloat = "left";
		tile.style.border="1px solid #440";

		score.appendChild( tile );
		tile2 = tile.cloneNode(false);
		tile2.setAttribute( "id", "p2" );
		score.appendChild( tile2 );
		
		var scoreDiv = makeDiv( "playerScore", 0, 0, 15, 60, true );
		scoreDiv.style.position = "relative";
		scoreDiv.innerHTML = 0;
		scoreDiv.style.cssFloat = "left";
		scoreDiv.style.marginLeft = "100px";
		score.appendChild( scoreDiv );
		
		var hiscoreDisplay = makeDiv( "hiscoreDisplay", 0, 0, 15, 15, true );
		hiscoreDisplay.style.position = "relative";
		hiscoreDisplay.innerHTML = "HI";
		hiscoreDisplay.style.cssFloat = "left";
		hiscoreDisplay.style.marginLeft = "15px";
		hiscoreDisplay.style.marginRight = "3px";
		score.appendChild( hiscoreDisplay );
		
		var hiscoreDiv = makeDiv( "hiScore", 0, 0, 15, 60, true );
		hiscoreDiv.style.position = "relative";
		hiscoreDiv.innerHTML = this.player ? this.player.hiscore : 0;
		hiscoreDiv.style.cssFloat = "left";
		hiscoreDiv.style.marginLeft = "1px";
		score.appendChild( hiscoreDiv );

		if(iPhoneControls.active){
			iPhoneControls.drawDPads( container );
		}
	};
		
	this.buildMap = function( map, blnFirst )
	{
	
		// Erase current map
		while( this.domRef.childNodes[ 0 ]  ){
			this.domRef.removeChild( this.domRef.childNodes[ 0 ] );
		}
		var docFrag = document.createDocumentFragment();
			
		// Build new map
		var mapWidth = map[ 0 ].length;
		var mapHeight = map.length;
		for( var i = 0; i < mapHeight; i++ ){
			for( var j = 0; j < mapWidth; j++ ){
				this.tiles.tiles[ map[ i ][ j ] ].draw( j, i,  docFrag );
			}
		}
		
		// Moving tiles
		this.tiles.drawMoving( this.currentMap );
		
		// Place items
		this.currentMapItems = this.items.getMapItems( this.currentMap );
		for (i = 0; i < this.currentMapItems.length; ++i ){
			this.currentMapItems[ i ].draw( docFrag );
		}
		
		// Draw enemies
		this.enemies.setMapEnemies( this.currentMap );
		this.enemies.drawEnemies( docFrag );
		
		// Place character
		this.player.x = ( this.player.xTile * g_tileW ) + g_tileW / 2;
		this.player.y = ( ( this.player.yTile + 1 ) * g_tileH ) - ( this.player.height / 2 );
		this.player.draw( docFrag );
		
		this.domRef.appendChild( docFrag );
	};
	
	this.updateLevelStatus = function(){
		// Update the items available
		g_items[ this.currentMap ].length = 0; //delete old item list
		for( var i = 0; i < this.currentMapItems.length; i++ )
		{
			// Add the remaining items to the global list
			g_items[ this.currentMap ].push( new Array(this.currentMapItems[ i ].type, this.currentMapItems[ i ].x, this.currentMapItems[ i ].y ) );
		}
	};
	
	this.changeMap = function( p_door ){
		key[ KEY.left ] = key[ KEY.right ] = key[ KEY.jump ] = 0;
								
		this.updateLevelStatus();
		
		this.currentMap = p_door.newMap;
		this.player.xTile = p_door.newCharX;
		this.player.yTile = p_door.newCharY;
		this.player.lastDoor = p_door;
		this.buildMap( g_maps[ this.currentMap ] );
	};
	
	this.setState = function( p_state ){
		this.lastState = this.state;
		this.stateFrame = 0;
		this.state = p_state;
	};

	this.constructor();
}

