// isomaze.js
// Copyright 2006 Dave Laplander 
// dlaplander@gmail.com 
// http://del.typepad.com/

function showDiv(id,background)
{
	// set the div visibility on
	
	var d = document.getElementById(id);
	if (d)
	{ 

		d.style.visibility = "visible"; 
		
		if (background)
		{
			d.style.background = "url(" + background + ")";
		}
	}
	
//		if (id.indexOf("x00y01_lwall") >= 0 )
//		alert("foo");

}

function hideDiv(id)
{
	// set the div visibility off
	var d = document.getElementById(id);
	
	if (d)
		{ d.style.visibility = "hidden"; }
}

function ToggleCell(m, x, y, walls)
{
	if (walls.indexOf("t") >= 0)
		m[x][y].twall = !m[x][y].twall;
		
	if (walls.indexOf("l") >= 0)
		m[x][y].lwall = !m[x][y].lwall;
	
	if (walls.indexOf("b") >= 0)
		m[x][y].bwall = !m[x][y].bwall;

	if (walls.indexOf("r") >= 0)
		m[x][y].rwall = !m[x][y].rwall;
}

function BlankMaze(m)
{
	for (var x=0; x < m.length; x++)
		for (var y=0; y < m[0].length; y++)
			ToggleCell(m, x, y, "tlbr");
}

function DrawMaze(m, x, y)
{
	// Draws the maze m centered around coordinates (x,y). Nasty shit here.
	
	// Get the surrounding visible cells (5 x 4 array of maze cells)
	var cells = GetSurroundingCells(m, x,y);
	
	// Toggle the wall segment shadows
	DrawShadows(m, cells);	
	
	// Draw maze walls
	DrawWalls(m, cells);
}

function DrawMazeEdge(m, x, y)
{
		
	
}

function GetSurroundingCells(m, x,y)
{
	// Returns a (5 x 5) array of the cells around (x,y), some of which may be null. (x,y) will
	// be located at (2,2) in the returned array.
	
	// Initialize the array with empty maze cells
	var cells = new Array(5);
	for (var i = 0; i < 5; i++)
	{
		cells[i] = new Array(5);
		for (var j=0; j < 5; j++)
		{
			cells[i][j] = null;
		}
	}
	

	// Figure out valid cell ranges
	var x_start = x-2;
	var y_start = y-2
	
	// Grab the cells
	for (var i = 0; i < 5; i++)
	{
		for (var j = 0; j < 5; j++)	
		{
			cells[i][j] =  (m[x_start + i] && m[x_start + i][y_start + j]) ? m[x_start + i][y_start + j] : null;
		}
	}
	
	return cells;
}

function OrientCharacter(dir)
{
	// Displays the character oriened in the correct direction
	if ( dir == "t" )
	{ showDiv("character", "images/character_000.gif"); }
	else if ( dir == "l" )
	{ showDiv("character", "images/character_270.gif"); }
	else if ( dir == "b" )
	{ showDiv("character", "images/character_180.gif"); }
	else if ( dir == "r" )
	{ showDiv("character", "images/character_090.gif"); }
	else
	{ hideDiv("character"); }
}

function DrawShadows(m, cells)
{
	// Toggles on the shadows
	for (var i=0; i < 5; i++)
	{
		for (var j=0; j < 5; j++)
		{
			// Holds current cells div prefix name
			var cell_prefix = GetCellPrefix(i,j);
			
			hideDiv(cell_prefix + "_shadow");
			hideDiv( GetCellPrefix(i-1, j+1) + "_twall_shadow" );
			//hideDiv( GetCellPrefix(i, j) + "_twall_shadow" );
			
			// If there is a wall to the left then we turn on the lwall shadow
			if ( cells[i][j] && cells[i][j].lwall == true )
			{
				// Wall to the left so enable the lwall shadow				
				showDiv(cell_prefix + "_shadow");
			}
			
			// If cell to left and down has twall then show it's twall shadow
			if ( cells[i-1] &&  cells[i-1][j+1] && cells[i-1][j+1].twall == true && cells[i][j] && cells[i][j].lwall == false)
			{
				showDiv( GetCellPrefix(i-1,j+1) + "_twall_shadow" );
			}
		}
	}	
}

