
 /*
Copyright (C) 2007 Bruce Martin. All Rights Reserved.
 Portions:
 Copyright (C) 2007 Apple Inc. All Rights Reserved.
 
 */ 
 
 // Set up basic in-game variables
// The number of columns (numberOfColumns) and rows (numberOfRows) of the game. 
//The grid array contains numbers ranging from 1 to 5, which represent the different ball images.
//The selected array contains either true or false. True indicates that the current cell is selected.
//The dirty array contains either true or false values. True indicates that the current cell contains a grey ball. 

var numberOfColumns = 7;
var numberOfRows = 7;

var grid = [];
var selected = [];
var dirty = [];
var allowClicks = true;
var gScore=0;
var gPossibleScore=0;
var gMultiplyer=1;
var gEndLevel=0;
var gUserLevel=1;
var gRandomPhrases=[];
var gLevelHasChanged=false;
var goRight=true;
var goLeft=false;
var goDown=true;
var goUp=false;
var gGoUpOrDown=goDown;
var gGoLeftOrRight = goRight;
//Set Up random Phrases
function initPhrases(){
//['Game Over!','Try Again!','Better Luck Next Time!','Not Quite!','Almost!'];
//Automate this later
gRandomPhrases=new Array(5);
gRandomPhrases[0]="Game Over!";
gRandomPhrases[1]="Try Again!";
gRandomPhrases[2]="Better Luck Next Time!";
gRandomPhrases[3]="Not Quite!";
gRandomPhrases[4]="Almost!";
}

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

//Reset the grid
function resetGrid()
{

	grid = new Array(numberOfColumns);
	selected = new Array(numberOfColumns);
	dirty = new Array(numberOfColumns);
	gPossibleScore=0;
	if(gEndLevel<(numberOfColumns*numberOfRows)){
		gScore=0;
		gUserLevel=1;
		gLevelHasChanged=false;
		gGoLeftOrRight=goRight;
		gGoUpOrDown=goDown;
	}else{
	gUserLevel++;
	gLevelHasChanged=true;
	}
	var tUseNumBalls = gUserLevel+2;
	if (tUseNumBalls > 5){
	tUseNumBalls=5;
	}
	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] = 1 + Math.floor(Math.random() * tUseNumBalls);
			selected[x][y] = false;
			dirty[x][y] = false;
		}
	}
	
	var tLevel=document.getElementById('theLevel');
	tLevel.firstChild.nodeValue=gUserLevel;
	gEndLevel=0;
	
	
	var thePossibleScore=document.getElementById('possible');
	thePossibleScore.firstChild.nodeValue=gPossibleScore;
	var theScore=document.getElementById('score');
	theScore.firstChild.nodeValue=gScore;
}

//Set up the game on the page using DOM elements
function setup()
{ 
var theHighScore = document.getElementById('highScore');
if(theHighScore.firstChild.nodeValue< gScore){
theHighScore.firstChild.nodeValue=gScore;

}
var theGameOver=document.getElementById('gameOver');
theGameOver.style.display='none';
allowClicks=true;
	resetGrid();
	
	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');
			col.setAttribute("class","gridCell");
			var img = document.createElement('img');
			img.setAttribute("onclick", "click("+x+","+y+")");
			img.setAttribute("src", "images/ice-"+grid[x][y]+".png");
			img.setAttribute("id", x+"_"+y);
			img.setAttribute("numberOfColumns", 32);
			img.setAttribute("numberOfRows", 32);
			img.setAttribute("width", 36);
			img.setAttribute("height", 36);
			col.appendChild(img);
			
			row.appendChild(col);
		}
		gridTable.appendChild(row);
	}
	gridTable.setAttribute("height",(36*numberOfRows));
}

//Update image at position represented by (x,y)
function updateCell(x, y)
{
    var newSrc;
	if( selected[x][y] ){
        newSrc = "images/ice-sel.png";
    }    
    else {
        newSrc = "images/ice-"+grid[x][y]+".png";
    }    
        
	document.images[x+"_"+y].src = newSrc;
}


//Update all images on the grid
function updateAllCells()
{
	for( var y = 0; y < numberOfRows; y++ ) {
		for( var x = 0; x < numberOfColumns; x++ ) {
			updateCell(x, y);
		}
	}
}


function updateAllDirtyCells()
{
	for( var y = 0; y < numberOfRows; y++ ) {
		for( var x = 0; x < numberOfColumns; x++ ) {
			if( dirty[x][y] ) {
				updateCell(x, y);
				dirty[x][y] = false;
				
			}
		}
	}
}

