/*------------------------------------------------------------------------------*\
 * Memory Spiel                                                                 *
 * Programmiert von Markus Eichenberger  http://mypage.bluewin.ch/katzenseite   *
 * Es handelt es sich um eine sehr einfache Implementierung in JavaScript 1.2   *
 *                                                                              *
 * Version 1.0.0 25.06.2002 Erste Version                                       *
 * Version 1.0.1 02.08.2002 Jahr 2000 sicheres Datum                            *
 * Version 1.0.2 26.05.2003 Automatisches ermitteln von IMG_OFFSET              *
 * Version 1.0.3 27.07.2003 Aufdecken von zwei Bildern die eine Gemeinsamkeit   *
 *                          haben wie z.B. Schuhe + Al Bundy                    *
\*------------------------------------------------------------------------------*/

 var IMG_OFFSET = 1;           // Nummer des ersten Bildes in document.images[*]
                               // wird durch searchFirstImage() gesetzt
 var IMG_PATH   = "";          // Pfad der Bilder
 var IMG_MODE   = 0;           // IMG_MODE=0 zwei identische Bilder aufdecken
                               //            Dateinamen bildX.jpg
                               // IMG_MODE=1 zwei logisch zusammenpassende Bilder
                               //            Dateinamen bildXa.jpg und BildXb.jpg

 // Imagepositionen vorbelegen
 var IMG_START = 18;
 var IMG_STOP  = 20;
 var IMG_PLUS  = 28;
 var IMG_MINUS = 24;

 var IMG_LEVEL = 26;
 var IMG_SEC   = 33;
 var IMG_HIT   = 49;
 var IMG_ATTEMPTS = 41;

 var nImages = 8;                               // Anzahl der Bilder
 var arrHighScore    = new Array();             // HighScore Objekt Array
 var imgArrField     = new Array(nImages * 2);  // Bilder im Spielfeld
 var imgKarte        = new Image();             // Rueckseite der Karte
 var imgArrStartStop = new Array(4);            // Start und Stop Button
 var imgArrPlusMinus = new Array(4);            // Plus und Minus Button
 var imgArrNumber    = new Array(11);           // Zahlen 0 bis 9
 var bRunning        = false;                   // Zustand des Spiels
 var nLevel          =  4;                      // Spiellevel
 var nSeconds        =  0;                      // Anzahl Sekunden der Spieldauer
 var nAttempts       =  0;                      // Anzahl Versuche
 var nHit            =  0;                      // Anzahl Treffer
 var nSelected1      = -1;                      // Erstes selektiertes Bild
 var nSelected2      = -1;                      // Zweites selektiertes Bild
 var bShowCard       = false;                   // Zustand Karte Anzeigen
 var strPlayerName   = "xxx";                   // Name der Spielers
 var strDate         = "";                      // Datum des Spiels
 var nPoints         = 0;                       // Anzahl Punkte des Spiels
 var bCookies        = false;                   // Cookies
 var nSumImages      = nImages * 2 + 4 + 4 + 11;// Summe alle zu ladenden Bilder

/*
 *  Bilder laden
 */
 function loadImages()
 {
   if(document.images)
   {
     imgKarte.src  = IMG_PATH + "karte.jpg";

     // Start und Stop Button
     for(var i = 0; i < 4; i++)
     {
       imgArrStartStop[i] = new Image();
       imgArrStartStop[i].src = IMG_PATH + "startstop" + (i + 1) + ".gif";
     }

     // Plus und Minus Button
     for(var i = 0; i < 4; i++)
     {
       imgArrPlusMinus[i] = new Image();
       imgArrPlusMinus[i].src = IMG_PATH + "plusminus" + (i + 1) + ".gif";
     }

     // Zahlen und Buchstaben laden
     for(var i = 0; i < 11; i++)
     {
       imgArrNumber[i] = new Image();
       imgArrNumber[i].src = IMG_PATH + i + ".gif";
     }

     // Bilder laden
     for(var i = 0; i < nImages; i++)
     {
       if(IMG_MODE == 1)
       {
         imgArrField[i * 2] = new Image();
         imgArrField[i * 2].src = IMG_PATH + "bild" + (i + 1) + "a.jpg";
         imgArrField[i * 2 + 1] = new Image();
         imgArrField[i * 2 + 1].src = IMG_PATH + "bild" + (i + 1) + "b.jpg";
       }
       else
       {
         IMG_MODE = 0;
         imgArrField[i * 2] = new Image();
         imgArrField[i * 2].src = IMG_PATH + "bild" + (i + 1) + ".jpg";
         imgArrField[i * 2 + 1] = new Image();
         imgArrField[i * 2 + 1].src = IMG_PATH + "bild" + (i + 1) + ".jpg";
       }
     }

     loadHighScore();
     nLevel = 4;
     nSeconds  =  0;
     nAttempts =  0;
     nHit      =  0;
     searchFirstImage();
     clearField();
     updateAll();
     setTimeout("checkLoading()", 1000)
   }
 }