function DrawWalls(m, cells)
{
	// Toggles on the wall segments in cells (centered around (x,y) )
	
	// First, blank the whole thing
	for (var i=0; i < 5; i++)
	{
		for (var j=0; j < 5; j++)
		{
			var cell_prefix = GetCellPrefix(i,j);
			hideDiv( cell_prefix + "_lwall");
			hideDiv(cell_prefix + "_twall");
		}
	}
	
	hideDiv("x-01y02_twalls");
	hideDiv("x-01y02_twall");
	hideDiv("x02y-01_lwall");
	hideDiv("x02y-01_shadow");


	// Now, go in and turn everything on that should be on
	for (var i=0; i < 5; i++)
	{
		for (var j=0; j < 5; j++)
		{
			// Holds current cells div prefix name
			var cell_prefix = GetCellPrefix(i,j);
			
		
			// If there is a wall to the left then we turn on the wall
			if ( cells[i][j] && cells[i][j].lwall == true )
			{
				// Turn on the left wall
				showDiv(cell_prefix + "_lwall");
			}
			
			if ( cells[i][j] && cells[i][j].twall == true )
			{
				// Wall to the top so enable it
				if (cells[i][j].lwall == true )
				{
					// Shadow
					showDiv(cell_prefix + "_twall", "images/" + cell_prefix + "_twalls.gif");
				}
				else
				{
					// No Shadow
					showDiv(cell_prefix + "_twall", "images/" + cell_prefix + "_twall.gif");
				}					
			}				
			
			// If we're at the right edge of the maze then turn on the rwall and the shadow
			if ( cells[i][j] && cells[i][j].x == (m.length - 1) )
			{
				var rwallPrefix = GetCellPrefix(i+1, j);
				showDiv( rwallPrefix + "_lwall" );
				showDiv( rwallPrefix + "_shadow" );
			}
			
			// If we're at the bottom of the maze then turn on the cell below's twall
			if ( cells[i][j] && cells[i][j].y == (m[0].length -1) )
			{
				// No need to test for a shadow
				var botRowPrefix = GetCellPrefix(i, j+1);
				
				// As long as this isn't the 'exit' cell then show the twall
				if ( cells[i][j].x == (m.length -1) && cells[i][j].y == (m[0].length -1) )
				{ }
				else
				{
					showDiv( botRowPrefix + "_twall", "images/" + botRowPrefix + "_twall.gif" );
				}
			}
		}
	}	
	
	// This is a hack to get around the fact that we can see just a little of the twall in the cell
	// to the left of x00y02 (off the edge of the "visible" matrix).
	if ( (cells[2][2].x - 3) >= 0  )
	{
		if ( m[cells[2][2].x - 3][cells[2][2].y].twall == true )
		{
			showDiv("x-01y02_twalls", "images/x-01y02_twalls.gif");
			showDiv("x-01y02_twall");
		}
	}
	
	// And this is a hack to get around the fact that we can see just a little of the lwall in the cell
	// above x02y00 (off the edge of the "visible" matrix).
	if ( (cells[2][2].y - 3) >= 0  )
	{
		if ( m[cells[2][2].x][cells[2][2].y - 3].lwall == true )
		{
			showDiv("x02y-01_lwall", "images/x02y-01_lwall.gif");
			showDiv("x02y-01_shadow");
		}
	}

}


function GetCellPrefix( x, y)
{
	// Returns a string prefix for the specified display cell
	var xprefix = (x < 10) ? "x0" + x : "x" + x;
	var yprefix = (y < 10) ? "y0" + y : "y" + y;
	
	return (xprefix + yprefix);	
}

// Toggle the glow on one of the arrows
function glowIt(id, i)
{
	var d = document.getElementById(id);
	d.style.background = "url(" + i + ")";
}

// Toggles the map display on/off
function toggleMap()
{
	// If the map isn't displayed then move it to the top of the stack and turn on its visibility
	if (display_map == true)
	{
		// Hide the map
		hideDiv("mazemap");
		
		// Lower it to the bottom of the z-order stack
		var d = document.getElementById("mazemap");
		if (d)
		{ 
	
			d.style.zIndex = "-99"; 
		}
		
		chatText("You put the map away.");
	}
	else
	{
		// Show the map
		showDiv("mazemap");
		
		// Raise it to the top of the z-order stack
		var d = document.getElementById("mazemap");
		if (d)
		{
			d.style.zIndex = "1000";
		}
		chatText("You look at the map.");
	}
	
	// Toggle off/on the display variable
	display_map = !display_map;

}

function chatText(s)
{
	var c = document.getElementById("chatSpan");
	c.innerHTML = s;
}

function TranslateDirection(d)
{
	// Translates a direction (t,l,b,r) to a direction (i.e. North, South, etc)
	switch (d)
	{
		case "t":
			return "North";
			break;
			
		case "l":
			return "West";
			break;
			
		case "b":
			return "South";
			break;
			
		case "r":
			return "East";
			break;
	}
}
		