function removeSelectedCells()
{
var tCnt=0;
gPossibleScore=0;
var thePossibleScore=document.getElementById('possible');
thePossibleScore.firstChild.nodeValue=gPossibleScore;
	for( var y = 0; y < numberOfRows; y++ ) {
		for( var x = 0; x < numberOfColumns; x++ ) {
			if( selected[x][y] ) {
				grid[x][y] = 0;
				selected[x][y] = false;
				dirty[x][y] = true;
				tCnt=tCnt+1;
				
			}
		}
	}
	
	gEndLevel=gEndLevel+tCnt;
	gScore= gScore+(tCnt*(tCnt*gMultiplyer));
	var theScore=document.getElementById('score');
	theScore.firstChild.nodeValue=gScore;
}


function fallDown()
{

    var fallTo,foundGap;
	for( var x = numberOfColumns-1; x >= 0; x-- ) {
		foundGap = false;
		for( var y = numberOfRows-1; y >= 0; y-- ) {
			if( grid[x][y] == 0 ) {
				if( ! foundGap ) {
					fallTo = y;
					foundGap = true;
				}
			}
			else { // grid occupied
				if( foundGap ) {
					grid[x][fallTo] = grid[x][y];
					grid[x][y] = 0;
					dirty[x][fallTo] = true;
					dirty[x][y] = true;
					fallTo -= 1;
				}
			}
		}
	}
}

function fallUp()
{

    var fallTo,foundGap;
	for( var x =0;x <= numberOfColumns-1; x++ ) {
		foundGap = false;
		for( var y =0;y <= numberOfColumns-1; y++ ) {
			if( grid[x][y] == 0 ) {
				if( ! foundGap ) {
					fallTo = y;
					foundGap = true;
				}
			}
			else { // grid occupied
				if( foundGap ) {
					grid[x][fallTo] = grid[x][y];
					grid[x][y] = 0;
					dirty[x][fallTo] = true;
					dirty[x][y] = true;
					fallTo += 1;
				}
			}
		}
	}
}

//Make them fall left
function fallLeft()
{

     var fallTo,foundGap;
	for( var y = 0;y<=numberOfRows-1;y++ ) {
	    foundGap = false;
		for( var x = 0;x<=numberOfColumns-1; x++ ) {
			if( grid[x][y] == 0 ) {
				if( ! foundGap ) {
					fallTo = x;
					foundGap = true;
				}
			}
			else { // grid occupied
				if( foundGap ) {
					grid[fallTo][y] = grid[x][y];
					grid[x][y] = 0;
					dirty[fallTo][y] = true;
					dirty[x][y] = true;
					fallTo += 1;
				}
			}
		}
	}
}


function fallRight()
{

     var fallTo,foundGap;
	for( var y = numberOfRows-1; y >= 0; y-- ) {
	    foundGap = false;
		for( var x = numberOfColumns-1; x >= 0; x-- ) {
			if( grid[x][y] == 0 ) {
				if( ! foundGap ) {
					fallTo = x;
					foundGap = true;
				}
			}
			else { // grid occupied
				if( foundGap ) {
					grid[fallTo][y] = grid[x][y];
					grid[x][y] = 0;
					dirty[fallTo][y] = true;
					dirty[x][y] = true;
					fallTo -= 1;
				}
			}
		}
	}
}

function deselectAllCells()
{
	for( var y = 0; y < numberOfRows; y++ ) {
		for( var x = 0; x < numberOfColumns; x++ ) {
			if( selected[x][y] ) {
				selected[x][y] = false;
				dirty[x][y] = true;
			}
		}
	}
}

//Determines whether each of the 4 neighbors(top,bottom,left, and right) of a
//cell is equal to that current cell
function cellHasIdenticalNeighbour(x, y)
{
	var cell = grid[x][y];
	if( ( x+1 < numberOfColumns  && cell == grid[x+1][y] )
	 || ( x-1 >= 0     && cell == grid[x-1][y] )
	 || ( y+1 < numberOfRows && cell == grid[x][y+1] )
	 || ( y-1 >= 0     && cell == grid[x][y-1] ) ) {
		return true;
	}
	else {
		return false;
	}
}
//check to see if there are any more matches that can be made.
//If not end game.
function isStuck()
{
	for( var y = 0; y < numberOfRows; y++ ) {
		for( var x = 0; x < numberOfColumns; x++ ) {
			if (grid[x][y] != 0){
				if (cellHasIdenticalNeighbour(x, y) == true){
				return false;
				}
			}
		}
	}
	return true;
}
//Select all contiguous cells of the same color
function selectCellAndContiguousCells(cell, x, y)
{
	if( x >= 0 && x < numberOfColumns && y >= 0 && y < numberOfRows ) {
		if( cell == grid[x][y] && ! selected[x][y] ) {
			selected[x][y] = true;
			dirty[x][y] = true;
			selectCellAndContiguousCells( cell, x+1, y );
			selectCellAndContiguousCells( cell, x-1, y );
			selectCellAndContiguousCells( cell, x, y+1 );
			selectCellAndContiguousCells( cell, x, y-1 );
			gPossibleScore = gPossibleScore+1;
			
			var thePossibleScore=document.getElementById('possible');
			thePossibleScore.firstChild.nodeValue=(gPossibleScore*(gPossibleScore*gMultiplyer));
			
		}
	}
}
function fallLeftAndAllowClicks()
{
	fallLeft();
	updateAllDirtyCells();
	allowClicks = true;
}

