/*************************************************************************/
/***************** W I N M E S S A G E ( ) *******************************/
/*************************************************************************/
function winmessage() {
/**************************/
/* (c)2001 www.diaware.de */
     if( gewonnen != 0 || parseInt(document.display.level.value) < 5 || parseInt(document.display.points.value) < 100000 ) {
        alert("spiel ist vorbei!\nsie haben " + document.display.points.value + " punkte erreicht.\n\n" +
        "hinweis: ab erreichen der stufe 5 und mind. 100000 punkten können\nsie sich " +
        "in die bestenliste eintragen lassen.")
        return;
     }
     gewonnen = 1;
     text1 = "tetris";
     text2 = document.display.points.value;
     text3 = document.display.level.value;
     text4 = 'Zeilen: ' + document.display.lines.value;
     // Nun den Namen erfragen un bei OK das Formular abschicken lassen
     oeffneListenFenster();
}

/**************************************************/
/* Funktionen die per Tastatur aufgerufen werden */
/**************************************************/

function moveLeft() {
/**************************/
/* (c)2001 www.diaware.de */
     newPattern = new Array();
     newPattern = newPattern.concat(globalPattern);
     anzElements = (newPattern.length - 1);
     for( I=1; I < anzElements; I+=2 ) { newPattern[I] -= 1; }
     isNewPatternChanged = 1;
     moveResult = movePattern();
     if( moveResult == 0) globalX --;
}

function moveRight() {
/**************************/
/* (c)2001 www.diaware.de */
     newPattern = new Array();
     newPattern = newPattern.concat(globalPattern);
     anzElements = (newPattern.length - 1);
     for( I=1; I < anzElements; I+=2 ) { newPattern[I] += 1; }
     isNewPatternChanged = 1;
     moveResult = movePattern();
     if( moveResult == 0) globalX ++;
}

function rotate() {
/**************************/
/* (c)2001 www.diaware.de */
     newPattern = new Array();
     newPattern = newPattern.concat(globalPattern);
     anzGlobalElements = ( globalPattern.length - 1);
     for( I=1; I < anzGlobalElements; I+=2 ) {
         /* Rotieren um 90Grad = koordinaten umdrehen und den x Wert negieren */
         newPattern[I] = -globalPattern[I+1];
         newPattern[I+1] = globalPattern[I];
     }
     isNewPatternChanged = 1;
     moveResult = movePattern();
     if( moveResult == 0) {
         /*Wenn gelungen, muss globalPattern das aussehen des gedrehten Steins annehmen */
         globalPattern = new Array();
         globalPattern = globalPattern.concat(newPattern);
     };
}

function moveFast() {
/**************************/
/* (c)2001 www.diaware.de */
     actGlobalSpeed = 50;
}

function moveSlow() {
/**************************/
/* (c)2001 www.diaware.de */
     actGlobalSpeed = getSpeedTime();
}

function pause() {
         if( isPause ) isPause = false;
         else isPause=true;
}

/******************************************************/
/* Funktionen für sonstige Logik */
/******************************************************/

function init() {
/**************************/
/* (c)2001 www.diaware.de */
         if( gamestatus == 1 ) stop();
         /* Spielfeld löschen */
         maxPics = C_ROW * C_COL;
         for( I=0; I < maxPics; I++) document.images[firstfield + I].src=leer.src;
         /* Anzeigefelder löschen */
         setLevel(1);
         document.display.lines.value = 0;
         document.display.points.value = 0;
         isPause = false;
         gewonnen = 0; gamestatus = 1;
         nextPatternIdx = -1;
         start();
}

function Bewege(pixel) {
 return;
 var oldValue = 0;
 var newValue = 0;
 var Koeff = 5 * pixel;
 for( x=0; x/100 <= Math.PI; x+=0.01 ) {
    newValue = Math.round( Koeff * Math.sin(x/100) );
    this.moveBy(0,newValue-oldValue)
    oldValue = newValue;
 }
}

function getSpeedTime() {
     MAXTIME = 800;
     MINTIME = 300;
     RELDELTA = Math.round((MAXTIME-MINTIME)/9);
     return MINTIME + ((9 - parseInt(document.display.level.value)) * RELDELTA);
}

