/************
ifruitgame.js
copyright (c) ragnar nohre
************/


    var DimR = 9;         // Antal rutor (rader)
    var DimK = 9;         // Antal rutor (kolumner)
    var DimDelta = 34;    // Storleken av en kvadratisk ruta (mellanrum EJ inräknat)

    var CANVAS;           // vår canvas 

    var IMG   = new Array(8);


    var IMFILE = new Array(8);

    IMFILE[0] = "dum.gif";
    IMFILE[1] = "orange2.gif";
    IMFILE[2] = "apple2.gif";
    IMFILE[3] = "banana2.gif";
    IMFILE[4] = "pear2.gif";
    IMFILE[5] = "cherry2.gif";
    IMFILE[6] = "lemmon2.gif";
    IMFILE[7] = "melon2.gif";

    var MATRIX;     // Spelbordet

    var actionState = 0;
    var KrdSrc      = null; // koordinat till SRC (om någon)
    var KrdDst      = null; // koordinat till DST (om någon)

    var animPathSeq = null;  // sekvens av koordinater
    var animPathIx  = 0;     // aktuellt index till ovanst sekvens
    var animPathSymb= 0;     // fruktsymbol som skall flyttas
    var animPathID  = 0;     // ID som timern returnerar

    var animCreateIx= 0;
    var animCreateID= 0;     // ID som timern returnerar

    var animEraseSeq= 0;     // koordinater som skall suddas
    var animEraseIx = 0;
    var animEraseID = 0;     // ID som timern returnerar

    var DistMTX;    // Avstånd från SRC, imitieras då man klickar på SRC
    var POANG       = 0;

    function obj( nam )
    {
      return document.getElementById(nam);
    }//obj

  /*******************************************************************************
  ANROP:       saveCookie(namn,  värde, antaldagar);
  VERSION:     090214 RAG
  UPPGIFT:     Sparar en kaka
  *******************************************************************************/
  function saveCookie(namn, innehall, numDays)
  {
    numDays=parseInt(eval(numDays));  
    var numMS  = numDays*24*60*60*1000;

    var datum = new Date();                            // dagens datum.
    datum.setTime(datum.getTime() + numMS); 
    datum=datum.toGMTString(); 
    var datumsnutt="; expires=" +datum; 

    // spara kakvärdet i escape:ad form samtdatumsnutten 

    var kaka = namn+"="+escape(innehall)+datumsnutt;    
    
    document.cookie=kaka;
  }//saveCookie



  /*******************************************************************************
  ANROP:       str = getCookie(namn);
  VERSION:     090214 RAG
  UPPGIFT:     Returnerar angiven kaksträng
  *******************************************************************************/
  function getCookie(namn)
   {
     var kakor=document.cookie;    //alla kakor

     var kakor_delar=kakor.split("; ");  
     for (ix=0;ix<kakor_delar.length;ix++)    
       {
	 tva_delar=kakor_delar[ix].split("="); 
	 if (tva_delar[0]==namn)
	   return unescape(tva_delar[1]); 
       }
     return "";    // kakan fanns ej
   }// getCookie


  function restoreState()
  {
    var stateStr = getCookie("fruits:");
    if (stateStr.length<80)
    { 
        for (var r=0; r<MATRIX.length;++r)
	  for (var k=0; k<MATRIX[r].length;++k)
	      MATRIX[r][k] = 0;

        POANG = 0;
        return;
     }


    var ix=0;
    for (var r=0; r<MATRIX.length;++r)
      {
	for (var k=0; k<MATRIX[r].length;++k)
	    MATRIX[r][k] = parseInt( stateStr.charAt(ix++) );
      }
   
    var poangstr =  getCookie("points:");
    POANG = parseInt( poangstr );
    obj("poang").innerHTML = "score = " + POANG;
    draw();
  }// restoreState

  function storeState()
  {
    var stateStr = "";

    for (var r=0; r<MATRIX.length;++r)
      {
	for (var k=0; k<MATRIX[r].length;++k)
           { var i = MATRIX[r][k];
             stateStr = stateStr + "0123456789".charAt(i);
           }
      }

    saveCookie("fruits:", stateStr, 365);
    saveCookie("points:", POANG, 365);
  }// storeState


   // symbol = getMatrix( krd );
   function getMatrix( krd )
   {
     return MATRIX[krd.r][krd.k];
   }// getMatrix


   function setMatrix( krd, symbol )
   {
     MATRIX[krd.r][krd.k] = symbol;
   }// setMatrix



   /*******************************************************************************
    ANROP:    drawSq(cts,   k,r, background, symbol)
    VERSIOBN:  080926 RAG
    UPPGIFT:  Målar rutan med symbol symbol
              bakgrunden målas
              background==0  => tom
              background==1  => SRC
              background=2   => DST
    **********************************************************************************/
    function drawSq(ctx, k,r,background, symb)
    {
      ctx.save();

      ctx.fillStyle = "rgb(240,240,255)";

      if (background==1)
        ctx.fillStyle = "rgb(0,200,0)";
      if (background==2)
        ctx.fillStyle = "rgb(100,240,100)";
      if (background==3)
        ctx.fillStyle = "rgb(200,255,200)";

      ctx.fillRect (0+k*(DimDelta+1)+1,r*(DimDelta+1)+1,DimDelta,DimDelta);

      if (symb>0 && symb!=8)
	  ctx.drawImage(IMG[symb],k*(DimDelta+1)+1, r*(DimDelta+1)+1);
      if (symb==8)
      	  ctx.drawImage(IMG[symb],1+k*(DimDelta+1), 1+r*(DimDelta+1));

      ctx.restore();
    }// drawSq



    function clearSrc(ctx)
    {   
      if (KrdSrc!=null)
        { drawSq(ctx, KrdSrc.k, KrdSrc.r, 0,  getMatrix(KrdSrc));
	  KrdSrc = null;
        }
    }

    function clearDst(ctx)
    {   
      if (KrdDst!=null)
        {  drawSq(ctx, KrdDst.k, KrdDst.r, 0, getMatrix(KrdDst));
	   KrdDst = null;
        }
    }


    function command( cmd )
    {
       actionState = cmd;  // 0==src, 1==dst, 2==go

       if (cmd==0) // src
           {// playSound('create.wav');
	    var canvas = obj("canvas");
	    var ctx = canvas.getContext("2d");
	    clearDst(ctx);

             var butt = obj("buttGo");
	     butt.disabled = true;

	     clearDistMTX();
	     draw();
	   }

       if (cmd==1)// dst
	 {  //playSound('claps.wav');
             var butt = obj("buttGo");
	     butt.disabled = true;
          }

       if (cmd==2) // go
         {
            var rd     = obj("rdSrc");
	    var canvas = obj("canvas");
	    var ctx = canvas.getContext("2d");

	    animPathIx = 0;
            rd.checked = true;
	    MATRIX[KrdDst.r][KrdDst.k] = MATRIX[KrdSrc.r][KrdSrc.k];
	    MATRIX[KrdSrc.r][KrdSrc.k] =0;
	    animPathSymb = MATRIX[KrdDst.r][KrdDst.k];
	    animPathID = setInterval("animPathFunc()",50);
	    obj("poang").innerHTML = "score = " + POANG;
         }


       if (cmd==3)
	   { 
              if(true || confirm('clear the board?'))
	      {
	        initBoard(DimR,DimK);
		draw();
	        obj("poang").innerHTML = "scrore = " + POANG ;

	        animCreateIx = 3;
	        animCreateID = setInterval( "animCreateFunc()" , 500 );
	        command( 0 );
              }

	   }
    }//command


  /***************************************************************************
  ANROP:    animPathFunc();
  VERSION:  081005RAG
  UPPGIFT:  Sköter animeringen av ett object som rör sig
            involverar alla globaler med namn animPath*
  ****************************************************************************/
   function animPathFunc()
   {  
     if (animPathSeq==null)
	   return;

     var ctx = CANVAS.getContext("2d");

     if (animPathIx>= (animPathSeq.length-1))
	 { 
	   clearInterval( animPathID );
           clearDistMTX();
	   draw();
	   var erasing = testNumInRow(KrdDst.r,KrdDst.k);
	   command(0);  // action src
	   clearDst(ctx);
	   clearSrc(ctx);

           if (erasing==0)
	     { animCreateIx = 3;
	       animCreateID = setInterval( "animCreateFunc()" , 500 );
             }
	   storeState();

	   return;
	 }

     // iterera 2 varv
     // sudda i första varvet 
     // rita symbolen i det andra

     {
	 var ix1 =  parseInt(animPathIx);
	 var ix2 =  ix1+1;
	 var f   = animPathIx-ix1;
     
	 var p1 = animPathSeq[ix1];
	 var p2 = animPathSeq[ix2];
	 var p = null;
	 if (Math.abs(f)<0.1)
	     p = p1;
	 else p = new Krd((p1.r+p2.r)/2,(p1.k+p2.k)/2);

	 var symb = animPathSymb;

	 drawSq(ctx, p.k,p.r, 0, 0);
     }

     animPathIx += 0.5;

     {
	var ix1 =  parseInt(animPathIx);
	var ix2 =  ix1+1;
	var f   = animPathIx-ix1;
     
	var p1 = animPathSeq[ix1];
	var p2 = animPathSeq[ix2];
	var p = null;
	if (Math.abs(f)<0.1)
	    p = p1;
	else p = new Krd((p1.r+p2.r)/2,(p1.k+p2.k)/2);

	var symb = animPathSymb;

	drawSq(ctx, p.k,p.r, 0, symb);
     }
   }// animPathFunc


   function Krd( rr, kk )
   {
     this.r = rr;
     this.k = kk;
     return this;
   }// Krd

   function KrdDist( rr, kk, pr,pk,  dd )
   {
     this.r = rr;
     this.k = kk;
     this.prevR = pr;
     this.prevK = pk;

     this.dist = dd;

     return this;
   }// KrdDist



