//========================================================================
//   "MemorySquares" JavaScript Memory Game
//
//   Copyright (C) 2000,2002  Jan Mulder
//
//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation; either version 2 of the License, or
//   (at your option) any later version, and as long as this notice is
//   kept unmodified at the top of the JavaScript source code.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License (license.txt) for more details.
//
//   Contact: Jan Mulder info@EnglishCafe.co.uk
//
//=======================================================================

imageCount = 0;
numImages = 0;
numPairs = 0;
numCorrect = 0;
numWrong = 0;
numAttempts = 0;
numMinutes = 0;
numSeconds = 0;
timeLeft = 0;
isTimed = false;
timerOn = false;
gameOver = false;

var progressBar = '||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||';

var solvedItems = new Array();
var randArray = new Array();  // randomised with excess pairs removed
var tempArray = new Array();
var imsArray = new Array();

function arrayDeletePair( arrayName, delIndex ) {
  var ar = new Array();
  for (var ii = 0; ii < arrayName.length; ii++)
  {
     if ((ii != delIndex) && (ii != (delIndex+1)))
      ar[ar.length] = arrayName[ii];
  }
  return ar;
}

function randomizeArray( arrSrc ) {
  var arrOut = new Array();
  var arrIn = new Array();  
  for (var i = 0; i < arrSrc.length; i++) {
    arrOut[arrOut.length] = null; 
    arrIn[arrIn.length] = arrSrc[i]; 
  }  
  for (var i = 0; i < arrIn.length; i++) {
    while (arrOut[i.toString()] == null) {
      var rand = Math.round(Math.random()*(arrIn.length - 1));
      if (arrIn[rand] != null) {
        arrOut[i.toString()] = arrIn[rand];
        arrIn[rand] = null;
      }
    }
  }
  return arrOut;
}   

function getLeftSide( str, token ) {
   return str.substring(0, str.indexOf(token))
}

function getRightSide( str, token ) {
   return str.substring(str.indexOf(token)+1, str.length)
}

function getMatchingPairs( amount ) {
  var arr = new Array();
  var arr2 = new Array();

  for (var i=0; i < matchingPairs.length; i=i+2) {
    arr[arr.length] = matchingPairs[i] + '=' + matchingPairs[i+1];
  }
  
  arr = randomizeArray( arr );
  
  for (var i=0; i < arr.length; i++) {
    arr2[arr2.length] = "item"+i;
    arr2[arr2.length] = getLeftSide(arr[i], "=");
    arr2[arr2.length] = "item"+i;
    arr2[arr2.length] = getRightSide(arr[i], "=");
  }
  
  return arr2;
}	

function initializeGame() {
  tempArray = getMatchingPairs( numPairs );
  
  var count = numPairs*2;
  
  for (var i = 0; i < count; i++) {
    imageRem = count - i;
    var rand = Math.floor(Math.random()*imageRem);
    randArray[randArray.length] = tempArray[rand*2];
    randArray[randArray.length] = tempArray[(rand*2)+1];

    tempArray = arrayDeletePair(tempArray, rand*2);
  }
}

function doFunction(aFunction) {
 if (aFunction.indexOf('(') > -1)
   eval( aFunction );
 else
   eval(aFunction+'()');
}

function updateTime() {
  if (!timerOn) return;

  if(numSeconds == 59)
  {
    numMinutes++;
    numSeconds=0;
  }
  else
    numSeconds++;

  if ((isTimed) && !(gameOver))
  {
    timeLeft--;
    document.timerForm.timeLeft.value = timeLeft;
	if (timeLeft == 0)
	{
	  gameOver = true;
      numAttempts = numCorrect + numWrong;
      doFunction(doneAction);
	}
  }	
}

function startTimer() {
  numSeconds = 0;
  numMinutes = 0;
  timerOn = true;
  timer=setInterval('updateTime()',1000);
}

function stopTimer() {
  timerOn = false;
  clearInterval(timer);
}

function onComplete() {
 window.status='Done';
}

function updateProgress(ims) {
 var cnt=0;

 for(var i = 0; i < ims.length; i++)
  if(ims[i].complete || ims[i].errored) cnt++;

 if(ims.length > 0)
    window.status='Loading ['+Math.round((cnt / imageCount)*100)+'%] ' + progressBar.substring(0, cnt);

 if(cnt < ims.length)
 {
  imsArray = ims;
  setTimeout("updateProgress(imsArray)",200);
 }
 else
  onComplete();
}

