/* This notice must be untouched at all times.

linesGame.js 
from http://www.ragnarius.com

By Ragnar Nohre

****************************************************/

var canvas1;
var canvas3;
var canvas2;

var ANIM1_DIST;
var ANIM1_SUB;
var ANIM1_ID;

var ANIM2_DIST;
var ANIM2_SUB;
var ANIM2_ID;
var ANIM2_TYP;
var ANIM2_CAT;

var ANIM3_CNT;
var ANIM3_ID;
var ERASER;

var ANIM4_CNT;
var ANIM4_ID;

var DELTA;


var SELECT_FLAG = 0;
var SELECT_R = 0;
var SELECT_K = 0;



var IMFILE = new Array(8);
IMFILE[0] = "/code/gameline/dum.gif";
IMFILE[1] = "/code/gameline/orange.gif";
IMFILE[2] = "/code/gameline/apple.gif";
IMFILE[3] = "/code/gameline/banana.gif";
IMFILE[4] = "/code/gameline/pear.gif";
IMFILE[5] = "/code/gameline/cherry.gif";
IMFILE[6] = "/code/gameline/lemmon.gif";
IMFILE[7] = "/code/gameline/melon.gif";


var MATRIX;
var DistMTX;

var POANG;



function obj( nam )
{
  return document.getElementById(nam);
}//obj


function initPos()
{

  DELTA = 21;

  var xpos = obj("sensitiva").style.left; //offsetLeft;
  var ypos = obj("sensitiva").style.top; //offsetTop;

  obj("canvas1").style.left = xpos;
  obj("canvas1").style.top = ypos;
  obj("canvas2").style.left = xpos;
  obj("canvas2").style.top = ypos;
  obj("canvas3").style.left = xpos;
  obj("canvas3").style.top = ypos;

}


function testPos()
{

canvas1.setColor("#FF0000");
canvas1.fillRect(0,0,10,10);
canvas1.paint();

canvas2.setColor("#00FF00");
canvas2.fillRect(0,0,10,10);
canvas2.paint();

canvas3.setColor("#0000FF");
canvas3.fillRect(0,0,10,10);
canvas3.paint();
}

function SetCookie(sName, sValue)
{
  date = new Date(2040,12,31);
  document.cookie = sName + "=" + sValue + "; expires=" + date.toGMTString();
}
function GetStateString()
{
  
  var startIx =  document.cookie.indexOf( "ragLines9x9v1.1" );
  if (startIx<0)
     return "";  
  var i1  =  document.cookie.indexOf( "(", startIx );
  if (i1<0)
     return "";  
  var i2  =  document.cookie.indexOf( ")", i1 );
  if (i2<=i1)
     return "";  
  return  document.cookie.substring(i1+1,i2);
}// GetStateString

function displayCookies()
{
  var str = GetStateString();
  obj("kaka").innerHTML = str;
  obj("kakahel").innerHTML = document.cookie;
}

function GetPointString()
{
  
  var startIx =  document.cookie.indexOf( "ragLines9x9v1.1" );
  if (startIx<0)
     return "";  
  var i1  =  document.cookie.indexOf( "[POANG:", startIx );
  if (i1<0)
     return "";  
  i1  =  document.cookie.indexOf( ":", i1 );
  var i2  =  document.cookie.indexOf( "]", i1 );
  if (i2<0)
     return "";  
  return  document.cookie.substring(i1+1,i2);
}


function storeState()
{
  var state = "(";
  for (var r=0; r<MATRIX.length;++r)
   {
     for (var k=0; k<MATRIX.length;++k)
        state = state + MATRIX[r][k];
     state = state + ".";
    }
  state = state + ")";
  state = state + "[POANG:" + POANG + "]";
  SetCookie("ragLines9x9v1.1", state);
  showState();
}

function showState()
{
  var stateStr = GetStateString()

  if (stateStr.length<80)
       return;
}