function Cell( _dist, prevpos )
{
  this.dist  = _dist;
  this.prev  = prevpos
  return this;
}// Cell



function randomColor()
{
 var c = 1 + parseInt( Math.random()*(IMFILE.length-1) );
 return c;

 var prob = new Array();
 for (var p=0; p<=6 ; ++p)
   prob.push( 0.1*p );

 prob.push( 0.0 ); // 7
 prob.push( 0.05 ); // evil
 
var sum = 0;
 for (var p=0;p<prob.length ; ++p)
    sum = sum + prob[p];

 for (var p=0;p<prob.length ; ++p)
    prob[p] = prob[p]/sum;

 var f = Math.random(); 

 sum = 0;
 for (var p=0;p<prob.length ; ++p)
   {
      sum = sum + prob[p];
      if (sum>f)
         return p;
   }

 
 return 8;


}//randomColor






function randomStart(numR, numK)
{
   for (var r=0; r<numR ; ++r)
    for (var k=0; k<numK ; ++k)
      MATRIX[r][k] = 0;


  POANG = 0;
  animCreateIx = 5;
  animCreateID = window.setInterval( "animCreateFunc()" , 500 );

  obj("poang").innerHTML = "score = " + POANG;
}




/***************************************************************************
ANROP:    krd = getRandomFreeKrd();
VERSION:  081005RAG
UPPGIFT:  Returnerar en fri koordinat (eller null)
****************************************************************************/
function  getRandomFreeKrd()
{
  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)
    { 
      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)
		     return new Krd(r,k);
		 }
    }  	   	      
  return null; 
}// getRandomFreeKrd