function preloadImgs() {
 imageCount = matchingPairs.length;

 this.length = imageCount;

 for (var i = 0; i < matchingPairs.length; i++)
 {
  this[i] = new Image();
  this[i].errored=false;
  this[i].onerror=new Function("this["+i+"].errored=true");
  this[i].src = matchingPairs[i];
 }

 updateProgress(this);
}

function drawTimer( amount ) {
  isTimed = true;
  timeLeft = amount;
  document.writeln('<FORM name="timerForm">');
  document.writeln(
  '<TABLE border="1" cellspacing="0" cellpadding="1"><TR>'
  +'<TD background="memory/timer.gif"><IMG border=0 SRC="memory/dotclear.gif" width="85" height="20"><input type="text" size="3" name="timeLeft" value="'+timeLeft+'"></TD>'
  +'</TR></TABLE></FORM>'
  );
}

function drawTable(width, height) {
 numPairs = (width*height)/2;
 
 initializeGame();
 
 window.defaultStatus = "";
 var isNetscape = (navigator.appName == "Netscape");

 document.write('<table border="1" cellspacing="0" cellpadding="0" bgcolor="white">');
 for (i = 0; i < height; i++)
 {
  document.write('<tr>');
  for (j = 0; j < width; j++)
  {
    document.write(
    '<td background="memory/question.gif">'
    );

    if (isNetscape)
      document.write(
      '<A  href="javascript:void(check(\'box'+(i*width+j)+'\'))"'
	  + ' onMouseOut="imgMouseOut()">'
      );

    document.write(
    '<img border="0" src="memory/question.gif" width="'
    + imageWidth
    + '" height="'
    + imageHeight
    + '" name="box'
    + (i*width+j)
    + '"'
    );

    if (!isNetscape)
      document.write(
      ' onClick="check(\'box' + (i*width+j) + '\')"'
	  + ' onMouseOut="imgMouseOut()"'
      );

    document.write(
    '></A><br></td>'
    );
  }
  document.write('</tr>');
 }
 document.write("</table>");
}

var lastID="none";
var lastItem="none";
var currentID = "";
var currentItem = "";
var numVisible = 0;
var wrongAnswer = false;

function resetChecked() {
  if (!wrongAnswer) return;
  wrongAnswer = false;
  numVisible = 0;
  eval("document."+currentID+".src = 'memory/question.gif';");
  eval("document."+lastID+".src = 'memory/question.gif';");
  lastID="none";
  lastItem="none";
}

function imgMouseOut() {
  if (numVisible == 2)
    if ((delay == 0) && (wrongAnswer))
	  resetChecked();
}

function check(boxID) {
  if (numVisible == 2)
    if (wrongAnswer)
	  resetChecked();
	else
      return;

  if ((gameOver) || (boxID == lastID)) return;
  
  itemIndex = parseInt(boxID.slice(3, boxID.length));
  if (checkSolved(randArray[2*itemIndex])) return;

  if (!timerOn) startTimer();

  if (numVisible==0)
  {
    numVisible = 1;
    lastID = boxID;
    itemIndex = parseInt(boxID.slice(3, boxID.length));
    lastItem = randArray[2*itemIndex];
    return eval("document."+boxID+".src = '"+randArray[2*itemIndex+1]+"';");
  }
  else if (numVisible==1)
  {
    numVisible=2;
    itemIndex = parseInt(boxID.slice(3, boxID.length));
    eval("document."+boxID+".src = '"+randArray[2*itemIndex+1]+"';");
    currentID = boxID;
    currentItem = randArray[2*itemIndex];
    checkItem2(currentItem);
  }
}

function checkItem2(item) {
  if(lastItem==item)
  {
    numVisible=0;
    wrongAnswer = false;
    if (!checkSolved(item))
    {
      solvedItems[solvedItems.length] = item;
      numCorrect++;
    }
    if (numCorrect >= numPairs)
    {
      stopTimer();
      if (doneAction != '')
      {
        gameOver = true;
        numAttempts = numCorrect + numWrong;
        doFunction(doneAction);
      }
    }
  }
  else if (lastItem!=item)
  {
    numWrong++;
    wrongAnswer = true;
	if (delay > 0)
      window.setTimeout("resetChecked()", delay);
  }
}

function checkSolved(iSolved) {
  found = false;
  for (var i=0; i < solvedItems.length; i++)
    if (solvedItems[i] == iSolved)
      found = true;

  return found;
}

var pictures = new preloadImgs();

//== DEBUGGING FUNCTIONS ==

function dumpArray( arr ) {
  document.write('<BR>Array Dump<BR>'); 	
  for (var i=0; i < arr.length; i++)
    document.write(arr[i] + '<BR>'); 
}

function debugStr( str ) {
    document.write( str + "<BR>" );
}