/*
Baffle! (TM) Flying Rabbit Enterprises, Cincinnati OHIO
Copyright 2007 Flying Rabbit

Game programming for iPhone by Mike Helmick
http://mikehelmick.com/ 
*/
var numberOfColumns = 5;
var numberOfRows = 5;

var grid = [];
var selected = [];
var dirty = [];
var allowClicks = true;

var oneSelected = false;

function firstLoad() {
	
	setText("<div align=\"center\"><h2>Baffle!</h2><p>Loading Images...</p></div>")
	
	var imageFiles = new Array(31);
	var idx = 0
	for( var x = 0; x < numberOfColumns; x++ ) {
		for( var y = 0; y < numberOfRows; y++ ) {
			imageFiles[idx++] = "c0" + (x+1) + "_s0" + (y+1) + ".png"
		}
	}
	imageFiles[idx++] = "new.png";
	imageFiles[idx++] = "help.png";
	imageFiles[idx++] = "yes.png";
	imageFiles[idx++] = "now.png";
	imageFiles[idx++] = "return.png";
	imageFiles[idx++] = "solution.png";
	
	document.imageArray = new Array(imageFiles.length);
	for(var i=0; i<imageFiles.length; i++)
	{
	  document.imageArray[i] = new Image;
	  document.imageArray[i].src = imageFiles[i];
	}
	
	
	setup();
}

//Remove all elements of the grid
function removeAllChildren (parent)
{
	while (parent.hasChildNodes()) {
		parent.removeChild(parent.firstChild);
	}
}

// get a random piece from the array, set it to null
function randomPiece( arr ) {
	piece = null
	while( piece == null ) {
		x = Math.floor(Math.random() * (numberOfColumns * numberOfRows) )
		piece = arr[x]
		if (piece != null ) {
			arr[x] = null
		}
	}
	return piece;
}

//Reset the grid
function resetGrid()
{
	oneSelected = false;	
	toFill = new Array( numberOfColumns * numberOfRows );
	for( var i = 0; i < numberOfColumns; i++ ) {
		for( var j = 0; j < numberOfRows; j++ ) {
			toFill[i*5 + j] = "c0" + (i+1) + "_s0" + (j+1) + ".png"
		}
	}

	grid = new Array(numberOfColumns);
	selected = new Array(numberOfColumns);
	dirty = new Array(numberOfColumns);
	
	for( var x = 0; x < numberOfColumns; x++ ) {
		grid[x] = new Array(numberOfRows);
		selected[x] = new Array(numberOfRows);
		dirty[x] = new Array(numberOfRows);
		
		for( var y = 0; y < numberOfRows; y++ ) {
			grid[x][y] = randomPiece( toFill );
			selected[x][y] = false;
			dirty[x][y] = false;
		}
	}
}

function help() {
	setText( "<p><b>Baffle!</b></p>" +
			 "<p><b>To play Baffle!</b> Align the pieces so that every row, column, and major diagonal has 1 piece of each color and each shape.  Tap on 2 pieces to swap them.</p>" +
	         "<p>Baffle! was created by Flying Rabit Enterprises - <a href=\"http://www.bafflegame.com/\">www.bafflegame.com</a>.   This is just a sample of the entire Baffle! game and its variations, you can purchase the full game at <a href=\"http://www.bafflegame.com/\">www.bafflegame.com</a>.</p>" +
				  "<p>Baffle! is programmed for iPhone by<br/> Mike Helmick - <a href=\"http://mikehelmick.com/\">http://mikehelmick.com/</a></p>" +
				  "<p><a href=\"#\" onClick=\"redrawGrid();\"><img src=\"return.png\"></a></p>" );	
}

//Set up the game on the page using DOM elements
function setup()
{
	resetGrid();
	redrawGrid();
	allowClicks = true;
}


// clears the main content area 'grid' and draws the pieces
function redrawGrid() {
	var gridTable = document.getElementById('grid');
	removeAllChildren(gridTable);
	for( var y = 0; y < numberOfRows; y++ ) {
		var row = document.createElement('tr');
		for( var x = 0; x < numberOfColumns; x++ ) {
			var col = document.createElement('td');
			var img = document.createElement('img');
			img.setAttribute("onclick", "click("+x+","+y+")");
			img.setAttribute("src", grid[x][y] );
			img.setAttribute("id", x+"_"+y);
			img.setAttribute("border", "0");
			img.setAttribute("style","margin: 0; padding: 0; border: 2px solid black;");
			
			col.appendChild(img);
			col.setAttribute("style","margin: 0; padding: 0; border: 0;");
			
			row.appendChild(col);
		}
		gridTable.appendChild(row);
	}
}