function restoreState()
{
  showState();
  var stateStr = GetStateString()
  if (stateStr.length<80)
       return;

  var ix=0;
  for (var r=0; r<MATRIX.length;++r)
   {
     for (var k=0; k<MATRIX.length;++k)
        MATRIX[r][k] = parseInt( stateStr.charAt(ix++) );
     ix++;
    }

   
   var poangstr =  GetPointString();
   POANG = parseInt( poangstr );
   document.onstop = storeState;
}

function inside(r,k)
{
  return (r>=0 && r<MATRIX.length && k>=0 && k<MATRIX.length);
}


function Position( rr, kk )
{
  this.r = rr;
  this.k = kk;
  return this;
}// Position

function Cell( _dist, prevpos )
{
  this.dist  = _dist;
  this.prev  = prevpos
  return this;
}// Cell

function randomColor()
{
 return parseInt(Math.random()*7)+1;
}

function initBoard(numR, numK)
{
 ANIM1_ID = 0;
 ANIM2_ID = 0;

 MATRIX = new Array( numR );
 DistMTX = new Array( numR );

 for (var r=0; r<numR ; ++r)
   {  MATRIX[r] = new Array( numK );
      DistMTX[r] = new Array( numK );
      for (var k=0; k<MATRIX[r].length ; ++k)
          DistMTX[r][k] = new Cell( 0, new Position(0,0) );
   }      

}

function randomStart(numR, numK)
{
   for (var r=0; r<numR ; ++r)
    for (var k=0; k<numK ; ++k)
        MATRIX[r][k] = 0;

  storeState();
  canvas1.clear();
  drawRutor(canvas1, 9,9);

  POANG = 0;
  ANIM4_CNT = 5;
  ANIM4_ID = window.setInterval( "animateCreate()" , 500 );

  obj("poang").innerHTML = POANG;
}


function drawRutor(canv, numR, numK)
{
   canv.setColor("#008800"); // 
   for (r=0;r<=numR;++r)
    { 
       var y = r*DELTA;
       canv.drawLine( 0,y, numK*DELTA, y);
    }
   for (k=0;k<=numR;++k)
    {
       var x = k*DELTA;
       canv.drawLine( x,0, x, numR*DELTA);
    }
  canv.paint();
}


function drawMark(canv, r,k, cat)
{
   if (cat>7 || cat<0)
         cat = 0;

   canv.drawImage(IMFILE[cat], k*DELTA+1, r*DELTA+1, 19,19);
}

function eraseMark(canv, r,k)
{
   canv.setColor( "#FFFFFF" );
   canv.fillRect( k*DELTA+1, r*DELTA+1, DELTA-2,DELTA-2 );
}

function drawMarks(canv)
{
  for (var r=0;r<MATRIX.length ; ++r)
    for (var k=0;k<MATRIX[r].length ; ++k)
      {
        if (MATRIX[r][k]>0)
           { var col = MATRIX[r][k];
             drawMark( canv, r,k, col );
           }
      }
    canv.paint();
    storeState();
}// drawMarks


function animateCreate()
{
  var numFree =0;
  for (var r=0;r<MATRIX.length;++r)
     for (var k=0;k<MATRIX.length;++k)
        if (MATRIX[r][k]==0)
	    numFree++;

  if (numFree==0 || ANIM4_CNT<=0)
     { window.clearInterval( ANIM4_ID );
       ANIM4_ID = 0;
       return;
     }

  if (numFree>0)
    { var n = parseInt( Math.random()*numFree );
      var cnt = 0;
      for (var r=0;r<MATRIX.length;++r)
         for (var k=0;k<MATRIX.length;++k)
             if (MATRIX[r][k]==0)
	        { if (cnt==n)
		    {  ANIM4_CNT--;	      
		       self.document.sndCreate.stop();
		       self.document.sndCreate.play();
		       MATRIX[r][k] = randomColor();
		       drawMark(canvas1, r,k, MATRIX[r][k] );
		       canvas1.paint();
		       testFiveInRow(r,k);
		       storeState();
		       return;
		    }
		  cnt++;
		}
    }  	   	    

}