function stop() {
/**************************/
/* (c)2001 www.diaware.de */
         window.clearTimeout(globalTimeout);
         gamestatus=0;
         winmessage();
}

function start() {
/**************************/
/* (c)2001 www.diaware.de */
         nextStone();
}

function nextStone() {
/**************************/
/* (c)2001 www.diaware.de */
         /* Jeder neue Stein bringt 10 Punkte */
         incPoints(10);
         /* Den SpezialStein ausblenden */
         if( document.display.spezial.checked ) {
             allPatterns[0] = grauPattern;
         } else {
             allPatterns[0] = dunkelbPattern;
         }
         /* wenn eine bestimmte Punktzahl überschritten, dann Level erhöhen */
         /* alle 5.000 Punkte das Level erhöhen */
         if((parseInt(document.display.level.value)*9000) <parseInt(document.display.points.value)){
             incLevel();
         }
         clearFullLines()
         /* per Zufall einen Stein aus dem allPatterns Array holen */
         anzPattern = allPatterns.length - 1;
         if( nextPatternIdx == -1 ) {
            patternIdx = Math.round(Math.random() * anzPattern)
         } else {
            patternIdx = nextPatternIdx;
         }
         nextPatternIdx = Math.round(Math.random() * anzPattern)
         drawPreview(allPatterns[nextPatternIdx]);

         /* Untersuche die Dimension des Pattern, um das Einstiegs Y zu finden */
         maxNegY = 0; /* negativstes Y suchen */
         anzElements = (allPatterns[patternIdx].length - 1);
         globalPattern = new Array();
         globalPattern = globalPattern.concat(allPatterns[patternIdx]);
         for( I=0; I < anzElements; I+=2 ) {
              if( globalPattern[I+2] < maxNegY ) maxNegY = globalPattern[I+2];
         }
         globalX = Math.round(C_COL/2); globalY = 0 - maxNegY - 1;
         isNewPatternChanged = 1; isNewStone = 1;
         window.setTimeout("letItFall()",0);
}

function letItFall() {
/**************************/
/* (c)2001 www.diaware.de */
         if( isPause ) {
             globalTimeout = window.setTimeout("letItFall()",actGlobalSpeed);
             return;
         }
         /* Das Pattern für den nächsten Fallschritt (newPattern) muss nur dann neu geneiert */
         /* werden wenn darüber ein vorhergehender nach links, rechts oder dreh gemacht wurde */
         if( isNewPatternChanged != 0 ) {
             newPattern = new Array();
             newPattern = newPattern.concat(globalPattern);
             anzElements = (newPattern.length - 1);
             for( I=0; I < anzElements; I+=2 ) { newPattern[I+2] += 1; }
             isNewPatternChanged = 0;
         }
         moveResult = movePattern();
         globalY++;
         if( moveResult == -2 ) {
             winmessage();
             return;
         }
         if( moveResult == 0) globalTimeout = window.setTimeout("letItFall()",actGlobalSpeed);
         if( moveResult == -1 ) window.setTimeout("nextStone()",0);
}

