/*------------------------------------------------------------------------------*\
 * Marshall Arts Memory Game                                                    *
 * Initial programming by Markus Eichenberger                                   *
 * http://mypage.bluewin.ch/katzenseite                                         *
 * Subsequent programming by The Blame Productions                              *
 * http://www.blamepro.com                                                      *
 *                                                                              *
 * Version 1.0.0 25.06.2002 First Release                                       *
 * Version 1.0.1 02.08.2002 Date Y2K compatible                                 *
 * Version 2.0.0 04.11.2003 Marshall Arts revisions                             * 
\*------------------------------------------------------------------------------*/ 

 var IMG_OFFSET = 1;          // Index of the first picture in document.images[*]
 var IMG_PATH   = "images/";  // Path of the pictures
  
 // Index of the pictures in document.images[*]
 var IMG_START = 18 + IMG_OFFSET;
 var IMG_STOP  = 20 + IMG_OFFSET;
 var IMG_PLUS  = 28 + IMG_OFFSET;
 var IMG_MINUS = 24 + IMG_OFFSET;

 var IMG_LEVEL = 26 + IMG_OFFSET;
 var IMG_SEC   = 33 + IMG_OFFSET;
 var IMG_HIT   = 49 + IMG_OFFSET;
 var IMG_TRIAL = 41 + IMG_OFFSET;
 
 var nImages = 8;                               // Number of single pictures
 var arrHighScore    = new Array();             // Array of highscore objects 
 var imgArrField     = new Array(nImages * 2);  // Pictures of items
 var imgBackside     = new Image();             // The backside of card
 var imgArrStartStop = new Array(4);            // Start and stop button
 var imgArrPlusMinus = new Array(4);            // Plus and minus button
 var imgArrNumber    = new Array(11);           // Ciphers 0 to 9
 var bRunning        = false;                   // State of the game   
 var nLevel          =  4;                      // Speed level
 var nSeconds        =  0;                      // Duration of the game in seconds
 var nAttempts       =  0;                      // Number of attempts
 var nHit            =  0;                      // Number of hits
 var nSelected1      = -1;                      // First selected picture
 var nSelected2      = -1;                      // Second selected picture
 var bShowCard       = false;                   // State of the card (uncovered or not)
 var strPlayerName   = "xxx";                   // Name of player for highscore
 var strDate         = "";                      // Date for highscore
 var nPoints         = 0;                       // Points for highscore
 var bCookies        = false;                   // Cookies enabled ?
 
/*
 *  Preload of images
 */
 function loadImages()
 {
   if(document.images)
   {
     imgBackside.src  = IMG_PATH + "card.jpg";
     
     // Load start and stop button
     for(var i = 0; i < 4; i++)
     {
       imgArrStartStop[i] = new Image();
       imgArrStartStop[i].src = IMG_PATH + "startstop" + (i + 1) + ".gif";
     }

     // Load plus and minus button
     for(var i = 0; i < 4; i++)
     {
       imgArrPlusMinus[i] = new Image();
       imgArrPlusMinus[i].src = IMG_PATH + "plusminus" + (i + 1) + ".gif";
     }
     
     // Load ciphers
     for(var i = 0; i < 11; i++)
     {
       imgArrNumber[i] = new Image();
       imgArrNumber[i].src = IMG_PATH + i + ".gif";
     }

     // Load pictures
     for(var i = 0; i < nImages; i++)
     {
       img = new Image();
       img.src = IMG_PATH + "pic" + (i + 1) + ".jpg";
    
       imgArrField[i * 2] = new Image();
       imgArrField[i * 2 + 1] = new Image();
       imgArrField[i * 2].src = img.src;
       imgArrField[i * 2 + 1].src = img.src;
     }
     
     loadHighScore();
     nLevel = 4;
     nSeconds  =  0;
     nAttempts =  0;
     nHit      =  0;
     clearField();
     updateAll();
   }   
 }
 
/*
 *  Shuffle all pictures
 */
 function shuffle()
 {
   if(document.images)
   {
     // Swap two pictures (random index)
     var j = Math.floor(new Date().getSeconds() * Math.random() + 60);
     for(var i = 0; i < j; i++)
     {
       n1 = Math.round(Math.random() * (nImages * 2 - 1));
       n2 = Math.round(Math.random() * (nImages * 2 - 1));
       img = imgArrField[n1];
       imgArrField[n1] = imgArrField[n2];
       imgArrField[n2] = img;
     } 
   }
 }
  
/*
 *  Start new game
 */
 function startGame()
 {
   if(document.images)
   {
     if(!bRunning)
     {
       shuffle();
       clearField();
       nSeconds = 0;
       nSelected1 = -1;
       nSelected2 = -1;    
       nAttempts  =  0;
       nHit       =  0;
       id = setInterval("countSeconds()", 1000)
       bRunning = true;
       bShowCard = false;
       updateAll();
     }
   }
 }
  