function animateErase()
{
   if (ANIM3_CNT<ERASER.length)
       { POANG += ANIM3_CNT;
         obj("poang").innerHTML = POANG;
       }

   for (var i=0;i<ERASER.length ; ++i)
     {
       var pos = ERASER[i];
       var x = parseInt( pos.k*DELTA + Math.random()*(DELTA-3) );
       var y = parseInt( pos.r*DELTA + Math.random()*(DELTA-3) );
       canvas3.setColor("#FFFFFF");
       canvas3.fillRect(x,y,3,3);
     }
   canvas3.paint();
   ANIM3_CNT++;
   if (ANIM3_CNT==10)
      {
         if (ERASER.length<=6)
	     self.document.sndClap.play();
	 else
	     self.document.sndClap2.play();
      }


   if (ANIM3_CNT==30)
      {
         window.clearInterval( ANIM3_ID );
         ANIM3_ID = 0;
	 canvas1.clear();
         drawRutor(canvas1, 9,9);
	 drawMarks(canvas1);
	 canvas1.paint();

	 canvas3.clear();
	 canvas3.paint();
      }

}


function eraseDirection(rr,kk, col, dr,dk, index)
{
  var r = rr +dr;
  var k = kk +dk;
  while (inside(r,k) && MATRIX[r][k]==col)
   { 
     MATRIX[r][k] = 0;
     ERASER[index++] = new Position( r,k );
     r += dr;
     k += dk;
   }
  return index;
}

function eraseDirection2(rr,kk,col, dr,dk, index)
{
  index = eraseDirection(rr,kk,col, dr,dk, index);
  index = eraseDirection(rr,kk,col,-dr,-dk, index);
  return index;
}



function countDirection(rr,kk, col, dr,dk)
{
  var cnt = 0;
  var r = rr +dr;
  var k = kk +dk;
  while (inside(r,k) && MATRIX[r][k]==col)
   { r += dr;
     k += dk;
     cnt++;
   }
  return cnt;
}

function testDirection(rr,kk,col, dr,dk)
{
  num = countDirection(rr,kk,col, dr,dk) + countDirection(rr,kk,col,-dr,-dk);
  if (num>=4)
     return num;
  else return 0;
}

function testFiveInRow(rr,kk)
{
  var col = MATRIX[rr][kk];
  if (col==0) return 0;

  var dirE = testDirection(rr,kk,col, 0,1);
  var dirN = testDirection(rr,kk,col, 1,0);
  var dirSE= testDirection(rr,kk,col, 1,1);
  var dirNE= testDirection(rr,kk,col, -1,1);

  var num = dirE+dirN+dirSE+dirNE;
  if (num>0)
   {
     self.document.sndErase.play();

     num += 1;
     ERASER = new Array( num );
     
     MATRIX[rr][kk]=0;
     var index = 0;
     ERASER[index++] = new Position( rr,kk );

     if (dirE) index = eraseDirection2(rr,kk,col, 0,1, index);
     if (dirN) index = eraseDirection2(rr,kk,col, 1,0, index);
     if (dirSE) index= eraseDirection2(rr,kk,col, 1,1, index);
     if (dirNE) index= eraseDirection2(rr,kk,col, -1,1, index);

     ANIM3_CNT = 0;
     ANIM3_ID = window.setInterval("animateErase()",50);
   }
  storeState();
  return num;  
}