function movePattern() { /* bewege Pattern von globalPattern nach newPattern */
/**************************/
/* (c)2001 www.diaware.de */
         /* lässt sich der Stein nicht weiter bewegen, gebe -1 zurück */
         /* wird der Stein zum ersten mal gezeichnet (isNewStone) schaue ob er etwas übermalt
            falls ja, dann gebe -2 zurück, um Spielende anzuzeigen */
         /* wurde der Stein weiter bewegt, gebe 0 zurück */

         if( isNewStone != 0 ) {
             anzNewElements = (newPattern.length - 1);
             isGameOver = 0;
             for( I=1; I < anzNewElements; I+=2 ) {
               if( gget( globalX+newPattern[I], globalY+newPattern[I+1] ) != 0 ) isGameOver=1;
               gset( globalX + newPattern[I], globalY + newPattern[I+1],newPattern[0] )
             }
             if( isGameOver != 0) return -2;
             isNewStone = 0;
             return 0;
         }
         /* fülle zunächst Array mit den neu zu zeichnenden Daten und prüfe ob eventuell */
         /* der zug gar nicht möglich ist, dann -1 zurückgeben */
         drawElements = new Array();
         anzGlobalElements = (globalPattern.length - 1);
         anzNewElements = (newPattern.length - 1);
         for( I=1; I < anzNewElements; I+=2 ) {
            isNewOld = 0; /* ist neues Element auch gleichzeitig ein altes? */
            for( II=1; II < anzGlobalElements; II+=2 ) {
                if( newPattern[I] == globalPattern[II] && newPattern[I+1] == globalPattern[II+1] ){
                    isNewOld = 1; break;
                }
            }
            if( isNewOld == 0 ) {
                /* das heißt es muss neu gezeichnet werden */
                drawElements = drawElements.concat( new Array(newPattern[I],newPattern[I+1]) );
                /* testen ob dort evetuell schon ein Stein vorhanden oder Rand berührt wird */
                if( gget( globalX + newPattern[I], globalY + newPattern[I+1] ) != 0 ) return -1;
            }
         }
         deleteElements = new Array();
         for( I=1; I < anzGlobalElements; I+=2 ) {
            isOldNew = 0; /* wird ein altes Element frei? */
            for( II=1; II < anzNewElements; II+=2 ) {
                if( globalPattern[I] == newPattern[II] && globalPattern[I+1] == newPattern[II+1] ){
                    isOldNew = 1; break;
                }
            }
            if( isOldNew == 0 ) {
               /* das heißt es muss gelöscht werden */
               deleteElements=deleteElements.concat( new Array(globalPattern[I],globalPattern[I+1]));
            }
         }

         /* Nun zur Tat schreiten und neu zeichnen */
         anzDrawElements = (drawElements.length - 1);
         anzDeleteElements = (deleteElements.length - 1);
         for( I=0; I < anzDrawElements; I+=2 ) {
              gset( globalX + drawElements[I], globalY + drawElements[I+1], globalPattern[0])
         }
         for( I=0; I < anzDeleteElements; I+=2 ) {
              gset( globalX + deleteElements[I], globalY + deleteElements[I+1], leer)
         }
         return 0;
}

function clearFullLines() {
/**************************/
/* (c)2001 www.diaware.de */
         /* Beginnend mit unterer Linie */
         deletedLines = 0;
         emptyLines = 0;
         greyElements = 0;
         for( actRow = C_ROW-1; actRow >= 0; actRow-- ) {

              /* teste die aktuelle Spalte */
              isFull = true;
              isEmpty = true;
              greyElementsPerLine = 0;
              for( actCol = 0; actCol < C_COL; actCol++ ) {
                   Element = gget(actCol,actRow);
                   if( Element != 0 ) isEmpty = false;
                   if( Element == 0 ) isFull = false;
                   if( Element == 2 ) greyElementsPerLine++;
              }
              if( isEmpty ) {
                /* wenn es eine Leerzeile ist, dann kann man auch abbrechen! */
                break;
              }
              if( isFull ) {
                  deletedLines++;
                  greyElements += greyElementsPerLine;
                  continue;
              }
              for( actCol = 0; actCol < C_COL; actCol++ ) {
                   gcopy(actCol,actRow,actCol,actRow+deletedLines);
              }
         }
        /* noch für die anzahl der gelöschten linien leerzeilen einfügen */
         for( deletedRow = 0; deletedRow < deletedLines; deletedRow++ ) {
            for( actCol = 0; actCol < C_COL; actCol++ ) {
                gset(actCol,actRow+deletedRow+1,leer);
            }
         }
         /* Für die Anzahl der gelöschten Linien Punkte verteilen */
         if( deletedLines == 1) incPoints(99);
         if( deletedLines == 2) incPoints(248);
         if( deletedLines == 3) incPoints(747);
         if( deletedLines >= 4) incPoints(1996);
         if( deletedLines > 0 ) {
              incPoints(greyElements*500);
              window.setTimeout("Bewege(deletedLines)",0);
         }
         /* nun noch Linien erhöhen */
         incLines(deletedLines);
}

