/****************************************************
 * Author: Kristján Einarsson.						*
 * Date: 15.11.2006.								*
 * Version 0.9										*
 * This is the pair game logic here the cards 		*
 * get flipped and paired together, then when		*
 * there are no more moves the player gets a		*
 * score.											*
 *													*
 * As well as game logic there is also a timer,		*
 * witch is a litle bit of a hack, ( take a look at	*
 * the timeRunner() method.							*
 *													*
 *													*
 * The animations are timed using setTimout()		*
 * and duration.									*	
 * 													*
 * The game relies on prototype and scriptaculous	*
 *													*
 *	WARNING this script is not maby easy to read,	*
 *	if one has improvements please let me know!		*
 *													*
 ***************************************************/
 
// Global variables.
var counter = 0;
var movements = 0;
var elementIDs = new Array();
var ids = new Array();
var howManyOpen = 0;
var start;
var timeNotStared = true;
var oneMoveLeft = false;
var onmousedown;
var isActive = true;
var globalGridSize;
var lastPairArr = new Array();

/*
 * The gameController controls the game flow.
 * This function comes instead off using delay for closing open
 * signes, in short it directs the game flow by calling the rigth 
 * functions every time there is a click/mousedown even.
 */
function gameController( elementid, gridSize) {
	this.startTime();
	var halfGridSize = gridSize/2;  // number of images
	globalGridSize = gridSize;
	lastPairArr[counter] = elementid;
	if(isActive) {
		isActive = false;
		if( elementIDs[0] != elementid && elementIDs[1] != elementid && counter != 2 ) {
			new Effect.Opacity( elementid, { duration: 0.01, transition: Effect.Transitions.linear, from: 1.0, to: 0.02, afterefinish: flipCard( elementid ) } );
		}
		else if( counter == 2) {
			    isPair( halfGridSize, elementid)
				if( elementIDs[0] != elementid && elementIDs[1] != elementid && counter != 2 ) {
					new Effect.Opacity( elementid, { duration: 0.1, transition: Effect.Transitions.linear, from: 1.0, to: 0.02 } );
					flipCard( elementid );
				}
		}
		else if( counter == 1 )
			setActive();
	}
}

/*
 * sets the isActive variable to true, so one can flip annother card
 */
function setActive() {
	isActive = true;
}

/* 
 * Flips the card over.  To cards flipped over counts as one movement.
 */
function flipCard( elementid ) {
	// the style for the flipped card.
	var card = 'card' + elementid;
	// get the onmouseover event and disable it.
	onmousedownVar = $( elementid ).onmousedown;
	$( elementid ).onmousedown = '';
	
	// switch to the new class thus flipping the card. card with pics

	setTimeout("$('"+ elementid +"').className = '"+ card +"' + ' sharedCardStyle';", 80 );
	setTimeout("new Effect.Opacity('"+ elementid +"', { duration: 0.1, transition: Effect.Transitions.linear, from: 0.02, to: 1.0, afterfinish: setActive() } );", 80 ); 
	
	// eneable the onmousedown again ( though it cannot be flipped )
	setTimeout("$('"+ elementid +"').onmousedown = onmousedownVar;", 80 );
	elementIDs[counter] = elementid;
	ids[counter] = card;
	counter++;
	
	// add game movement, if the onemoveLeft is true the game will stop.
	if(counter == 2 ) {
		movements++;
		$( 'movements' ).innerHTML = movements;
		
		// no more move's left the game is over.
		if( oneMoveLeft ) {
			clearInterval( start ) // stops the time by stopping the interval
			setTimeout( "gameOver( movements );", 10);  // the game is finished and score is calculated
		}
	}
}

/* 
 * Checks out if the cards are pair or not, if not it will flip them over.
 * It finds out if it is pair by: ( elementID1 - elementID2) == ( (+/-)( gridSize/2) ).
 * if somthing is unclear about that just send me a line kristjane@us.is :-)
 */
function isPair( halfGridSize, elementid ) {
	if( (( elementIDs[0] - elementIDs[1] ) == halfGridSize) || (( elementIDs[0] - elementIDs[1] ) == (-1*halfGridSize) ) && ( (elementIDs[0] != elementid) || (elementIDs[1] != elementid)) ) {
		// ok it is a pair! howManyOpen is raised and see if it is the last game.
		howManyOpen++;
		if( howManyOpen == (halfGridSize-1) ) {
			oneMoveLeft = true;
		}
		// disable the onmousedown so the card cannot be flipped again.
		$( elementIDs[0] ).onmousedown = '';
		$( elementIDs[1] ).onmousedown = '';
		setActive();
	}
	else if( elementIDs[0] == elementid || elementIDs[1] == elementid && ((( elementIDs[0] - elementIDs[1] ) == halfGridSize) || (( elementIDs[0] - elementIDs[1] ) == (-1*halfGridSize)) ) )
		flipToFrontCard();
	else  // not pair
		flipToFrontCard();
	
	counter = 0;
}

/*
 * turn the card back to the front card.
 */