/***************************************************************************
ANROP:    animCreateFunc()
VERSION:  081005RAG
UPPGIFT:  Returnerar en fri koordinat (eller null)
****************************************************************************/
function animCreateFunc()
{
  var krd = getRandomFreeKrd();

  if (krd==null || animCreateIx<=0)
     { clearInterval( animCreateID );
       animCreateID = 0;

       storeState();
       return;
     }
  animCreateIx--;	      
  MATRIX[krd.r][krd.k] = randomColor();

  var ctx = CANVAS.getContext("2d");
  drawSq(ctx, krd.k, krd.r, 0,  MATRIX[krd.r][krd.k]);

  testNumInRow(krd.r,krd.k);
}//animCreateFunc





function animEraseFunc()
{
   if (animEraseIx<animEraseSeq.length)
      { 
	 POANG += animEraseIx;
	 obj("poang").innerHTML = "score = " + POANG;

      }

   var ctx = CANVAS.getContext("2d");
   ctx.save();
   ctx.fillStyle = "rgb(240,240,255)";

   for (var i=0;i<animEraseSeq.length ; ++i)
       {
	   var pos = animEraseSeq[i];
	   var x = parseInt( pos.k*(DimDelta+1)+1 + Math.random()*(DimDelta-3) );
	   var y = parseInt( 1+pos.r*(DimDelta+1)+1 + Math.random()*(DimDelta-3) );
	   ctx.fillRect(x,y,3,3);
       }
   ctx.restore();

   animEraseIx++;

   // TODO applåder etc

   if (animEraseIx>30)
       {
	 for (var i=0; i<animEraseSeq.length; ++i)
	     {
                 var pos = animEraseSeq[i];
                 MATRIX[pos.r][pos.k]=0;
	     }
         clearInterval( animEraseID );
         animEraseID = 0;
         draw();

      }
}// animEraseFunc


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; // TODO?
     animEraseSeq[index++] = new Krd( 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 countDirection2(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 countDirection(rr,kk,col, dr,dk)
{
  num = countDirection2(rr,kk,col, dr,dk) + countDirection2(rr,kk,col,-dr,-dk);
  return num;
}// coundDirection

function atLeast(num, cnt)
{ 
   if (cnt>=num)
       return cnt;
   return 0;
}//atLeast



function testNumInRow(rr,kk)
{
  var col = MATRIX[rr][kk];
  if (col==0) return 0;

  var nn = 5-1; // col-1;
  var dirE = atLeast( nn, countDirection(rr,kk,col, 0,1));
  var dirN = atLeast( nn, countDirection(rr,kk,col, 1,0));
  var dirSE= atLeast( nn, countDirection(rr,kk,col, 1,1));
  var dirNE= atLeast( nn, countDirection(rr,kk,col, -1,1));

  var num = dirE+dirN+dirSE+dirNE;
  if (num>0)
   {
     num += 1;
     animEraseSeq = new Array( num );
     
     //     MATRIX[rr][kk]=0;  TODO
     var index = 0;
     animEraseSeq[index++] = new Krd( 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);

     animEraseIx = 0;
     if (animEraseID==0)
         animEraseID = window.setInterval("animEraseFunc()",50);
   }
  return num;  
}// testNumInRow



/***************************************************************************
ANROP:    d2 = distr2( krd1 , krd2 );
VERSION:  080927RAG
UPPGIFT:  returnerar avståndet ikvadrat
****************************************************************************/
function dist2( krd1, krd2 )
{
  var dr=krd1.r-krd2.r;
  var dk=krd1.k-krd2.k;
  return dr*dr+dk*dk;
}

/***************************************************************************
ANROP:    clearDistMTX( src )
VERSION:  080927RAG
UPPGIFT:  returnerar en array med bästa vägen från src till dst eller null
****************************************************************************/
function clearDistMTX()
{
  for (var r=0 ;r<MATRIX.length ;++r)
    for (var k=0 ; k<MATRIX[r].length ; ++k)
       DistMTX[r][k].dist = 2000;

}// clearDistMTX

/***************************************************************************
ANROP:    setDistMTX( src )
VERSION:  080927RAG
UPPGIFT:  returnerar en array med bästa vägen från src till dst eller null
****************************************************************************/
function setDistMTX(src)
{

  clearDistMTX()

  var que = new Array();

  que.push( new KrdDist(src.r+1, src.k,   src.r, src.k, 1) );
  que.push( new KrdDist(src.r-1, src.k,   src.r, src.k, 1) );
  que.push( new KrdDist(src.r,   src.k+1, src.r, src.k, 1) );
  que.push( new KrdDist(src.r,   src.k-1, src.r, src.k, 1) );

  while (que.length>0)
    {  
      var krdD = que.shift();
      if (inside(krdD.r, krdD.k) && getMatrix(krdD)==0)
	{
  	   var thisDist = krdD.dist;
	   var firstTime = (DistMTX[krdD.r][krdD.k].dist>=2000);

	   var improvement = false;
	   if (DistMTX[krdD.r][krdD.k].dist>thisDist)
	     improvement = true;

	   // improvement gör så att vi finner en mer naturlig (mindre manhattan) väg
	   if (DistMTX[krdD.r][krdD.k].dist==thisDist) 
	     { 
	       var dOld = dist2( src, DistMTX[krdD.r][krdD.k].prev);
	       var dNew = dist2( src, new Krd(krdD.prevR , krdD.prevK) );
	       improvement = (dNew<dOld);
	     }

	   if (improvement)
	     { 
	       DistMTX[krdD.r][krdD.k].dist=krdD.dist;
	       DistMTX[krdD.r][krdD.k].prev=new Krd( krdD.prevR, krdD.prevK);
	       if (firstTime)
		 { 
		   que.push( new KrdDist(krdD.r+1, krdD.k,   krdD.r, krdD.k, thisDist+1) );
		   que.push( new KrdDist(krdD.r-1, krdD.k,   krdD.r, krdD.k, thisDist+1) );
		   que.push( new KrdDist(krdD.r,   krdD.k+1, krdD.r, krdD.k, thisDist+1) );
		   que.push( new KrdDist(krdD.r,   krdD.k-1, krdD.r, krdD.k, thisDist+1) );
		 }
	     }
	}
    }
}// setDistMTX



/***************************************************************************
ANROP:    path = calcPath(dst)
VERSION:  080927RAG
UPPGIFT:  Returnerar en array med bästa vägen från KrdSrc till dst eller null
****************************************************************************/
function calcPath(dst)
{
  var pathLen = DistMTX[dst.r][dst.k].dist + 1;
  if (pathLen>=2000)
    return null;

  var path = new Array( pathLen );
  var i = pathLen-1;
  var r = dst.r;
  var k = dst.k;
  path[i] = new Krd(r,k);

  while (i>=0 && !(path[i].r==KrdSrc.r && path[i].k==KrdSrc.h))
    {  var p = path[i];
       path[--i] = DistMTX[p.r][p.k].prev;
    }

  return path;
}//calcPath


function mouseDown( ev )
{
   var krd = getKrd(ev.offsetX, ev.offsetY );
   if (krd==null)
       return;

   if (krd.r<MATRIX.length && krd.k<MATRIX[krd.r].length)
      {
	//        mouseHit( krd.r, krd.k );
      }

   var ctx = CANVAS.getContext("2d");
   if (ctx!=null)
       {
         if (actionState==0 && MATRIX[krd.r][krd.k]>0 && MATRIX[krd.r][krd.k]!=8 ) // src
	   {
	     clearSrc(ctx);
	     clearDst(ctx);

	     KrdSrc = krd;

	     drawSq(ctx, KrdSrc.k, KrdSrc.r, 1,  MATRIX[KrdSrc.r][KrdSrc.k]);
	     obj("rdDst").checked = true;
	     command(1);

	     setDistMTX(KrdSrc);

	     draw();
	     drawSq(ctx, KrdSrc.k, KrdSrc.r, 1,  MATRIX[KrdSrc.r][KrdSrc.k]);
	   }
         else
         if (actionState==1 && MATRIX[krd.r][krd.k]==0) // dst
	   {
             clearDst(ctx);

	     draw();
	     drawSq(ctx, KrdSrc.k, KrdSrc.r, 1,  MATRIX[KrdSrc.r][KrdSrc.k]);

	     KrdDst = krd;
	     drawSq(ctx, KrdDst.k, KrdDst.r, 2,  MATRIX[KrdDst.r][KrdDst.k]);
	     var path = calcPath(  KrdDst );
	     if (path!=null)
                {  var butt = obj("buttGo");
		   butt.disabled = false;
		   drawPath( path );
		   animPathSeq = path;
		}
	     else
	        obj("buttGo").disabled = true;
	   }
       }
}//mouseDown




/*********************************************************************
ANROP:     runGame()
VERSION:   080926 RAG
UPPGIFT:   körs då spelet laddas
**********************************************************************/
function runGame()
{

  window.scrollTo(0,1);

  CANVAS = obj("canvas");
  var ctx = CANVAS.getContext("2d");

  for (var i=0;i<IMFILE.length;++i)
    { IMG[i] = new Image();
      IMG[i].src = IMFILE[i];
    }

  initBoard(DimR,DimK);
  restoreState();
  draw();

  obj("poang").innerHTML = "score = " + POANG;
}// runGame


   // Returnerar true omm (r,k) innanför spelbordet
    function inside(r,k)
    {
      return (r>=0 && r<DimR && k>=0 && k<DimK);
    }

   function Point(xx,yy)
   {
     this.x = xx;
     this.y = yy;
     return this;
   }// Point



   function center( krd )
   {
     var x = (krd.k)*(DimDelta+1)+4+15;
     var y = (krd.r)*(DimDelta+1)+1+15;
     return new Point(x,y);
   }// center



    function getKrd( x, y )
    {
      var k = parseInt((x-4)/(DimDelta+1));
      var r = parseInt((y-1)/(DimDelta+1));
      if (k>=0 && k<DimK && r>=0 && r<DimR)
	{ var  krd = new Object();
	  krd.k = k;
	  krd.r = r;
	  return krd;
	}
      return null;
    }

   /*************************************************************************
   ANROP:    initBoard( R, K );
   VERSION:  080926 RAG
   UPPGIFT:  Initiarar 
                    MATRIX[][]
                    DistMTX[][]
   *************************************************************************/
   function initBoard(numR, numK)
   {

     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<numK ; ++k)
	       { DistMTX[r][k] = new Cell( 3000, new Krd(0,0) );
	         MATRIX[r][k] = 0;
	       }
       }      
     POANG = 0;
   }// initBoard



   /*************************************************************************
   ANROP:    draw()
   VERSION:  080926 RAG
   UPPGIFT:  Ritar hela brädet och alla symboler.
   *************************************************************************/
    function draw()
    {
      if (CANVAS.getContext) {
        var ctx = CANVAS.getContext("2d");

        ctx.fillStyle = "rgb(50,50,128)";
        ctx.fillRect(0,0,316,316); //282);

        for (var k=0;k<DimK;++k)
	   for (var r=0;r<DimR;++r)
	      { 
                 
		 if (MATRIX[r][k]!=0)
		     drawSq(ctx, k,r, 0, MATRIX[r][k]);
                  else
	      	  if (DistMTX[r][k].dist<2000)
                       drawSq(ctx, k,r, 3, 0);
		  else drawSq(ctx, k,r, 0, 0);
	      }
      }
    }// draw


   /*************************************************************************
   ANROP:    drawPath(path)
   VERSION:  080926 RAG
   UPPGIFT:  Ritar path
   *************************************************************************/
    function drawPath(path)
    {

//draw();
      if (CANVAS) //a.getContext) 
	{
	  var ctx = CANVAS.getContext("2d");
	  ctx.save();
	  ctx.beginPath();
          //ctx.clearRect(0,0,316,316);
          var len = path.length;

	  var c =  center(path[0]);
	  ctx.moveTo( c.x, c.y );


	  for (var i=1; i<len ; ++i)
	    {
	      c =  center(path[i]);
	      ctx.lineTo( c.x, c.y );

	    }
	  ctx.stroke();
	  ctx.restore();
	}
    }// drawPath