function swapSelected() {
	var x1 = -1, y1 = -1, x2 = -1, y2 = -1;
	
	// determine which two pieces should be swapped
	for( var i = 0; i < numberOfColumns && x2 < 0; i++ ) {
		for( var j = 0; j < numberOfRows; j++ ) {
			if ( selected[i][j] ) {
				if ( x1 < 0 ) {
					x1 = i;
					y1 = j;
				} else {
					x2 = i;
					y2 = j;
				}
			}
		}
	}
	
	var tmp = document.images[x1+"_"+y1].src
	document.images[x1+"_"+y1].src = document.images[x2+"_"+y2].src
	document.images[x2+"_"+y2].src = tmp
	
	document.images[x1+"_"+y1].style.border = "2px solid black";
	document.images[x2+"_"+y2].style.border = "2px solid black";
	
	tmp = grid[x1][y1];
	grid[x1][y1] = grid[x2][y2];
	grid[x2][y2] = tmp;
	
	selected[x1][y1] = false;
	selected[x2][y2] = false;
}

function resetBooleanArrays( arr, arr2 ) {
	for( var i = 0; i < arr.length; i++ ) {
		arr[i] = false;
		arr2[i] = false; 
	}
}

function allOn( arr, arr2 ) {
	for( var i = 0; i < arr.length; i++ ) {
		if ( !arr[i] || !arr2[i] ) {
			return false;
		}
	}
	return true;	
}

// check for a valid baffle solution
function solved() {
	var isSolved = true;
	
	var colors = new Array( numberOfColumns );
	var shapes = new Array( numberOfColumns );
	resetBooleanArrays( colors, shapes );
	
	// check rows
	for( var i = 0; i < numberOfRows && isSolved; i++ ) {
		for( var j = 0; j < numberOfColumns; j++ ) {
			colors[extractColor( grid[j][i] ) - 1] = true;
			shapes[extractShape( grid[j][i] ) - 1] = true;
		}
		//alert(colors);
		//alert(shapes);
		
		isSolved = allOn( colors, shapes );
		resetBooleanArrays( colors, shapes );
	}
	// check cols
	for( var i = 0; i < numberOfRows && isSolved; i++ ) {
		for( var j = 0; j < numberOfColumns; j++ ) {
			colors[extractColor( grid[i][j] ) - 1] = true;
			shapes[extractShape( grid[i][j] ) - 1] = true;
		}
		//alert(colors);
		//alert(shapes);
		
		isSolved = allOn( colors, shapes );
		resetBooleanArrays( colors, shapes );
	}

	// diagional 1
	for( var i = 0; i < numberOfRows && isSolved; i++ ) {
		colors[extractColor( grid[i][i] ) - 1] = true;
		shapes[extractShape( grid[i][i] ) - 1] = true;
	}
	isSolved = allOn( colors, shapes );
	resetBooleanArrays( colors, shapes );
	
	// diagional 2
	for( var i = 0; i < numberOfRows && isSolved; i++ ) {
		colors[extractColor( grid[4-i][i] ) - 1 ] = true;
		shapes[extractShape( grid[4-i][i] ) - 1 ] = true;
	}
	isSolved = allOn( colors, shapes );
	resetBooleanArrays( colors, shapes );
	
	return isSolved;
}

function alertArray( arr ) {
	var t = "";
	for( var i = 0; i < arr.length; i++ ) {
		t = t + " " + arr[i];
	}
	alert(t);
}

function extractColor( image ) {
	var i = image.indexOf("c0");
	return parseInt( image.substr(i+2, 1 ) );
}

function extractShape( image ) {
	var i = image.indexOf("s0");
	return parseInt( image.substr(i+2, 1 ) );	
}

function setText( text ) {
	var gridTable = document.getElementById('grid');
	removeAllChildren(gridTable);
	
	var row = document.createElement('tr');
	var col = document.createElement('td');
	col.setAttribute("width", "100%");
	col.setAttribute("align", "center");
	col.setAttribute("style", "margin-top: 25px;");

	col.innerHTML = text;
	row.appendChild( col );
	gridTable.appendChild( row );
}

function checkNewGame() {
	setText( "<div align=\"center\" style=\"padding-left: 50px\"><h2><b>New Game?</b></h2>" +
		"<p style=\"text-align: center;\"><a href=\"#\" onClick=\"setup();\"><img src=\"yes.png\" /></a><br/>" +
		"<a href=\"#\" onClick=\"redrawGrid();\"><img src=\"no.png\" /></a></p></div>" );
}

function doWin() {
	setText( "<div align=\"center\"><p><b>Baffle!</b></p>" +
	              "<p><b>Congratulations!<br/>You have solved the Baffle! classic game!</p>" +
	 			  "There are more variations of Baffle! available in the desktop version, visit <a href=\"http://www.bafflegame.com/\">www.bafflegame.com</a> to download a demo or purchase the full version." +
				  "<p><a href=\"#\" onClick=\"redrawGrid();\"><img src=\"solution.png\"></a></p></div>" );
}

function click(x, y)
{
	if( ! allowClicks ){
		return;
	}	
	
	if ( oneSelected ) {
		// swap
		if ( selected[x][y] ) {
			// same one - unselect
			selected[x][y] = false;
			oneSelected = false;
			document.images[x+"_"+y].style.border = "2px solid black";
		} else {
			oneSelected = false;
			selected[x][y] = true;
			swapSelected();	
			
			if ( solved() ) {
				allowClicks = false;
				doWin();
			}		
		}
		
	} else {
		selected[x][y] = true;
		oneSelected = true;
		document.images[x+"_"+y].style.border = "2px solid red";
		
	}
}