/*
 *  Stop game
 */
 function stopGame()
 {
   if(document.images)
   {
     if(bRunning)
     {
       clearInterval(id);
       bRunning = false;
       updateAll();
     }
   }
   return;
 }
 
/*
 *  Count seconds
 */
 function countSeconds()
 {
   nSeconds++;
   showNumber(nSeconds, IMG_SEC, 5);
 }
 
/*
 *  Show numbers
 */
 function showNumber(nNumber, nPosition, nCount)
 {
   if(document.images)
   {
     nNumber += "";
     while(nNumber.length < nCount) nNumber = " " + nNumber;
     for(var i = 0; i < nCount; i++)
     {
       var n = nNumber.charAt(i);
       if(n == " ")
       {
         document.images[nPosition + i].src = imgArrNumber[10].src;
       }
       else
       {
         document.images[nPosition + i].src = imgArrNumber[n].src;
       }
     }
   }
 }
 
/*
 *  Set the backside of all cards
 */
 function clearField()
 {
   if(document.images)
   {
     for(var i = 0; i < nImages * 2; i++)
     {
       document.images[i + IMG_OFFSET].src = imgBackside.src;
     }
   }
 }   

/*
 *  Show card
 */
 function showCard(nImage)
 {
   if(document.images)
   {
     if(bRunning && !bShowCard)
     {
       // Uncover a card, if not already two are selected
       if(nSelected1 == -1 || nSelected2 == -1)
       {
         // Is the clicked not uncovered ?
         if(document.images[nImage + IMG_OFFSET].src == imgBackside.src)
         {
           // Uncover selected card
           document.images[nImage + IMG_OFFSET].src = imgArrField[nImage].src;
           if(nSelected1 == -1)
           {
             nSelected1 = nImage;
           }
           else
           {
             nSelected2 = nImage;
           }
         }
       }
       
       // There are two cards uncovered
       if(nSelected1 != -1 && nSelected2 != -1)
       {
         showNumber(++nAttempts, IMG_TRIAL, 5);
                
         // Are the zwo cards equal ?
         if(document.images[nSelected1 + IMG_OFFSET].src == document.images[nSelected2 + IMG_OFFSET].src)
         {
           // If there are equal, incement the counter
           showNumber(++nHit, IMG_HIT, 5);
           nSelected1 = -1;
           nSelected2 = -1;
     
           // Are all pictures uncovered ?
           if(nHit == nImages)
           {
             stopGame();
             strMsg = "Please enter your name for the highscore:";
             strPlayerName = prompt(strMsg, strPlayerName);
             if(strPlayerName != null && strPlayerName != "")
             {
               strDate = getY2kDate();
               nPoints = Math.round(100000 * (nLevel + 1) / nSeconds / nAttempts);
               arrHighScore.push(new objHighScore());
             }
           }
         }
         else
         {
           // The two cards are not identical, start now the timer for hide the cards
           bShowCard = true;
           setTimeout("clearCard()", 2000 - nLevel * 200);
         }
       }
     }
     else
     {
       if(!bRunning)
       {
         alert("Please press the start button !");
       }
     }
   }
 }
 
/*
 *  Turn the two uncovered cards
 */
 function clearCard()
 {
   document.images[nSelected1 + IMG_OFFSET].src = imgBackside.src;
   document.images[nSelected2 + IMG_OFFSET].src = imgBackside.src;
   nSelected1 = -1;
   nSelected2 = -1;
   bShowCard = false;
  }
  
/*
 *  Set the level
 */
 function setLevel(nValue)
 {
   if(document.images && !bRunning)
   {
     nLevel += nValue;
     if(nLevel < 0) nLevel = 0;
     if(nLevel > 9) nLevel = 9;
     showNumber(nLevel, IMG_LEVEL, 1);
   }
 }

  
/*
 *  Update all counter
 */
 function updateAll()
 {
   if(document.images)
   {
     showNumber(nLevel, IMG_LEVEL, 1);
     showNumber(nSeconds, IMG_SEC, 5);
     showNumber(nAttempts, IMG_TRIAL, 5);
     showNumber(nHit, IMG_HIT, 5);

     if(bRunning)
     { 
       document.images[IMG_START].src = imgArrStartStop[1].src;
       document.images[IMG_STOP].src  = imgArrStartStop[2].src;
       document.images[IMG_PLUS].src  = imgArrPlusMinus[1].src;
       document.images[IMG_MINUS].src = imgArrPlusMinus[3].src;
     }
     else
     {  
       document.images[IMG_START].src = imgArrStartStop[0].src;
       document.images[IMG_STOP].src  = imgArrStartStop[3].src;
       document.images[IMG_PLUS].src  = imgArrPlusMinus[0].src;
       document.images[IMG_MINUS].src = imgArrPlusMinus[2].src;
     }
   }
 }
  
/*
 *  Show the highscore window
 */
 function showHighScore()
 {
   sortHighScore();
   saveHighScore();
   window.open("highscore.html", "Highscore", "toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=600,height=300");
 }
 