/******************************************************/
/* Funktionen für Anzeigeelemente */
/******************************************************/
function setLevel(level) {
/**************************/
/* (c)2001 www.diaware.de */
         /* es gibt insgesamt 9 Level */
         if( level > 9 ) level = 9;
         if( level < 1 ) level = 1;
         document.display.level.value = level;
         document.display.level2.value = level;
         actGlobalSpeed = getSpeedTime();
}
function incLevel() {
/**************************/
/* (c)2001 www.diaware.de */
         /* es gibt insgesamt 9 Level */
         setLevel( parseInt(document.display.level.value) + 1 );
}
function incPoints(point) {
/**************************/
/* (c)2001 www.diaware.de */
         document.display.points.value = parseInt(document.display.points.value) + point;
         document.display.points2.value = parseInt(document.display.points.value);
}
function incLines(line) {
/**************************/
/* (c)2001 www.diaware.de */
         document.display.lines.value = parseInt(document.display.lines.value) + line;
         document.display.lines2.value = parseInt(document.display.lines.value);
}

/******************************************************/
/* Funktionen für Graphik */
/******************************************************/
function drawPreview(pattern) {
/**************************/
/* (c)2001 www.diaware.de */
   /* Vorschau löschen */
   maxPics = C_P_ROW * C_P_COL;
   for( I=0; I < maxPics; I++) document.images[firstpreviewfield + I].src=preview.src;
   maxNegY = 0; /* negativstes Y suchen */
   anzElements = (pattern.length - 1);
   for( I=0; I < anzElements; I+=2 ) {
        if( pattern[I+2] < maxNegY ) maxNegY = pattern[I+2];
   }
   for( I=1; I < anzElements; I+=2 ) {
       gsetpreview(1+pattern[I],1 - maxNegY - 1+ pattern[I+1],pattern[0])
   }
}

function gsetpreview(x,y,img) {
/**************************/
/* (c)2001 www.diaware.de */
     my_offset = parseInt(x) + parseInt(y) * parseInt(C_P_COL);
     document.images[firstpreviewfield + my_offset].src=img.src;
}


function gset(x,y,img) {
/**************************/
/* (c)2001 www.diaware.de */
     /* setzt ein bild an die stelle (x,y) (0,0) ist oben links (xmax,ymax) ist unten rechts */
    if( x < 0 || x > (C_COL-1) || y < 0 || y > (C_ROW-1) ) return;
     my_offset = parseInt(x) + parseInt(y) * parseInt(C_COL);
     document.images[firstfield + my_offset].src=img.src;
}

function gcopy(x1,y1,x2,y2) {
/**************************/
/* (c)2001 www.diaware.de */
    /* schaue ob stelle (x,y) frei ist, falls außerhalb des Spielfeldes, wird dies */
    /* ebenfalls als besetzt angezeigt */
    /* 0 = frei; > 0 = besetzt; -1 = außerhalb; */
    if( x1 < 0 || x1 > (C_COL-1) || y1 < 0  || y1 > (C_ROW-1) ) return;
    if( x2 < 0 || x2 > (C_COL-1) || y2 < 0  || y2 > (C_ROW-1) ) return;
    my_offset1 = parseInt(x1) + parseInt(y1) * parseInt(C_COL);
    my_offset2 = parseInt(x2) + parseInt(y2) * parseInt(C_COL);
    document.images[firstfield + my_offset2].src = document.images[firstfield + my_offset1].src
}

function gget(x,y) {
/**************************/
/* (c)2001 www.diaware.de */
    /* schaue ob stelle (x,y) frei ist, falls außerhalb des Spielfeldes, wird dies */
    /* ebenfalls als besetzt angezeigt */
    /* 0 = frei; > 0 = besetzt; -1 = außerhalb; */
    if( x < 0 || x > (C_COL-1) || y > (C_ROW-1) ) return -1;
    if( y < 0 ) return 0; //da sonst bei neuen Stein an der Oberkante Fehler erscheinen
    my_offset = parseInt(x) + parseInt(y) * parseInt(C_COL);
    if( document.images[firstfield + my_offset].src.indexOf(greyimg) != -1 ) return 2;
    if( document.images[firstfield + my_offset].src.indexOf(emptyimg) != -1 ) return 0;
    else return 1;
}