function fallRightAndAllowClicks()
{
	fallRight();
	updateAllDirtyCells();
	allowClicks = true;
}


function fallDownThenFallRightAndAllowClicks()
{
	fallDown();
	updateAllDirtyCells();
    fallRightAndAllowClicks();
}

function fallDownThenFallLeftAndAllowClicks()
{
	fallDown();
	updateAllDirtyCells();
    fallLeftAndAllowClicks();
}

function fallUpThenFallRightAndAllowClicks()
{
	fallUp();
	updateAllDirtyCells();
    fallRightAndAllowClicks();
}

function fallUpThenFallLeftAndAllowClicks()
{
	fallUp();
	updateAllDirtyCells();
    fallLeftAndAllowClicks();
}

function click(x, y)
{
	// - if a given cell is selected:
	//   - remove all the selected cells
	//   - fall down
	//   - fall right
	//   - if the bottom-left cell is empty, add another (partial) column on the left and let it fall right
	// - if that cell is not selected, but is occupied:
	//   - deselect all cells
	//   - if there is an adjacent cell of the same color
	//     - select all contiguous cells of the same color
	
	if( ! allowClicks ){
		return;
	}	
	
	if( selected[x][y] ) {
		removeSelectedCells();
		updateAllDirtyCells();

		allowClicks = false;
		if (gLevelHasChanged){
			if(Math.floor(1+Math.random()*2)==1){
				gGoLeftOrRight=goRight;
				/*if(Math.floor(1+Math.random()*2)==1){
					gGoUpOrDown=goDown;
					setTimeout("fallDownThenFallRightAndAllowClicks();", 100);
				}else{ */
					gGoUpOrDown=goUp;
					setTimeout("fallUpThenFallRightAndAllowClicks();", 100);
			//	}
			}else{
				gGoLeftOrRight=goLeft;
				/*if(Math.floor(1+Math.random()*2)==1){
					gGoUpOrDown=goDown;
					setTimeout("fallDownThenFallLeftAndAllowClicks();", 100);
				}else{ */
					gGoUpOrDown=goUp;
					setTimeout("fallUpThenFallLeftAndAllowClicks();", 100);
			//	}
				
			}
			gLevelHasChanged=false;
		}else{
		
			if(gGoLeftOrRight==goRight){
				gGoLeftOrRight=goRight;
				/* if(gGoUpOrDown==goDown){
					setTimeout("fallDownThenFallRightAndAllowClicks();", 100);
				}else{ */
					setTimeout("fallUpThenFallRightAndAllowClicks();", 100);
				//}
			}else{
				gGoLeftOrRight=goLeft;
				/* if(gGoUpOrDown==goDown){
					setTimeout("fallDownThenFallLeftAndAllowClicks();", 100);
				}else{ */
					setTimeout("fallUpThenFallLeftAndAllowClicks();", 100);
				//}
				
			}
		}
			
		setTimeout("checkGameOver();",110);
		}
	 else if( grid[x][y] != 0 ) {
		deselectAllCells();
		if( cellHasIdenticalNeighbour( x, y ) ){
			selectCellAndContiguousCells( grid[x][y], x, y );
		/* }else if(isStuck()==true){
			var theGameIsOver =document.getElementById('gameOver');
			theGameIsOver.style.display='block';
			theGameIsOver.nodeValue="Game Over";
			allowClicks =false;*/
		} 
		updateAllDirtyCells();
		
		gPossibleScore = 0;
		var tLevel=document.getElementById('theLevel');
		tLevel.firstChild.nodeValue=gUserLevel;
	}
	if (gEndLevel == (numberOfColumns*numberOfRows)){
		setup();
		}
	


	
}
function checkGameOver(){
	if(isStuck()==true){
		initPhrases();
		var theGameIsOver =document.getElementById('gameOver');
		var tPhrase=Math.floor(Math.random() * 5);
		theGameIsOver.firstChild.nodeValue=gRandomPhrases[tPhrase];
		var theHighScore = document.getElementById('highScore');
		var p = document.getElementById('msg');
		if(theHighScore.firstChild.nodeValue< gScore){
			theHighScore.firstChild.nodeValue=gScore;
			
			/*if (p.hasChildNodes()!=true){
				theMsg=document.createTextNode("New High Score!");
				p.appendChild(theMsg);
			}else{ */
			theGameIsOver.firstChild.nodeValue="Great Game!";
				p.firstChild.nodeValue="New High Score!";
			//}
			//theGameIsOver.appendChild(p);
		}else{
		p.firstChild.nodeValue=" ";
		}
		rollAd();
		theGameIsOver.style.display='block';
		allowClicks =false;
	}
}