/*
 *  Bilder mischen
 */
 function shuffle()
 {
   if(document.images)
   {
     // Jeweils zwei Bilder vertauschen
     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;
     }
   }
 }

/*
 *  Neues Spiel starten
 */
 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();
     }
   }
 }

/*
 *  Spiel stoppen
 */
 function stopGame()
 {
   if(document.images)
   {
     if(bRunning)
     {
       clearInterval(id);
       bRunning = false;
       updateAll();
     }
   }
   return;
 }

/*
 *  Sekunden zählen
 */
 function countSeconds()
 {
   nSeconds++;
   showNumber(nSeconds, IMG_SEC + IMG_OFFSET, 5);
 }

/*
 *  Zahl anzeigen
 */
 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;
       }
     }
   }
 }

/*
 *  Spielfeld loeschen
 */
 function clearField()
 {
   if(document.images)
   {
     for(var i = 0; i < nImages * 2; i++)
     {
       document.images[i + IMG_OFFSET].src = imgKarte.src;
     }
   }
 }

/*
 *  Zeigen der Karte
 */
 function showCard(nImage)
 {
   if(document.images)
   {
     if(bRunning && !bShowCard)
     {
       // Aufdecken von zwei Karten
       if(nSelected1 == -1 || nSelected2 == -1)
       {
         // Nur zugedeckte Karten aufdecken
         if(document.images[nImage + IMG_OFFSET].src == imgKarte.src)
         {
           // Bild aufdecken
           document.images[nImage + IMG_OFFSET].src = imgArrField[nImage].src;
           if(nSelected1 == -1)
           {
             nSelected1 = nImage;
           }
           else
           {
             nSelected2 = nImage;
           }
         }
       }

       // Zwei Karten sind aufgedeckt
       if(nSelected1 != -1 && nSelected2 != -1)
       {
         showNumber(++nAttempts, IMG_ATTEMPTS + IMG_OFFSET, 5);

         // Karten miteinander vergleichen
         var pic1 = document.images[nSelected1 + IMG_OFFSET].src;
         var len1 = pic1.length;
         var pic2 = document.images[nSelected2 + IMG_OFFSET].src;
         var len2 = pic2.length;
         if(pic1.substr(0, len1 - IMG_MODE - 4) == pic2.substr(0, len2 - IMG_MODE - 4))
         {
           // Karten identisch, Counter erhoehen
           showNumber(++nHit, IMG_HIT + IMG_OFFSET, 5);
           nSelected1 = -1;
           nSelected2 = -1;

           // Alle Bilder aufgedeckt
           if(nHit == nImages)
           {
             stopGame();
             strMsg = "Geben Sie Ihren Namen fuer die Highscore Liste ein:";
             strPlayerName = prompt(strMsg, strPlayerName);
             if(strPlayerName != null && strPlayerName != "")
             {
               strDate = getY2kDate();
               nPoints = Math.round(100000 * (nLevel + 1) / nSeconds / nAttempts);
               arrHighScore.push(new objHighScore());
             }
           }
         }
         else
         {
           // Karten nicht identisch, nach n Sekunden wieder ausblenden, abhaengig vom Spiellevel
           bShowCard = true;
           setTimeout("clearCard()", 2000 - nLevel * 200);
         }
       }
     }
     else
     {
       if(!bRunning)
       {
         alert("Bitte zuerst Spiel starten !");
       }
     }
   }
 }

/*
 *  Zwei Karten wieder verdecken
 */
 function clearCard()
 {
   document.images[nSelected1 + IMG_OFFSET].src = imgKarte.src;
   document.images[nSelected2 + IMG_OFFSET].src = imgKarte.src;
   nSelected1 = -1;
   nSelected2 = -1;
   bShowCard = false;
  }

/*
 *  Spiellevel setzen
 */
 function setLevel(nValue)
 {
   if(document.images && !bRunning)
   {
     nLevel += nValue;
     if(nLevel < 0) nLevel = 0;
     if(nLevel > 9) nLevel = 9;
     showNumber(nLevel, IMG_LEVEL + IMG_OFFSET, 1);
   }
 }


/*
 *  Alle Zaehler neu anzeigen
 */
 function updateAll()
 {
   if(document.images)
   {
     showNumber(nLevel, IMG_LEVEL + IMG_OFFSET, 1);
     showNumber(nSeconds, IMG_SEC + IMG_OFFSET, 5);
     showNumber(nAttempts, IMG_ATTEMPTS + IMG_OFFSET, 5);
     showNumber(nHit, IMG_HIT + IMG_OFFSET, 5);

     if(bRunning)
     {
       document.images[IMG_START + IMG_OFFSET].src = imgArrStartStop[1].src;
       document.images[IMG_STOP + IMG_OFFSET].src  = imgArrStartStop[2].src;
       document.images[IMG_PLUS + IMG_OFFSET].src  = imgArrPlusMinus[1].src;
       document.images[IMG_MINUS + IMG_OFFSET].src = imgArrPlusMinus[3].src;
     }
     else
     {
       document.images[IMG_START + IMG_OFFSET].src = imgArrStartStop[0].src;
       document.images[IMG_STOP + IMG_OFFSET].src  = imgArrStartStop[3].src;
       document.images[IMG_PLUS + IMG_OFFSET].src  = imgArrPlusMinus[0].src;
       document.images[IMG_MINUS + IMG_OFFSET].src = imgArrPlusMinus[2].src;
     }
   }
 }