function recSetDist(r,k, dist, prevR, prevK )
{
  if (r>=0 && k>=0 && r<MATRIX.length && k<MATRIX[r].length)
    if (MATRIX[r][k]==0 && dist<DistMTX[r][k].dist)
       {
         DistMTX[r][k].dist = dist;
         DistMTX[r][k].prev.r = prevR;
         DistMTX[r][k].prev.k = prevK;

	 recSetDist(r+1,k, dist+1, r,k );
	 recSetDist(r-1,k, dist+1, r,k );
	 recSetDist(r,k+1, dist+1, r,k );
	 recSetDist(r,k-1, dist+1, r,k );
       }
}

function animateDist()
{
  var numFound = 0;

  canvas3.clear();

  for (var r=0 ;r<MATRIX.length ;++r)
    for (var k=0 ; k<MATRIX[r].length ; ++k)
      if (DistMTX[r][k].dist == ANIM1_DIST)
        { numFound++;
          x1 = DistMTX[r][k].prev.k * DELTA + DELTA/2;
          y1 = DistMTX[r][k].prev.r * DELTA + DELTA/2;

          x2 = k * DELTA + DELTA/2;
          y2 = r * DELTA + DELTA/2;



	  x1 = (x1+x2)/2;
	  y1 = (y1+y2)/2;

	  var z = 3;
          var z2 = 6;
	  if (ANIM1_SUB==0)
	        canvas3.fillRect(x1-z, y1-z, z2,z2);
          else  canvas3.fillRect(x2-z, y2-z, z2,z2);

        }


  ANIM1_SUB++;
  if (ANIM1_SUB>=2)
  { ANIM1_SUB = 0;
    ANIM1_DIST++;
  }

  if (numFound==0)
    { window.clearInterval(ANIM1_ID);
      self.document.sndSel.stop();
      ANIM1_ID = 0;

    }

  canvas3.paint();
}// animateDist


function animatePath()
{

  if (ANIM2_TYP==0)
   {
     var p1 = PATH[ANIM2_DIST-1];
     var p2 = PATH[ANIM2_DIST];

     var x1 = p1.k*DELTA + DELTA/2;
     var y1 = p1.r*DELTA + DELTA/2;
     var x2 = p2.k*DELTA + DELTA/2;
     var y2 = p2.r*DELTA + DELTA/2;

     canvas2.setStroke(5);
     canvas2.drawLine( x1,y1, x2,y2 );
     canvas2.paint();
     ANIM2_DIST++;
     if (ANIM2_DIST>=PATH.length)
        { ANIM2_DIST = 1;
          ANIM2_TYP  = 1;
          eraseMark( canvas1, SELECT_R, SELECT_K );
	  canvas1.paint();
        }
   }
  else
   {
      if (ANIM2_DIST>=PATH.length)
       { window.clearInterval(ANIM2_ID);
         ANIM2_ID = 0;
         self.document.sndMove.stop();

	 canvas3.clear();	 
         canvas3.paint();

	 canvas2.clear();	 
         canvas2.paint();

         var p2 = PATH[PATH.length-1];

	 MATRIX[p2.r][p2.k] = MATRIX[SELECT_R][SELECT_K];
	 MATRIX[SELECT_R][SELECT_K] = 0;
	 drawMark( canvas1, p2.r, p2.k, MATRIX[p2.r][p2.k]);
	 canvas1.paint();
	 storeState();

	 canvas1.clear();
         drawRutor(canvas1, 9,9);
	 drawMarks(canvas1);
	 canvas1.paint();

	 var erased1 = testFiveInRow(p2.r, p2.k);
	 if (!erased1)
	    {
	       ANIM4_CNT = 3;
	       ANIM4_ID = window.setInterval( "animateCreate()" , 500 );
            }
         return;
       }

      var p1 = PATH[ANIM2_DIST-1];
      var p2 = PATH[ANIM2_DIST];

      canvas3.clear();
      canvas3.drawImage(IMFILE[ANIM2_CAT], p2.k*DELTA+1, p2.r*DELTA+1, 19,19);
      canvas3.paint();


      ANIM2_DIST++;


   }


}// animatePath


