	// ******************************************************************
  // Titel   : Tetris Main Script and Variables
  // Autor   : Informatik Atelier Bern / Dimitri Jeanneret 
  // Datum   : Februar 09
  // Version : 1.1
  // ****************************************************************** 
         
  // ---------------------------------------------- 
  var GridAnzCol = 10;
  var GridAnzLine = 20; 
  
  // Initialize Game Data
  var ActiveForm = -1; // Active Form
  var NextForm = -1; // Next Form (to display)
  var ActivePosX = 0;
  var ActivePosY = 0;
  var ActiveOrientierung = 0 
  
  var Game_Over = false;
  var Score = 0;
  var Level = 0;
  var Speed = 0;
  var Game_laeuft = false;
  var TimeCounterGame = 0;
  var TimeCounter = 0;
  
  var Wait = false;
  var Wait_FormFix = false;
  
  // Array GridDaten [x] [y]
  var GridDatenBelegung = new Array(GridAnzCol-1); // [x] Belegung (0=Frei / 1=Belegt (Active) / 2=Belegt (Fix) )
  var GridDatenColor = new Array(GridAnzCol-1); // [x] Color 
  for (i=0; i < GridAnzCol; i++)
  {
    GridDatenBelegung [i] = new Array(GridAnzLine-1); // [y] Belegung  
    GridDatenColor [i] = new Array(GridAnzLine-1); // [y] Color
  }
  
  
  
  // ------------------------------------------------
  // Start Game Button
  function Start_Game()
  {
    // Button Start disabled (Not ok with mozzilla, keep the focus on button)
    //document.getElementById('btn_StartGame').disabled = true;
    //document.getElementById('SelectLevel').disabled = true;
    
    if (Game_laeuft) return;
    
    Game_laeuft = true;
    Game_Over = false;
    Score = 0;
    ActiveForm = -1;
    NextForm = -1;
    Level = document.getElementById('SelectLevel').value;// Level from Combobox
    Wait = false;
        
    Grid_Loeschen();
    Grid_Aktualisieren();
    
    Daten_Aktualisieren();
    
    // Elapsed Time
    TimeCounter = 0; TimeCounterGame = 0;
    setTimeout("Start_TimeCounter();",1000);
    
    // Clear Info Windows
    document.getElementById('Info').innerHTML = "";
    document.getElementById('Info').style.display='none'; // none
 
    // Run Game 
    Run_Game();   
  }
  
  // -------------------------------------------------
  // Game Running Cycle -> Form Down and Next Form (Executed all (500 - Speed)ms)
  function Run_Game()
  {
    
    if (!Wait) // No Waiting progress (Before Next Form)
    {
      if (ActiveForm == -1) // New Form
        Form_New();
      else
        Form_Down();
    }
    
    
    // Game In Progress
    if (!Game_Over)
    {
      Speed = (45 * Level)   ; // /(Level+1)
      
      setTimeout("Run_Game()",500 - Speed); // Recursive call of this function
    }
    // Game Over
    else
    { 
      if (Score > 0)
      {
        sql_CheckScorePos();
      }
      else
      {
        Display_GameOver();  
      }
      Game_laeuft = false;
    }     
  }
  // ------------------------------------------------  
  
  // ----------------------------------------------
  // Form nach unten
  function Form_Down()
  {
    if (ActiveForm == -1) return;
    
    // Form nicht unten
    if (Check_BottomPos())
    {
      Form_Grid_Loeschen();
      ActivePosY++;
      Daten_Aktualisieren();
      Grid_Aktualisieren();  
    }
    // Form unten
    else
    {
      
      if (!Wait_FormFix) // Execute only 1 time
        Set_Wait('300'); // Wait 0.3 sec  before Form Fix
      Wait_FormFix = true;
      
      // Wait done
      if (!Wait)
      {
        Wait_FormFix = false;
        Form_Fix(); // ActiveForm = -1 for Next_Form
        Check_Line_Filled();
        Daten_Aktualisieren();
        Grid_Aktualisieren();
        Set_Wait('300'); // Wait before next Form
      }        
    }                     
  }
  // ----------------------------------------------  
      

  // ----------------------------------------------
  // New Form
  function Form_New()
  {
    // Random New Form from 0 bis 6
    // Active Form
    if (NextForm != -1)
      ActiveForm = NextForm;
    else
      ActiveForm = GetRandom(0,6);
      
    NextForm = GetRandom(0,6);// Next Form
    
    ActiveOrientierung = 0;
    
    ActivePosX = (GridAnzCol / 2) - 2; // in the Middle
    ActivePosY = -1 * Return_Form_HighPos(); // Depend of higgest pos of Form
         
    Check_GameOver();
    
    Grid_Aktualisieren();
    
    DisplayNextForm();
   
  }
  // ---------------------------------------------- 

  // ---------------------------------------------- 
  // Set Form fixed wenn Form ganz nach unten ( Belegung=2)
  function Form_Fix()
  {
    if (ActiveForm == -1) return;
    
    // Copy Active Form into Array Grid
    for (i=0; i < 4; i++) // each Subteil
    {
      var AbsoluteX = ActivePosX + (SpielFormCoordX [ActiveForm] [ActiveOrientierung] [i]);
      var AbsoluteY = ActivePosY + (SpielFormCoordY [ActiveForm] [ActiveOrientierung] [i]);
      GridDatenBelegung [AbsoluteX] [AbsoluteY] = 2; // Belegung = belegt (Fix)
    }  
    ActiveForm = -1; // No Active Form
  }
  // ---------------------------------------------- 
  // ----------------------------------------------
  // Set form active (wenn form noch nicht nach unten)
  function Form_Active()
  {
    
    if (ActiveForm == -1) return;
    
    // Copy Active Form into Array Grid
    for (i=0; i < 4; i++) // each Subteil
    {
      var AbsoluteX = ActivePosX + (SpielFormCoordX [ActiveForm] [ActiveOrientierung] [i]);
      var AbsoluteY = ActivePosY + (SpielFormCoordY [ActiveForm] [ActiveOrientierung] [i]);
      
      GridDatenBelegung [AbsoluteX] [AbsoluteY] = 1; // Belegung = belegt (Active)
      GridDatenColor [AbsoluteX] [AbsoluteY] = SpielFormColor [ActiveForm]; // Color
    }
  }
  // ----------------------------------------------  

  // ---------------------------------------------- 
  // Active Form alte Position löschen (vor drehen oder pos nach unten)
  function Form_Grid_Loeschen()
  {
    if (ActiveForm == -1) return;
    // clear Form into Array Grid
    for (i=0; i < 4; i++) // each Subteil
    {
      var AbsoluteX = ActivePosX + (SpielFormCoordX [ActiveForm] [ActiveOrientierung] [i]);
      var AbsoluteY = ActivePosY + (SpielFormCoordY [ActiveForm] [ActiveOrientierung] [i]);
      
      GridDatenBelegung [AbsoluteX] [AbsoluteY] = 0; // Belegung frei
    } 
  
  
  }
  // ----------------------------------------------
  // Main Tetris Grid Clear
  function Grid_Loeschen()
  {
    // Clear Array Grid
    for (y=0; y < GridAnzLine; y++)
    { 
      for (x=0; x < GridAnzCol; x++)
      {
        GridDatenBelegung [x] [y] = 0;
        GridDatenColor [x] [y] = SpielGridBckgColor;
      
      }
    }
  }    
  // ----------------------------------------------
  // Main Tetris Grid Actualisieren 
  function Grid_Aktualisieren()
  {
    Form_Active();
    // Copy Array Grid into HTML Table
    for (y=0; y < GridAnzLine; y++)
    { 
      for (x=0; x < GridAnzCol; x++)
      {
        
        if (!Game_Over)
        {
          if (GridDatenBelegung [x] [y] > 0) // Belegung Fix oder Active
          {
            document.getElementById('a_'+ x + '-' + y).style.backgroundColor = GridDatenColor [x] [y]; // Change Background color
          }
          else
            document.getElementById('a_'+ x + '-' + y).style.backgroundColor = SpielGridBckgColor;
        }    
        else // Game Over
           document.getElementById('a_'+ x + '-' + y).style.backgroundColor = 'orange'; 
      }
    }  
  }
  // ---------------------------------------------- 
  
  // ---------------------------------------------- 
  // Display Next Form (on right panel (Table B))
  function DisplayNextForm()
  {
    // clear Table b
    for (y=0; y < 6; y++)
    { 
      for (x=0; x < 6; x++)
      {
        document.getElementById('b_'+ x + '-' + y).style.backgroundColor = SpielGridBckgColor;
      }
    }    
    // Display each Subteil
    for (i=0; i < 4; i++) 
    {
      if (NextForm != -1)
      { 
        var AbsoluteX = 1 + (SpielFormCoordX [NextForm] [ActiveOrientierung] [i]);
        var AbsoluteY = 1 + (SpielFormCoordY [NextForm] [ActiveOrientierung] [i]);
        
        document.getElementById('b_'+ AbsoluteX + '-' + AbsoluteY).style.backgroundColor 
            = SpielFormColor [NextForm]; // Change Background color
        
      }
    }     
  }
  // ---------------------------------------------- 
      
  // ---------------------------------------------- 
  // Score / Level /Timer actualisieren
  function Daten_Aktualisieren()
  {
    document.getElementById('Score').innerHTML = Score;
    document.getElementById('Level').innerHTML = Level; 
    document.getElementById('Timer').innerHTML = TimeCounterGame;  
  }
  // ---------------------------------------------- 


  // ---------------------------------------------- 
  // Check ob linke pos nicht belegt oder Grid border
  function Check_LeftPos()
  { 
   if (ActiveForm == -1) return false;
   // Check alle Zeile von Oben nach unten
    for (y=0; y < 4; y++) // each Lines
    {
      // Check alle Subteile
      for (i=0; i < 4; i++) // each Subteile
      {
        if (SpielFormCoordY [ActiveForm] [ActiveOrientierung] [i] == y) // Check if Subteil in Line Exists
        {
          var AbsoluteX = ActivePosX + (SpielFormCoordX [ActiveForm] [ActiveOrientierung] [i]);
          var AbsoluteY = ActivePosY + y;
    
          // Check Grid Ende
          if (AbsoluteX == 0) { return false;}
          
          // Check belegt (Fix)
          if (GridDatenBelegung [AbsoluteX-1] [AbsoluteY] == 2) {return false;}
        }
      }
    }
    return true;  
  }
  // ---------------------------------------------- 
  
  // ----------------------------------------------
  // Check ob rechte pos nicht belegt oder Grid border 
  function Check_RightPos()
  { 
   if (ActiveForm == -1) return false;
   // Check alle Zeile von Oben nach unten
    for (y=0; y < 4; y++) // each Lines
    {
      // Check alle Subteile
      for (i=0; i < 4; i++) // each Subteile
      {
        if (SpielFormCoordY [ActiveForm] [ActiveOrientierung] [i] == y) // Check if Subteil in Line Exists
        {
          var AbsoluteX = ActivePosX + (SpielFormCoordX [ActiveForm] [ActiveOrientierung] [i]);
          var AbsoluteY = ActivePosY + y;
    
          // Check Grid Ende
          if (AbsoluteX == GridAnzCol-1) { return false;}
          
          // Check belegt (Fix)
          if (GridDatenBelegung [AbsoluteX+1] [AbsoluteY] == 2) {return false;}
        }
      }
    }
    return true;
  }
  // ---------------------------------------------- 

  // ----------------------------------------------
  // Check ob bottom pos nicht belegt oder Grid border  
  function Check_BottomPos()
  { 
    if (ActiveForm == -1) return false;

   // Check alle Line von links nach recht
    for (x=0; x < 4; x++) // each Col
    {
      // Check alle Subteile
      for (i=0; i < 4; i++) // each Subteile
      {
        if (SpielFormCoordX [ActiveForm] [ActiveOrientierung] [i] == x) // Check if Subteil in Col Exists
        {
          var AbsoluteX = ActivePosX + x;
          var AbsoluteY = ActivePosY + (SpielFormCoordY [ActiveForm] [ActiveOrientierung] [i]);
    
          // Check Grid Ende
          if (AbsoluteY == GridAnzLine-1) { return false;}
          
          // Check belegt (Fix)
          if (GridDatenBelegung [AbsoluteX] [AbsoluteY+1] == 2) {return false;}
        }
      }
    }
    return true;  
  }
  // ---------------------------------------------- 

  // ---------------------------------------------- 
  // Check if Posible to turn Form
  function Check_Turn(direction)
  {   
    if (ActiveForm == -1) return false;
    
    if (direction == 'right') // Turn Right
    {
      var t_ActiveOrientierungNext = ActiveOrientierung + 1;
      if (t_ActiveOrientierungNext < 0 || t_ActiveOrientierungNext >3) t_ActiveOrientierungNext=0;
    }
    if (direction == 'left') // Turn Left
    {
      var t_ActiveOrientierungNext = ActiveOrientierung - 1;
      if (t_ActiveOrientierungNext < 0 || t_ActiveOrientierungNext >3) t_ActiveOrientierungNext=3;    
    }
    
    var t_ActivePosX = ActivePosX;
    var t_ActivePosY = ActivePosY;
    var t_OutOfRangeX = 0;
    var t_OutOfRangeY = 0;
    
    // Check if after turn if Subteil not out of Aera
    for (i=0; i < 4; i++) // each Subteile
    {
      var AbsoluteX = ActivePosX + (SpielFormCoordX [ActiveForm] [t_ActiveOrientierungNext] [i]);
      var AbsoluteY = ActivePosY + (SpielFormCoordY [ActiveForm] [t_ActiveOrientierungNext] [i]);
      
      
      
      // Check Out Of Range Left
      if (AbsoluteX < 0) 
        if (AbsoluteX < t_OutOfRangeX)
          t_OutOfRangeX = AbsoluteX;
       
      // Check Out Of Range Right
      if (AbsoluteX > (GridAnzCol - 1))
        if ((AbsoluteX - (GridAnzCol - 1)) > t_OutOfRangeX)
          t_OutOfRangeX = AbsoluteX - (GridAnzCol - 1);        

      // Check Out Of Range Bottom
      if (AbsoluteY > (GridAnzLine - 1))
        if ((AbsoluteY - (GridAnzLine - 1)) > t_OutOfRangeY)
          t_OutOfRangeY = AbsoluteY - (GridAnzLine - 1);                 
    } 
    
    // Correct Position X (After Rotate)
    t_ActivePosX -= t_OutOfRangeX;
    t_ActivePosY -= t_OutOfRangeY;
    
    
    // Check alle Subteile (in Next Position not occupated)
    for (i=0; i < 4; i++) // each Subteile
    {
      var AbsoluteX = t_ActivePosX + (SpielFormCoordX [ActiveForm] [t_ActiveOrientierungNext] [i]);
      var AbsoluteY = ActivePosY + (SpielFormCoordY [ActiveForm] [t_ActiveOrientierungNext] [i]);
     // Check belegt (Fix)
      if (GridDatenBelegung [AbsoluteX] [AbsoluteY] == 2) {return false;}
    }    
 
    // Copy New X Position before rotate
    ActivePosX = t_ActivePosX;
    ActivePosY = t_ActivePosY;
    return true;
  
  }
  // ---------------------------------------------- 
  
  // ----------------------------------------------
  // Check with new from if Start Position free -> If not ->Game Over 
  function Check_GameOver()
  {
    if (ActiveForm == -1) return false;
    
    // Check all Subteil in new_form (Position not occupated)
    for (i=0; i < 4; i++) // each Subteile
    {
      var AbsoluteX = ActivePosX + (SpielFormCoordX [ActiveForm] [ActiveOrientierung] [i]);
      var AbsoluteY = ActivePosY + (SpielFormCoordY [ActiveForm] [ActiveOrientierung] [i]);
     // Check belegt (Fix)
      if (GridDatenBelegung [AbsoluteX] [AbsoluteY] == 2) 
      { 
        Game_Over = true; 
        // Button Start enable
        document.getElementById('btn_StartGame').disabled = false;
        document.getElementById('SelectLevel').disabled = false;
        return false;
      }  
    }    
    return true;
  }


  // ---------------------------------------------- 
  // ---------------------------------------------- 
  // Check if Full line belegt
  function Check_Line_Filled()
  {  
    var t_AnzLine = 0;
    
    for (y=0; y < GridAnzLine; y++)
    {
      var t_Line_Filled = true;
      
      for (x=0; x < GridAnzCol; x++)
      {
        if (GridDatenBelegung [x] [y] != 2) // Belegung = belegt (Fix))
          t_Line_Filled = false;
      
      }
      
      if (t_Line_Filled) // if filled: shift all line above one step down
      {
        t_AnzLine++;
        for (i=y; i > 0; i--)      
        {
          for (x=0; x < GridAnzCol; x++)
          {
            GridDatenBelegung [x] [i] = GridDatenBelegung [x] [i-1]; // Belegung 
            GridDatenColor [x] [i] = GridDatenColor [x] [i-1]; // Color      
          }      
        
        }      
      }    
    
    }    
    Add_Score(t_AnzLine);
  
  
  }
  // ---------------------------------------------- 
  
  // ---------------------------------------------- 
  // Return Highest position of Form (For New Active Form Positionning )
  function Return_Form_HighPos()
  { 
   if (ActiveForm == -1) return 0;
   // return pos of first Form-Subteil 
    for (y=0; y < 4; y++) // each Lines from top to bottom
    {
      // Check alle Subteile
      for (i=0; i < 4; i++) // each Subteile
      {
        if (SpielFormCoordY [ActiveForm] [ActiveOrientierung] [i] == y) // Check if Subteil in Line Exists
        {
          return SpielFormCoordY [ActiveForm] [ActiveOrientierung] [i];
        }
      }
    }
    return 0;
  }
  // ---------------------------------------------- 
  
  // ---------------------------------------------- 
  // Add Actual Score (depending from AnzLine)
  function Add_Score(AnzLine)
  { 
    
    if (AnzLine==0) return;
    
    var t_AnzPunkte = 0;
    
    
    switch (AnzLine) 
    {
      case 1: 
        t_AnzPunkte = 40;  
        break;
      case 2: 
        t_AnzPunkte = 100;  
        break;    
      case 3: 
        t_AnzPunkte = 300;  
        break; 
      case 4: 
        t_AnzPunkte = 1200;  
        break;     
    }
    Score += t_AnzPunkte * (Level+1); 
    
  

  }
  // ----------------------------------------------   
  // ---------------------------------------------- 
  // Wait Function
  function Set_Wait(Zeit)
  { 
    if (!Game_laeuft) return; // Exit if Game over
    Wait = true; setTimeout("Wait = false;",Zeit); 
  }
  // ---------------------------------------------- 
      
  // ----------------------------------------------
  // Timer Counter for Level change 
  function Start_TimeCounter()
  {  
    if (!Game_laeuft) return; // Exit if Game over
    
    TimeCounter++;
    TimeCounterGame++;
    
    // Increase Level alle 60 sec
    if (TimeCounter >= 60) 
    {
      if (Level < 9)
        Level++;
      TimeCounter = 0;
    }
    setTimeout("Start_TimeCounter();",1000);
    
     
  }
  // ---------------------------------------------- 

  // ---------------------------------------------- 
  // return Random Number from min bis max 
  function GetRandom( min, max ) 
  {
    if( min > max ) {
      return( -1 );
    }
    
    if( min == max ) {
      return( min );
    }
    
    return( min + parseInt( Math.random() * ( max-min+1 ) ) );
  
  }
  
  // ---------------------------------------------- 