//Handle Ads 
function rollAd(){
if(Math.floor(1+Math.random()*3)==1){
insertYencoAd("magicdice");
}else{
insertbluelineAd("theCastle");
}
}


function insertbluelineAd(pAdName){
	var col = document.getElementById('adSpace');
	if(document.getElementById('theAdImg')== null){
		var theAd = document.createElement('img');
		if (pAdName =="theCastle"){
			theAd.setAttribute("onclick", "window.open("+"\""+"http://www.blueline-studios.com/castle/"+"\");");
			theAd.setAttribute("id","theAdImg");
			theAd.setAttribute("src", "../ads/bluelinestudio/theCastle/castlebanner.jpg");
			theAd.setAttribute("width", 180);
			theAd.setAttribute("height", 150);
		}
		col.appendChild(theAd);
	}else{
		var theAd = document.getElementById('theAdImg');
		if (pAdName =="theCastle"){
			theAd.setAttribute("onclick", "window.open("+"\""+"http://www.blueline-studios.com/castle/"+"\");");
			theAd.setAttribute("id","theAdImg");
			theAd.setAttribute("src", "../ads/bluelinestudio/theCastle/castlebanner.jpg");
			theAd.setAttribute("width", 180);
			theAd.setAttribute("height", 150);
		}
	}
	
}

function insertYencoAd(pAdName){
var col = document.getElementById('adSpace');

if(document.getElementById('theAdImg')== null){
var theAd = document.createElement('img');
	if (pAdName =="magicdice"){
			theAd.setAttribute("onclick", "window.open("+"\""+"http://www.yenco.com/magicdice"+"\");");
			theAd.setAttribute("id","theAdImg");
			theAd.setAttribute("src", "../ads/yenco/magicdice/MagicDiceAd.gif");
			theAd.setAttribute("width", 180);
			theAd.setAttribute("height", 150);
	}
	col.appendChild(theAd);
 }else{
 var theAd = document.getElementById('theAdImg');
	if (pAdName =="magicdice"){
			theAd.setAttribute("onclick", "window.open("+"\""+"http://www.yenco.com/magicdice"+"\");");
			theAd.setAttribute("id","theAdImg");
			theAd.setAttribute("src", "../ads/yenco/magicdice/MagicDiceAd.gif");
			theAd.setAttribute("width", 180);
			theAd.setAttribute("height", 150);
		}
	}
}



//Handle image rollOver.
gNumImages = 0;
var lastButton="";
function psHover(bName) 
{
	if (document.images) 
	{
		if (lastButton != "")
			psNormal(lastButton);

		lastButton=bName;
		if (!document.images[bName])
			return false;

		document.images[bName].src = hoverSrc[bName];
		if (clickSrc[bName])
		{
			tmpImage = new Image();
			tmpImage.src = clickSrc[bName];
			delete tmpImage;
		}
		if (imgStatusText[bName] != "")
		{ self.status = imgStatusText[bName]; return true; }
	}
	return false;
}

function psClick(bName) 
{
	if (document.images) 
	{
		lastButton=bName;
		if (!document.images[bName] || clickSrc[bName]=="")
			return true;

		document.images[bName].src = clickSrc[bName];
	}
	return true;
}

function psNormal(bName)
{
	if(document.images && bName != "")
	{
		if (document.images[bName])
			document.images[bName].src = normalSrc[bName];

		if (imgStatusText[bName] != "")
		{	self.status = ""; return true; }
	}
	return false;
}

function psRegImages(bName, normalSource, hoverSource, clickSource, width, height, statusText)
{
	if (document.images) 
	{
		gNumImages++;
		normalSrc[bName] = normalSource;
		hoverSrc[bName] = hoverSource;
		clickSrc[bName] = clickSource;
		imgStatusText[bName] = statusText;

		hoverImg[bName] = new Image();
		hoverImg[bName].src = hoverSource;
	}
}

if (document.images)
{
	hoverSrc	=	new Array(gNumImages);
	normalSrc	=	new Array(gNumImages);
	clickSrc	=	new Array(gNumImages);
	hoverImg	=	new Array(gNumImages);
	imgStatusText = new Array (gNumImages);
}