function mouseHit( r0, k0 )
{
 if (ANIM1_ID!=0 && 0)
    { window.clearInterval(ANIM1_ID);
      self.document.sndSel.stop();
      ANIM1_ID = 0;
    }

 if (ANIM2_ID!=0 ) //|| ANIM4_ID!=0)
    return;

 if (MATRIX[r0][k0]>0)
   {
      drawMarks( canvas1 ); // erase old selection
      self.document.sndSel.play();

      var sel = MATRIX[r0][k0];

      canvas1.setColor( "#8888FF" );
      canvas1.fillRect( k0*DELTA+1, r0*DELTA+1, DELTA-2,DELTA-2 );
      canvas1.drawImage(IMFILE[sel], k0*DELTA+4, r0*DELTA+4, 13,13);
      canvas1.paint();

      for (var r=0 ;r<MATRIX.length ;++r)
        for (var k=0 ; k<MATRIX[r].length ; ++k)
          DistMTX[r][k].dist = 200;

      var save = MATRIX[r0][k0];
      MATRIX[r0][k0] = 0;
      recSetDist( r0,k0, 0, r0,k0 );
      MATRIX[r0][k0] = save;

      ANIM1_DIST = 0;
      ANIM1_SUB  = 0;
      ANIM1_ID = window.setInterval("animateDist()",50);
      SELECT_FLAG = 1;
      SELECT_R = r0;
      SELECT_K = k0;

      canvas3.setColor( "#8888FF" );
   }
 else
 if (SELECT_FLAG==1)
    {
      var pathLen = DistMTX[r0][k0].dist + 1;
      if (pathLen>=200)
         { self.document.sndErr.play(); 
	   return;
	 }
      PATH = new Array( pathLen );
      var i = pathLen-1;
      var r = r0;
      var k = k0;
      PATH[i] = new Position(r0,k0);

      while (i>=0 && !(PATH[i].r==SELECT_R && PATH[i].k==SELECT_K))
        {  var p = PATH[i];
           PATH[--i] = DistMTX[p.r][p.k].prev;

        }

      var col = MATRIX[SELECT_R][SELECT_K];
      canvas1.setColor( "#8888FF" );
      canvas2.setColor( "#8888FF" );
      canvas3.setColor( "#8888FF" );

      self.document.sndMove.play();
      ANIM2_DIST = 1;
      ANIM2_TYP  = 0;
      ANIM2_SUB  = 0;
      ANIM2_CAT  = col;
      ANIM2_ID   = window.setInterval("animatePath()",50);

      SELECT_FLAG = 0;
    }	  

}// mouseHit


function mouseDD(ev)
{
  var y = ev.offsetY;  // fel om man klickar i bitmapsbild...
  var x = ev.offsetX;
  obj("poang").innerHTML = POANG;
  var src = ev.srcElement;

  if ( ev.srcElement.id!="canvas3" )
   {   src = src.parentElement;
       x = src.style.pixelLeft;
       y = src.style.pixelTop;
    }

  var r0 = parseInt(  y/DELTA );
  var k0 = parseInt(  x/DELTA );

  if (r0<MATRIX.length && k0<MATRIX[r0].length)
      {
        mouseHit( r0, k0 );  
      }
}// mouseDD


function mouseDown( ev )
{

   var r0 = parseInt( ev.offsetY/DELTA );
   var k0 = parseInt( ev.offsetX/DELTA );

   if (r0<MATRIX.length && k0<MATRIX[r0].length)
      {
        mouseHit( r0, k0 );  
      }

}//mouseDown


function runGame()
{

  initPos();

  canvas1 = new jsGraphics("canvas1");
  canvas3 = new jsGraphics("canvas3");
  canvas2 = new jsGraphics("canvas2");


  initBoard(9,9);
  drawRutor(canvas1, 9,9);
  restoreState();

  drawMarks(canvas1);


  canvas1.paint();
  canvas3.paint();
  obj("poang").innerHTML = POANG;
}

