  
    var hiscore = Get_Cookie('hiscore') == null ? 0 : Number(Get_Cookie('hiscore'));
    var moving = false; 
    var currentColor = "silver";
    var currentImg = "/images/blank.gif";
    var selectedEl = null;
    var selectedCell = new Array(2);
    
    var colorArray = ['red', 'blue', 'lime', 'yellow', 'maroon', 'aqua', 'fuchsia'];
    var imagesArray = ['/images/red.gif', '/images/blue.gif', '/images/lime.gif', '/images/yellow.gif', '/images/maroon.gif', '/images/aqua.gif', '/images/fuchsia.gif'];
    var Height = 9;
    var Width = 9;
    
    var shortestPath = new Array();
    
    var nextBalls = new Array(3);
    var nextBallsImg = new Array(3);
    var maxPathLength = (Width + Height) * 2;
    
    var cellHTable = {};

    var removing = new Array();
    
    var matrix = new Array(Height);
    
    var gameEnded = false;
    /* init matrix and cellHTable */
    for (var x=0; x<matrix.length; x++)
    {
      matrix[x] = new Array(Width);
      for (var y=0; y<matrix[x].length; y++)
      {
        matrix[x][y] = 0;
        var tdId = MakeID(x,y);
        cellHTable[tdId] = 0; 
      }
    }
    
    function setMatrixAndCheckCells()
    {
      
      var emptyCells = 0;
      for (var x=0; x<Height; x++)
      {
        for (var y=0; y<Width; y++)
        {
          var tdId = MakeID(x,y);
          
          matrix[x][y]=cellHTable[tdId];
          
          if (matrix[x][y] != -1)
            ++emptyCells;
        }
      }
      
      return emptyCells;
    }

    
    function matrixValue(mtx)
    {
      var r="";
      
      for (var x=0; x<Height; x++)
      {
        for (var y=0; y<Width; y++)
         r += mtx[x][y];
        r+="\n";
      
      }
      return r;
    }
    

    function SetPosValue(x, y, val)
    {
      matrix[x][y] = val;
    }

    function SetStartPos(x, y)
    {
      SetPosValue(x, y, -2);
    }

    function SetEndPos(x, y)
    {
      SetPosValue(x, y, 1);
    }

    function FindPath(startcell, endcell)
    {
      SetStartPos(startcell.x, startcell.y);
      SetEndPos(endcell.x, endcell.y);


      
      var found = false;
      var current = 1;

      while ((current < (maxPathLength + 1)) && (!found))
      {
        for (var i = 0; i < Height; i++)
        {
          for (var j = 0; j < Width; j++)
          {
            if (matrix[i][j] == current)
            {
              if (CheckNeighbour(i - 1, j, current + 1))
              {
                found = true;
              }
              if (CheckNeighbour(i + 1, j, current + 1))
              {
                found = true;
              }
              if (CheckNeighbour(i, j - 1, current + 1))
              {
                found = true;
              }
              if (CheckNeighbour(i, j + 1, current + 1))
              {
                found = true;
              }
            }
          }
        }
        current++;
      }
      

      if (found)
      {
        shortestPath = new Array(current - 1);
        var pos = startcell;
        var pstr = "";
        var index = 0;
        while ((pos.x != endcell.x) || (pos.y != endcell.y))
        {

          animateCell(pos.x,pos.y,1);
          pause(100);
          animateCell(pos.x,pos.y,0);
                    
          shortestPath[index] = new Array(2);
          pos = GetMinNearest(pos);
          shortestPath[index].x = pos.x;
          shortestPath[index].y = pos.y;

          ++index;
        }
        return true;
      } 
      else 
      {
        shortestPath = null;
        return false;
      }
    }
    
    function pause(numberMillis) 
    {
      var dialogScript = 
        'window.setTimeout(' + ' function () { window.close(); }, ' + numberMillis + ');';
      if (window.showModalDialog)
      {
        var result = 
          window.showModalDialog('javascript:document.writeln(' + '"<script>' + dialogScript + '<' + '/script>")');
      }
    }
    
    function animateCell(x,y,col)
    {
      document.getElementById(MakeID(x,y)).style.color = (col == 0) ? 'silver' : currentColor;
      document.getElementById(MakeID(x,y)).childNodes[0].src = (col == 0) ? '/images/blank.gif' : currentImg;
    }

    function CheckNeighbour(x, y, val)
    {
      if (IsInBounds(x, y))
      {
        if (matrix[x][y] == -2)
        {
          return true;
        }
        if (matrix[x][y] == 0)
        {
          matrix[x][y] = val;
        }
      }
      return false;
    }

    function IsInBounds(x, y)
    {
      if ((x < 0) || (y < 0) || (y >= Width) || (x >= Height))
      {
        return false;
      }
      return true;
    }

    function GetMinNearest(pos)
    {
      var min = matrix[pos.x][pos.y];
      var result = pos;
      var x, y;

      x = pos.x - 1;
      y = pos.y;
      
      if (IsInBounds(x, y) && (matrix[x][y] > 0))
      {
        if ((min < 0) || (matrix[x][y] < min))
        {
          min = matrix[x][y];
          result = new Array(2);
          result['x'] = x;
          result['y'] = y;
        }
      }
      x = pos.x + 1;
      y = pos.y;
      if (IsInBounds(x, y) && (matrix[x][y] > 0))
      {
        if ((min < 0) || (matrix[x][y] < min))
        {
          min = matrix[x][y];
          result = new Array(2);
          result['x'] = x;
          result['y'] = y;
        }
      }
      x = pos.x;
      y = pos.y - 1;
      if (IsInBounds(x, y) && (matrix[x][y] > 0))
      {
        if ((min < 0) || (matrix[x][y] < min))
        {
          min = matrix[x][y];
          result = new Array(2);
          result['x'] = x;
          result['y'] = y;
        }
      }
      x = pos.x;
      y = pos.y + 1;
      if (IsInBounds(x, y) && (matrix[x][y] > 0))
      {
        if ((min < 0) || (matrix[x][y] < min))
        {
          min = matrix[x][y];
          result = new Array(2);
          result['x'] = x;
          result['y'] = y;
        }
      }
      return result;
    }      
    
    function Move(el) 
    { 
      
      var currentCell = getXY(el.id);
      
      
      if (!moving && cellHTable[el.id] == -1) 
      { 
        selectedEl = el;
        selectedCell = getXY(selectedEl.id);
        currentColor = el.style.color;
        currentImg = el.childNodes[0].src;
        el.style.border = "1px inset white"; 
        el.style.backgroundColor ="gray";
        moving = true; 
      } 
      
      else if(moving)
      {
        if (cellHTable[el.id] == -1)
        {
          selectedEl.style.backgroundColor = "silver";
          selectedEl.style.border = "1px outset silver";
          selectedEl = el;
          selectedCell = getXY(selectedEl.id);
          currentColor = el.style.color;
          currentImg = el.childNodes[0].src;
          el.style.border = "1px inset white"; 
          el.style.backgroundColor ="gray";
        }
        else
        {
          if (!FindPath(selectedCell, currentCell))
            return;
          else
          { 
            
            selectedEl.style.border = "1px outset silver";
            selectedEl.style.color = "silver";
            selectedEl.childNodes[0].src = "/images/blank.gif";
            selectedEl.style.backgroundColor = "silver";
            cellHTable[selectedEl.id] = 0;
            
          }
          
          el.style.color = currentColor;
          el.childNodes[0].src = currentImg;
          cellHTable[el.id] = -1;
          
          moving = false;
          
          var emptycells;
          
          if (CheckTable(false))
          {
            emptycells = setMatrixAndCheckCells();
            Deal(emptycells);
          }
          CheckTable(true);
          
          if (emptycells<=3)
          {
            gameEnded = true;
            alert("Gioco finito col punteggio di " + document.forms['scores'].scval.value);
            var finalscore = Number(document.forms['scores'].scval.value);
            if (finalscore > hiscore)
              Set_Cookie('hiscore', finalscore, 1000);
            document.forms['scores'].submit();
          }
          else
            setMatrixAndCheckCells(); 
        }
      }
    } 
    
    
    function MakeID(row,column){
    return  "cell" + row + "_" + column;  
    }
    
    function getXY(id)
    {
      var rc = new Array(2);
      rc['x'] = Number(id.charAt(4));
      rc['y'] = Number(id.charAt(6));
      return rc;
    } 
    
    function CheckTable(afterdeal)
    {
     for (var i=0;i<Height;i++)
       for (var j=0;j<Width;j++)
       {
            CheckDirections(i,j);
      }
      
      
      var svalue = Number(document.forms['scores'].scval.value);
      
      /* Punteggio:
       2 punti per palla per 5 palle
       6° palla -> 4 punti (2^2)
       7° palla -> 8 punti (2^3)
       8° palla -> 16 punti (2^4)
       9° palla -> 32 punti (2^5  ) 
      */
      for (var r=0; r<removing.length; r++)
      {
         var scorefactor = (r<5) ? 2 : (Math.pow(2,(r-3)));  
         document.getElementById(removing[r]).style.color="silver";
         document.getElementById(removing[r]).childNodes[0].src = "/images/blank.gif";
         cellHTable[removing[r]] = 0;
         var rcell = getXY(removing[r]);
         svalue += scorefactor;
      }
      
      if (!afterdeal) 
        document.forms['scores'].scval.value = svalue;
      
      
      if (removing.length>0)
      {
        removing = new Array();
        return false;
      }
      else
        return true;    
    }
    
    function CheckDirections(i,j)
    {
  
     if (i<=4)
     {
      CheckDirection(i,j,2);
      if (j>=4)
      {
        CheckDirection(i,j,3);
      }
     }
     if (j<=4)
     {
      CheckDirection(i,j,0);
      if (i<=4)
      {
        CheckDirection(i,j,1);
      }
     }

    } 
    
    function iof(array, val)
    {
      for (var i=0; i<array.length; i++)
      {
        if (array[i]==val)
          return i;
      }
      return -1;
    
    }
    
    function CheckDirection(i,j,dir)
    {
     
     var id=MakeID(i,j);
     if (cellHTable[id]!=-1)
       return;
     var ijcol=document.getElementById(id).style.color;
     var ccol;
     var rcandidate=new Array();
     rcandidate.push(id);
     var r="";
     do
     {
      switch (dir)
      {
        case 0:
          id=MakeID(i,++j);
          break;
        case 1:
          id=MakeID(++i,++j);
          break;
        case 2:
          id=MakeID(++i,j);
          break;
        case 3:
          id=MakeID(++i,--j);
          break;                
      }
      
      if (!IsInBounds(i,j))  
        break;
      ccol=document.getElementById(id).style.color;
      if (ccol==ijcol)
      {
        rcandidate.push(id);
      }
      else 
        break;
     } while (iof(removing,id)==-1) 
     

     if(rcandidate.length>4)
       removing = removing.concat(rcandidate);
    }
    
    function preDealBalls()
    {
      for (var i = 0; i < 3; i++) 
      {
        var rndIdx =  Math.floor(Math.random()*7);
        var rndCol = colorArray[rndIdx];
        nextBalls[i] = rndCol;
        var id = "ball" + i;
        var el = document.getElementById(id);
        el.style.color = rndCol;
        el.childNodes[0].src = imagesArray[rndIdx];
        nextBallsImg[i] = imagesArray[rndIdx];
        
      }
    }
    
    function Deal(emptycells)  
    { 
      var deals = 3
      if (emptycells <3 )
        deals = emptycells;
      
      for (var i = 0; i < deals; i++) 
      {
        
        var id ="";
        do {
         
          var randomnumber=Math.floor(Math.random()*Height*Width); 
          var row = Math.floor(randomnumber/Height); 
          var column = randomnumber%Width;
          id = MakeID(row,column);  
        } while (cellHTable[id] == -1);  
        
        var theTd = document.getElementById(id);
        theTd.style.color = nextBalls[i];
        theTd.childNodes[0].src = nextBallsImg[i];
        cellHTable[id] = -1;
        matrix[row][column] = -1;
      }
      preDealBalls();
    } 
    
    function initGame()
    {
      preDealBalls();
      Deal(81);
      document.forms['scores'].hscval.value = hiscore;      
    }
    
    function showOrHideNext()
    {
      var el = document.getElementById("nextballs");
      el.style.display = (el.style.display == '') ? "none" : "";  
    }
  