function turnLeft()
{
	// The character is turning left
	
	// Make orientation change based on current direction we're facing
	switch (cur_facing)
	{
		case "t":
			cur_facing = "l";
			break;
			
		case "l":
			cur_facing = "b";
			break;
			
		case "b":
			cur_facing = "r";
			break;
			
		case "r":
			cur_facing = "t";
			break;
	}
	
	OrientCharacter(cur_facing);
	chatText("You turn to face " + TranslateDirection(cur_facing) + ".");
}

function turnRight()
{
	// The character is turning right
	
	// Make orientation change based on current direction we're facing
	switch (cur_facing)
	{
		case "t":
			cur_facing = "r";
			break;
			
		case "l":
			cur_facing = "t";
			break;
			
		case "b":
			cur_facing = "l";
			break;
			
		case "r":
			cur_facing = "b";
			break;
	}
	
	OrientCharacter(cur_facing);
	chatText("You turn to face " + TranslateDirection(cur_facing) + ".");
}

function PlayAgain()
{
	//	Ask the player if they want to play again and if they do then
	// reset the maze.
	
	if ( confirm("Would you like to play again?") == true )
	{
		m = InitMaze(20,20);
	    m = CarveMaze(m,10,10,10,10);
	
		// Open up the exit in lower right corner
		m[19][19].bwall = false;
	
		// These control the location and direction the character is facing. We start out facing 
		// towards the bottom of cell (0,0).
		cur_x = 0;
		cur_y = 0;
		cur_facing = "b";
		
		var s = PrintMaze(m);
		document.getElementById("mazemap").innerHTML = s
	
		
		var tc = document.getElementById("c" + cur_x + "x" + cur_y);
		tc.bgColor = "#FF0000";
		
		DrawMaze(m,cur_x,cur_y);
		chatText("Click the arrows in the upper right or your arrow keys to navigate.");
	}
}
	

function stepForward()
{
	// Character is trying to move forward
	
	// Check for end-case
	if ( m[cur_x][cur_y].x == (m.length-1) && m[cur_x][cur_y].y == (m[0].length-1) && cur_facing == "b" )
	{
		alert("Congratulations! You found the exit!");
		cur_x = m.length-1;
		cur_y = m[0].length-1;
		chatText("You escaped from the maze!");
		
		// Ask if they want to play again
		setTimeout(PlayAgain, 1000);
		return;
	}
	
	
	// First, make sure there's no wall in front of us
	if ( m[cur_x][cur_y].HasWall(cur_facing) == true )
		{ chatText("There appears to be a solid wall in front of you."); }
	else
		{
			// Move to the next cell
			switch (cur_facing)
			{
				case "t":
					cur_y--;
					Move(cur_x, cur_y);
					break;
				case "l":
					cur_x--;
					Move(cur_x, cur_y);
					break;
				case "b":
					cur_y++;
					Move(cur_x, cur_y);
					break;
				case "r":
					cur_x++;
					Move(cur_x, cur_y);
					break;
			}
			
			chatText("You step forward into the room to your " + TranslateDirection(cur_facing) + ".");
			
		}
		
}

function glowUp()
{
	glowIt('iarrows', 'working/arrowsupclick.gif');
}

function glow_off()
{
	glowIt('iarrows', 'working/arrows.gif');	
}
function glowLeft()
{
	glowIt('iarrows', 'working/arrowsleftclick.gif');
}
function glowRight()
{
	glowIt('iarrows', 'working/arrowsrightclick.gif');
}


function keyPressed_handler(e)
{
	// User pressed a key
	
	// Get the event object and character code in a portable way
	var c = e || window.event;
	var code = e.charCode || e.keyCode;
	
	if ( code == 37 )
	{
		// Left arrow key
		setTimeout(glowLeft, 0);
		setTimeout(glow_off, 150);			
		setTimeout(turnLeft, 200);
	}
	else if ( code == 39 )
	{
		// Right arrow key
		setTimeout(glowRight, 0);
		setTimeout(glow_off, 150);						
		setTimeout(turnRight, 200);
	}
	else if ( code == 38 )
	{
		// Up arrow key
		setTimeout(glowUp, 0);
		setTimeout(glow_off, 150);			
		setTimeout(stepForward, 200);
	}
}

function Move(old_x, old_y, x_new, y_new)
{
	ResetMap();
	var tc = document.getElementById("c" + cur_x + "x" + cur_y);
	tc.bgColor = "#FF0000";
	DrawMaze(m, cur_x, cur_y);
}

function ResetMap()
{
	for (var i=0; i < m.length; i++)
	{
		for (var j=0; j < m[0].length; j++)
		{
			var tc = document.getElementById("c" + i + "x" + j);
			tc.bgColor = "";
		}
	}
}