/*
 *  The highscore object (class)
 */
 function objHighScore()
 {
   this.nPoints   = nPoints;
   this.strName   = strPlayerName;
   this.strDate   = strDate;
   this.nLevel    = nLevel;
   this.nSeconds  = nSeconds;
   this.nAttempts = nAttempts;
 }

/*
 *  Sort the highscore, ascend by points (implementation of bubblesort)
 */
 function sortHighScore()
 {
   var l = arrHighScore.length;
   if(l > 1)
   {
     for(var n = 0; n < l - 1; n++)
     {
       for(var m = 0; m < l - 1; m++)
       {
         if((arrHighScore[m].nPoints - arrHighScore[m + 1].nPoints) > 0)
         {   
           var tmp = arrHighScore[m];
           arrHighScore[m] = arrHighScore[m + 1];
           arrHighScore[m + 1] = tmp;
         }
       }
     }
   }
 }


/*
 *  Read the highscore form cookies
 */
 function loadHighScore()
 {
   if(document.cookie != "")
   {
     bCookies = true;

     // Only the top three
     for(var i = 1; i < 4; i++)
     {
       var strCookieValue = getCookie("MemoryScore" + i);
       if(strCookieValue != "")
       {
         var arrValues = unescape(strCookieValue).split(";");
         nPoints       = arrValues[0];
         strPlayerName = arrValues[1];
         strDate       = arrValues[2];
         nLevel        = arrValues[3];
         nSeconds      = arrValues[4];
         nAttempts     = arrValues[5];
         arrHighScore.push(new objHighScore());
       }
     }
    
     strPlayerName = getCookie("MemoryPlayerName");   
   }
   else
   {
     // There is no cookies, try to create one
     setCookie("MemoryPlayerName", strPlayerName);
     if(document.cookie == "")
     {
       // Can't create the cookie (e.g. disabled by user)
       bCookies = false;
     }
     else
     {
       bCookies = true;
     }
   }
 }

 
/*
 *  Save highsore as cookie
 */
 function saveHighScore()
 {
   if(bCookies)
   {
     setCookie("MemoryPlayerName", strPlayerName);
   
     // The top three
     if(arrHighScore.length != null)
     {
       var n = arrHighScore.length - 1;
       var j = 0;
       for(var i = n; i > n - 3; i--)
       {
         if(i >= 0)
         {
           var strCookieValue = "";
           strCookieValue += arrHighScore[i].nPoints + ";";
           strCookieValue += arrHighScore[i].strName + ";";
           strCookieValue += arrHighScore[i].strDate + ";";
           strCookieValue += arrHighScore[i].nLevel + ";";
           strCookieValue += arrHighScore[i].nSeconds + ";";
           strCookieValue += arrHighScore[i].nAttempts;
           setCookie("MemoryScore" + ++j, strCookieValue);
         }
       }
     }
   }
 }
  
/*
 *  Read cookie
 */
 function getCookie(strId)
 {
   var strReturn = "";

   if(document.cookie != "")
   {
     var arrCookies = document.cookie.split(";");
     for(var i = 0; i < arrCookies.length; i++)
     {
       var arrCookie = arrCookies[i].split("=");
       if(arrCookie.length == 2)
       {
         if(strTrim(arrCookie[0]) == strTrim(strId))
         {
           strReturn = unescape(arrCookie[1]);
         }
       }
     }
   }

   return strReturn;
 }
  
 /*
 *  Save cookie
 */
 function setCookie(strId, strValue)
 {
   document.cookie = strId + "=" + escape(strValue) + ";expires=" + new Date(2036, 12, 31).toGMTString();
 }
  
/*
 *  Remove all white spaces
 */
 function strTrim(str)
 {
   var strReturn = "";
   
   for(var i = 0; i < str.length; i++)
   {
     if(str.charAt(i) != " ")
     {
       strReturn += str.charAt(i);
     }
   }

   return strReturn;
 }
 
/*
 *  Y2K compatibe date
 */
 function getY2kDate()
 {
   var strReturn = "";
   var d = new Date();
   
   var strDate = addLeadingZero(d.getDate(), 2) + "." + addLeadingZero(d.getMonth() + 1, 2) + "." + getY2kYear(d);
   var strTime = addLeadingZero(d.getHours() , 2) + ":" + addLeadingZero(d.getMinutes() , 2) + ":" + addLeadingZero(d.getSeconds() , 2);
   strReturn = strDate + " " + strTime;
   
   return strReturn;
 }
    
/*
 *  Y2K compatible year
 */
 function getY2kYear(d)
 {
   var y = d.getYear();
   if(y < 1970)
   {
     return y + 1900;
   }
   else
   {
     return y;
   }
 }
 
/*
 *  Insert leading white spaces
 */
 function addLeadingZero(value, nTotalLength)
 {
   value += "";
   while(value.length < nTotalLength) value = "0" + value;
   return value;
 }
 