/*
 *  HighScore anzeigen
 */
 function showHighScore()
 {
   sortHighScore();
   saveHighScore();
   window.open("highscore.htm", "Highscore", "toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=600,height=150");
 }

/*
 *  HighScore Objekt
 */
 function objHighScore()
 {
   this.nPoints   = nPoints;
   this.strName   = strPlayerName;
   this.strDate   = strDate;
   this.nLevel    = nLevel;
   this.nSeconds  = nSeconds;
   this.nAttempts = nAttempts;
 }

/*
 *  HighScore sortieren nach Punktezahl (BubbleSort, sortieren durch Vertauschen)
 */
 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;
         }
       }
     }
   }
 }


/*
 *  HighScore lesen
 */
 function loadHighScore()
 {
   if(document.cookie != "")
   {
     bCookies = true;

     // Die besten drei Spieler
     for(var i = 1; i < 4; i++)
     {
       var strCookieValue = getMemoryCookie("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 = getMemoryCookie("MemoryPlayerName");
   }
   else
   {
     // Es sind noch keine Cookies gespeichert, versuchen eines zu speichern
     setMemoryCookie("MemoryPlayerName", strPlayerName);
     if(document.cookie == "")
     {
       // Definitiv keine Cookies moeglich
       bCookies = false;
     }
     else
     {
       bCookies = true;
     }
   }
 }


/*
 *  HighScore speichern
 */
 function saveHighScore()
 {
   if(bCookies)
   {
     setMemoryCookie("MemoryPlayerName", strPlayerName);

     // Der beste drei Spieler
     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;
           setMemoryCookie("MemoryScore" + ++j, strCookieValue);
         }
       }
     }
   }
 }

/*
 *  Cookie lesen
 */
 function getMemoryCookie(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;
 }

 /*
 *  Cookie setzen
 */
 function setMemoryCookie(strId, strValue)
 {
   document.cookie = strId + "=" + escape(strValue) + ";expires=" + new Date(2036, 12, 31).toGMTString();
 }

/*
 *  Leerzeichen aus String entfernen
 */
 function strTrim(str)
 {
   var strReturn = "";

   for(var i = 0; i < str.length; i++)
   {
     if(str.charAt(i) != " ")
     {
       strReturn += str.charAt(i);
     }
   }

   return strReturn;
 }

/*
 *  Y2k sicheres Datum liefern
 */
 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 sichere Jahreszahl
 */
 function getY2kYear(d)
 {
   var y = d.getYear();
   if(y < 1970)
   {
     return y + 1900;
   }
   else
   {
     return y;
   }
 }

/*
 *  Fuehrende Nullen einfuegen
 */
 function addLeadingZero(value, nTotalLength)
 {
   value += "";
   while(value.length < nTotalLength) value = "0" + value;
   return value;
 }


/*
 *  Index der ersten Grafik suchen (IMG_OFFSET)
 */
 function searchFirstImage()
 {
   for(var i = 0; i < document.images.length; i++)
   {
     if(document.images[i].name == "memory_id")
     {
       IMG_OFFSET = i + 1;
       break;
     }
   }
 }


/*
 *  Sind alle Bilder geladen ?
 */
 function countLoadedImages()
 {
   var nCompleted = 0;
   for(var i = 0; i < 2 * nImages; i++)
   {
     if(imgArrField[i].complete)
     {
       nCompleted++;
     } //else alert(imgArrField[i].src);
   }

   for(var i = 0; i < 4; i++)
   {
     if(imgArrStartStop[i].complete)
     {
       nCompleted++;
     } //else alert(imgArrStartStop[i].src);
   }

   for(var i = 0; i < 4; i++)
   {
     if(imgArrPlusMinus[i].complete)
     {
       nCompleted++;
     } //else alert(imgArrPlusMinus[i].src);
   }

   for(var i = 0; i < 11; i++)
   {
     if(imgArrNumber[i].complete)
     {
       nCompleted++;
     } //else alert(imgArrNumber[i].src);
   }
   return nCompleted;
 }


/*
 *  Ladestand der Bilder anzeigen
 */
function checkLoading()
{
  var nLoaded = countLoadedImages();
  if(nLoaded < nSumImages)
  {
    document.images[IMG_OFFSET - 1].width = 456 - (456 / nSumImages * nLoaded);
    window.status = "" + nLoaded + " von " + nSumImages + " Bilder geladen";
    setTimeout("checkLoading()", 250);
  }
  else
  {
    document.images[IMG_OFFSET - 1].src = IMG_PATH + "blank.gif";
    document.images[IMG_OFFSET - 1].width = 5;
    window.status = "";
    updateAll();
  }
}