function flipToFrontCard() {
	new Effect.Opacity( elementIDs[0], { duration: 0.1, transition: Effect.Transitions.linear, from: 1.0, to: 0.02 } );
	setTimeout("$('"+ elementIDs[0] +"').className = 'frontCardStyle sharedCardStyle';", 80 );
	setTimeout("new Effect.Opacity( '"+ elementIDs[0] +"', { duration: 0.1, transition: Effect.Transitions.linear, from: 0.02, to: 1.0 } );", 80 );
	elementIDs[0] = '';
	
	new Effect.Opacity( elementIDs[1], { duration: 0.1, transition: Effect.Transitions.linear, from: 1.0, to: 0.02 } );
	setTimeout("$('"+ elementIDs[1] +"').className = 'frontCardStyle sharedCardStyle';", 80 );
	setTimeout("new Effect.Opacity( '"+ elementIDs[1] +"', { duration: 0.1, transition: Effect.Transitions.linear, from: 0.02, to: 1.0, afterFinish: setActive() } );", 80 );
	elementIDs[1] = '';
}

/* 
 * Start the timer.
 */
function startTime() {
	if( timeNotStared ) {
		start = setInterval("timeRunner()",1000);
		timeNotStared = false;
	}
}

/*
* The timeRunner is the game clock. It gets the current value from the span
* in the HTML file then it adds 1 every second.  When it reach 60 seconds it 
* will restart the seconds and add one minute.  
* 
* The timeRunner usese the checkDigits to see if the time is (time < 10 ), then 
* the checkDigits will add 0 to the span 'xxxxxZero' span in the HTML.
*/
function timeRunner() {
	var spanSeconds = $('seconds');
	var currentSeconds = parseInt(spanSeconds.childNodes[0].nodeValue) + 1;
	
	checkDigits(currentSeconds, 'secondsZero');
	spanSeconds.childNodes[0].nodeValue = currentSeconds;
	
	if (currentSeconds == 60) {
		currenSeconds = 0;
		spanSeconds.childNodes[0].nodeValue = '00';
		var spanMinutes = $('minutes');
		var currentMinutes = parseInt(spanMinutes.childNodes[0].nodeValue) + 1;
		checkDigits( currentMinutes, 'minutesZero' );
		spanMinutes.childNodes[0].nodeValue = currentMinutes;
	}
}
  
  /*
   * see above
   */
function checkDigits( currentSeconds, elementID ) {
	if( currentSeconds < 10 ) {
		$( elementID ).innerHTML = '0';
	}
	else { 
		$( elementID ).innerHTML = '';
	}
}

function detectBrowser() {
	var browser=navigator.appName;
	//var b_version=navigator.appVersion;
	//var version=parseFloat(b_version):
	return browser;
}


/*
 * Congrads the player and displays the score,,, TODO Try again.
 */
function gameOver( movements) {
	var browser = detectBrowser();
	
	if( browser == 'Microsoft Internet Explorer' ) {
		var seconds = $( 'seconds' ).childNodes[0].nodeValue;
		var minutes = $( 'minutes' ).childNodes[0].nodeValue;
		switch ( globalGridSize ) {
			case 16: $( 'score' ).style.left = '145px';break;
			case 20: $( 'score' ).style.left = '195px';break;
			case 36: $( 'score' ).style.left = '246px';break;
		}
	}
	else {
		var seconds = $( 'seconds' ).childNodes[0].nodeValue;
		var minutes = $( 'minutes' ).childNodes[0].nodeValue;
		switch ( globalGridSize ) {
			case 16: $( 'score' ).style.left = '135px';break;
			case 20: $( 'score' ).style.left = '185px';break;
			case 36: $( 'score' ).style.left = '236px';break;
		}
	}
    $( 'score' ).innerHTML = 'Þú fékkst ' + calculateScore( minutes, seconds, movements ) + ' stig.' + ' <br />Tími: ' + minutes +' mín. og ' + seconds + 'sek';
	$( 'score' ).style.visibility = 'visible';
}

/*
 * Calculates the score, at the moment the score has NO meaning
 */
function calculateScore( minutes, seconds, movements ) {
	var totalTimeInSeconds = 0;
	if( minutes > 0 )
		totalTimeInSeconds = parseInt(minutes*60) + parseInt(seconds); 
	else
		totalTimeInSeconds = seconds;
	switch( globalGridSize ) {
		/* linear
		case 16 : if( (5000  + total ) < 0 ) return 0; else return ( 5000  - total );
		case 20 : if( (10000 + total ) < 0 ) return 0; else return ( 10000 - total );
		case 36 : if( (30000 + total ) < 0 ) return 0; else return ( 30000 - total );*/
		case 16 : if( 5000  - (Math.round( totalTimeInSeconds*movements )) < 0 ) return 0; else return ( 5000  - (Math.round( totalTimeInSeconds*movements )));
		case 20 : if( 10000 - (Math.round( totalTimeInSeconds*movements )) < 0 ) return 0; else return ( 10000 - (Math.round( totalTimeInSeconds*movements )));
		case 36 : if( 30000 - (Math.round( totalTimeInSeconds*movements )) < 0 ) return 0; else return ( 30000 - (Math.round( totalTimeInSeconds*movements )));
	}
}

function closeGameDescription() {
    $( 'gameDescription' ).style.visibility = "hidden";
    $( 'shaddowDescription' ).style.visibility = "hidden";
    $( 'noClickableLayer' ).style.visibility = "hidden";
    $( 'aroundDescription' ).style.visibility = "hidden";
}

