/* This javascript allows us to scroll through a game           *
 * Copyright The ICCF WebServer Development Team                *
 * Based on the script provided by Chessbase                    *
 * Written 04 May 2004 (A.Chatterjee) Last Modified 07 Jun 2004 */

/* Current ply count on hidden form    ... done 13 May
     To confirm it put <input type="text" name="currentply" value="65">
     instead of "hidden" on the web page
   Complex moves                       ... done 13 May
   Pawn Promotion                      ... done 13 May
*/

var MoveNo; var Row; var Col; var HOffs;   
var MaxMoves; var MoveArray=new Array(1);
var HiColor='#c6d6ea'; var HiIndex;
var ColA=new Array("a","b","c","d","e","f","g","h");
var QCol; var QRow; 
//----------------------------------------------------------------------------------------------
function Init(GifPath,StartPly)                                         //Initialize
//GifPath (location of pics), BoardTurned (true if viewed from Black's side)
//and StartPly (The MoveNo of the initial display) are provided by the server            
{
MaxMoves=HOffs=0;
for (var i=0;i<document.links.length;i++)    //Loop over all links to locate first and last move
    {
    if (document.links[i].href.indexOf(":Display(") > -1) MaxMoves++;
    if (document.links[i].href.indexOf(":Display(1,") > -1) HOffs=i;
    }
Square=new Array(8);                                //Create 3 dim. array to store all positions
for (Row=0;Row<8;Row++)
    {     
    Square[Row]=new Array(8);
    for (Col=0;Col<8;Col++)
        {          
        Square[Row][Col]=new Array(MaxMoves+1);
        for (MoveNo=0;MoveNo<=MaxMoves;MoveNo++) Square[Row][Col][MoveNo]="Null";
        }     
    }
StartPos();                                                                   //Initial position
if (MaxMoves>0) 
    for (MoveNo=1;MoveNo<=MaxMoves;MoveNo++) 
        { GraspMove(); ComputePosition(); }               //Store the positions after every move
MoveNo=StartPly;                                                              //Current position 
if (MoveNo > 0)
   {
   document.links[HOffs+MoveNo-1].style.backgroundColor=HiColor;           //Highlight this move
   HiIndex=HOffs+MoveNo-1;                               //Index of the link that is highlighted
   }
else HiIndex=-1;

gifs=new Array(26);                                          //Array to store pics of the pieces 
for (i=0;i<26;i++) gifs[i]=new Image(); 
gifs[0].src= GifPath+"b.gif";   gifs[1].src= GifPath+"bBb.gif"; 
gifs[2].src= GifPath+"bBw.gif"; gifs[3].src= GifPath+"bKb.gif"; 
gifs[4].src= GifPath+"bKw.gif"; gifs[5].src= GifPath+"bNb.gif"; 
gifs[6].src= GifPath+"bNw.gif"; gifs[7].src= GifPath+"bPb.gif"; 
gifs[8].src= GifPath+"bPw.gif"; gifs[9].src= GifPath+"bQb.gif"; 
gifs[10].src=GifPath+"bQw.gif"; gifs[11].src=GifPath+"bRb.gif";
gifs[12].src=GifPath+"bRw.gif"; gifs[13].src=GifPath+"w.gif"; 
gifs[14].src=GifPath+"wBb.gif"; gifs[15].src=GifPath+"wBw.gif";
gifs[16].src=GifPath+"wKb.gif"; gifs[17].src=GifPath+"wKw.gif"; 
gifs[18].src=GifPath+"wNb.gif"; gifs[19].src=GifPath+"wNw.gif";
gifs[20].src=GifPath+"wPb.gif"; gifs[21].src=GifPath+"wPw.gif"; 
gifs[22].src=GifPath+"wQb.gif"; gifs[23].src=GifPath+"wQw.gif"; 
gifs[24].src=GifPath+"wRb.gif"; gifs[25].src=GifPath+"wRw.gif";
}
//----------------------------------------------------------------------------------------------
function MoveBack(Delta)                                                   //Go back Delta moves
{
var x=MoveNo-Delta; if (x<0) x=0;
MoveNo=x; Display(MoveNo,"");
}
//----------------------------------------------------------------------------------------------
function MoveFwd(Delta)                                                 //Go forward Delta moves
{
var x=MoveNo+Delta; if (x>MaxMoves) x=MaxMoves;
MoveNo=x; Display(MoveNo,"");
}
//----------------------------------------------------------------------------------------------
function Display(No,String)                                                 //Display a position
{
var ImageStr;

if (HiIndex > -1)
   document.links[HiIndex].style.backgroundColor=document.bgColor;            //Remove highlight
MoveNo=No;                                //This global variable keeps track of where we are now
if (MoveNo>0)
   {
   document.links[HOffs+MoveNo-1].style.backgroundColor=HiColor;                     //Highlight
   HiIndex=HOffs+MoveNo-1;                                                  //Remember the index
   }

for (Row=0;Row<8;Row++)                                                      //Graphical display
    {
    for (Col=0;Col<8;Col++)
        {
        ImgStr=ColA[Col]+(8-Row);
        document.images[ImgStr].src=gifs[SquareToGif()].src;
        }
    }
//Output present MoveNo (i.e. the currentPly) to the hidden form:
document.forms[0].currentply.value=MoveNo;
}
//----------------------------------------------------------------------------------------------
function SquareToGif()            //Returns index of gif image according to piece and background
{
if ( (Row+Col)%2)  //Black squares
   {
   if (Square[Row][Col][MoveNo]=="--") return 0;
   if (Square[Row][Col][MoveNo]=="bb") return 1;
   if (Square[Row][Col][MoveNo]=="bk") return 3;
   if (Square[Row][Col][MoveNo]=="bn") return 5;
   if (Square[Row][Col][MoveNo]=="bp") return 7;
   if (Square[Row][Col][MoveNo]=="bq") return 9;
   if (Square[Row][Col][MoveNo]=="br") return 11;
   if (Square[Row][Col][MoveNo]=="wb") return 14;
   if (Square[Row][Col][MoveNo]=="wk") return 16;
   if (Square[Row][Col][MoveNo]=="wn") return 18;
   if (Square[Row][Col][MoveNo]=="wp") return 20;
   if (Square[Row][Col][MoveNo]=="wq") return 22;
   if (Square[Row][Col][MoveNo]=="wr") return 24;
   }
else                //White squares
   {
   if (Square[Row][Col][MoveNo]=="--") return 13;
   if (Square[Row][Col][MoveNo]=="bb") return 2;
   if (Square[Row][Col][MoveNo]=="bk") return 4;
   if (Square[Row][Col][MoveNo]=="bn") return 6;
   if (Square[Row][Col][MoveNo]=="bp") return 8;
   if (Square[Row][Col][MoveNo]=="bq") return 10;
   if (Square[Row][Col][MoveNo]=="br") return 12;
   if (Square[Row][Col][MoveNo]=="wb") return 15;
   if (Square[Row][Col][MoveNo]=="wk") return 17;
   if (Square[Row][Col][MoveNo]=="wn") return 19;
   if (Square[Row][Col][MoveNo]=="wp") return 21;
   if (Square[Row][Col][MoveNo]=="wq") return 23;
   if (Square[Row][Col][MoveNo]=="wr") return 25;
   }
}
//----------------------------------------------------------------------------------------------
function StartPos()                                               //Stores the starting position
{ 
MoveNo=0; 
Square[0][0][MoveNo]="br"; Square[0][1][MoveNo]="bn"; Square[0][2][MoveNo]="bb";
Square[0][3][MoveNo]="bq"; Square[0][4][MoveNo]="bk"; Square[0][5][MoveNo]="bb";
Square[0][6][MoveNo]="bn"; Square[0][7][MoveNo]="br"; 
for (Col=0;Col<8;Col++) Square[1][Col][MoveNo]="bp";
for (Row=2;Row<6;Row++) { for (Col=0;Col<8;Col++) Square[Row][Col][MoveNo]="--"; }
for (Col=0;Col<8;Col++) Square[6][Col][MoveNo]="wp";
Square[7][0][MoveNo]="wr"; Square[7][1][MoveNo]="wn"; Square[7][2][MoveNo]="wb";
Square[7][3][MoveNo]="wq"; Square[7][4][MoveNo]="wk"; Square[7][5][MoveNo]="wb";
Square[7][6][MoveNo]="wn"; Square[7][7][MoveNo]="wr";
}
//---------------------------------------------------------------------------------------------
function GraspMove()                                      //Parses href tag to isolate the move
{
var String=document.links[MoveNo+HOffs-1].href;
var x=String.indexOf("'"); var y=String.lastIndexOf("'");
MoveArray[MoveNo]=String.substring(x+1,y);
//alert("GraspMove...MoveNo="+MoveNo+ ",MoveArray="+MoveArray[MoveNo]);
}
//---------------------------------------------------------------------------------------------
function CheckAndEmpty(XRow,XCol,XWhite,XPiece)                              //Empties a square
//Return 0 for invalid cases; -1 for obstructing pieces; 1 if ok
//When QCol or QRow != -1 we consider only this row/col (for moves like Nge7)
{
var Cq; var Sq;

if ((XCol<0) || (XCol>7) || (XRow<0) || (XRow>7)) return 0;
if ((QCol>-1) && (XCol != QCol)) return 0;           //For qualified (complex) moves check QCol
if ((QRow>-1) && (XRow != QRow)) return 0;           //For qualified (complex) moves check QRow

Cq=Square[XRow][XCol][MoveNo];
if (XWhite) Sq="w"+XPiece; else Sq="b"+XPiece;
if ((XPiece!="n") && (XPiece!="k"))       //Check obstruction except for Knight and King moves
   { if ( (Cq != "--") && (Cq != Sq) ) return -1; }
if (Cq==Sq) { Square[XRow][XCol][MoveNo]="--"; return 1; } 
else        return 0;
}
//---------------------------------------------------------------------------------------------
function ComputePosition()                                     //Store new position after a move
{
var Capture; var White; var Quali; var Move; var x; var y; var Piece; var z; var DestRow;
var DRow; var DestCol; var DCol; var Promotion; var PromotedPiece; var i;

for (Row=0;Row<8;Row++)                                           //First copy previous position
    { for (Col=0;Col<8;Col++) Square[Row][Col][MoveNo]=Square[Row][Col][MoveNo-1]; }
Quali=""; Quali2="";                       //Qualifiers for complex moves and very complex moves 
Move=MoveArray[MoveNo];

//If the move contains "=" (for promotion) get rid of it
x=Move.indexOf("="); if (x>-1) Move=Move.substring(0,x)+Move.substring(x+1,Move.length);

x=Move.indexOf("x"); if (x>-1) Capture=1; else Capture=0;
if (Move.indexOf("..")>-1) White=0; else White=1;
y=Move.indexOf('.')+1; if (White==0) y++;
Piece=Move.charAt(y); 
if ((Piece != "K") && (Piece != "Q") && (Piece != "R") && (Piece != "B") && (Piece != "N"))
    { if (Capture) Quali=Piece; Piece="P"; }
Piece=Piece.toLowerCase();

z=Move.length-1;                  //Search backwards from the end looking for a numeric character
for (i=z;i>0;i--)
    {
    DestRow=Move.charAt(i);
    if ( (DestRow == "1") || (DestRow == "2") || (DestRow == "3") || (DestRow == "4") ||
         (DestRow == "5") || (DestRow == "6") || (DestRow == "7") || (DestRow == "8") ||
         (DestRow == "O") /*Castling*/) { z=i; DestRow=Move.charAt(z); break; }
    }

Promotion=false;
if (z<Move.length-1)
   {
   PromotedPiece=Move.charAt(z+1).toLowerCase();
   if ( (PromotedPiece == "q") || (PromotedPiece == "r") || (PromotedPiece == "n") ||
        (PromotedPiece == "b") ) Promotion=true;
   }

DRow=8-parseInt(DestRow);
DestCol=Move.charAt(z-1);
if (DestCol=="a") DCol=0;
else if (DestCol=="b") DCol=1; else if (DestCol=="c") DCol=2; else if (DestCol=="d") DCol=3; 
   else if (DestCol=="e") DCol=4; else if (DestCol=="f") DCol=5; else if (DestCol=="g") DCol=6; 
   else DCol=7;
//alert("Capture="+Capture+",White="+White+",Piece="+Piece+",DRow="+DRow+",DCol="+DCol);

//For pawn moves Qualifier is the column of the starting square (computed above) 
//For other cases Qualifier as in R5xh6 (Quali=5) or Nge7 (Quali=g) is calculated here
if ( (Piece !="p") && (Piece !="k") )
   {
   if (z > y+2+Capture) Quali=Move.charAt(y+1);                         //Complex move e.g. Nge7
   if (z > y+3+Capture) Quali2=Move.charAt(y+2);                  //Very complex move e.g. Qg2c6
   } 
switch (Quali)
   {
   case "a": QCol=0; QRow=-1; break; case "b": QCol=1; QRow=-1; break;
   case "c": QCol=2; QRow=-1; break; case "d": QCol=3; QRow=-1; break;
   case "e": QCol=4; QRow=-1; break; case "f": QCol=5; QRow=-1; break;
   case "g": QCol=6; QRow=-1; break; case "h": QCol=7; QRow=-1; break;
   case "1": QCol=-1; QRow=7; break; case "2": QCol=-1; QRow=6; break;
   case "3": QCol=-1; QRow=5; break; case "4": QCol=-1; QRow=4; break;
   case "5": QCol=-1; QRow=3; break; case "6": QCol=-1; QRow=2; break;
   case "7": QCol=-1; QRow=1; break; case "8": QCol=-1; QRow=0; break;
   default:  QCol=-1; QRow=-1;
   }
if (Quali2 != "") QRow=8-parseInt(Quali2);

if (Move.charAt(y)=='O')                                                          //Castling move
   {
   if (White && (Move.substring(y,z+1)=="O-O") )
      {
      Square[7][4][MoveNo]="--"; Square[7][7][MoveNo]="--";
      Square[7][6][MoveNo]="wk"; Square[7][5][MoveNo]="wr";
      }
   if (!White && (Move.substring(y,z+1)=="O-O") )
      {
      Square[0][4][MoveNo]="--"; Square[0][7][MoveNo]="--";
      Square[0][6][MoveNo]="bk"; Square[0][5][MoveNo]="br";
      }
   if (White && (Move.substring(y,z+1)=="O-O-O") )
      {
      Square[7][4][MoveNo]="--"; Square[7][0][MoveNo]="--";
      Square[7][2][MoveNo]="wk"; Square[7][3][MoveNo]="wr";
      }
   if (!White && (Move.substring(y,z+1)=="O-O-O") )
      {
      Square[0][4][MoveNo]="--"; Square[0][0][MoveNo]="--";
      Square[0][2][MoveNo]="bk"; Square[0][3][MoveNo]="br";
      }
   return;
   }

if (White) Square[DRow][DCol][MoveNo]="w"+Piece;                //Put piece on destination square
else       Square[DRow][DCol][MoveNo]="b"+Piece;

switch (Piece) 
   {
   case "p":
      if (Capture)
         {
         if (Square[DRow][DCol][MoveNo-1]=="--")                                  //e.p. capture
            {if (White) Square[DRow+1][DCol][MoveNo]="--"; else Square[DRow-1][DCol][MoveNo]="--";}
         if (White) Square[DRow+1][QCol][MoveNo]="--"; else Square[DRow-1][QCol][MoveNo]="--";
         }
      else
         {
         if (White)
            {
            if (Square[DRow+1][DCol][MoveNo]=="wp") Square[DRow+1][DCol][MoveNo]="--";
            else                                    Square[DRow+2][DCol][MoveNo]="--";
            }
         else
            {
            if (Square[DRow-1][DCol][MoveNo]=="bp") Square[DRow-1][DCol][MoveNo]="--";
            else                                    Square[DRow-2][DCol][MoveNo]="--";
            }
         }
      if (Promotion)                                   //Put Promoted piece on destination square
         {
         if (White) Square[DRow][DCol][MoveNo]="w"+PromotedPiece;
         else       Square[DRow][DCol][MoveNo]="b"+PromotedPiece;
         }  
      break;
   case "k":
      Seen=0;
      if (!Seen) { SCol=DCol-1; SRow=DRow-1; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol+1; SRow=DRow+1; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol-1; SRow=DRow;   Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol+1; SRow=DRow;   Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol;   SRow=DRow-1; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol;   SRow=DRow+1; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol-1; SRow=DRow+1; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol+1; SRow=DRow-1; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      break;
   case "n":
      Seen=0;
      if (!Seen) { SCol=DCol-1; SRow=DRow-2; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol+1; SRow=DRow-2; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol-1; SRow=DRow+2; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol+1; SRow=DRow+2; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol-2; SRow=DRow-1; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol+2; SRow=DRow-1; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol-2; SRow=DRow+1; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      if (!Seen) { SCol=DCol+2; SRow=DRow+1; Seen=CheckAndEmpty(SRow,SCol,White,Piece); }
      break;
   case "b":
      Seen=0;
      if (Seen!=1)
         {
         for (SCol=DCol+1;SCol<DCol+8;SCol++)
             { SRow=SCol+DRow-DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
          }
      if (Seen!=1)
         {
         for (SCol=DCol-1;SCol>DCol-8;SCol--)
             { SRow=SCol+DRow-DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
          }
      if (Seen!=1)
         {
         for (SCol=DCol-1;SCol>DCol-8;SCol--)
             { SRow=-SCol+DRow+DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
          }
      if (Seen!=1)
         {
         for (SCol=DCol+1;SCol<DCol+8;SCol++)
             { SRow=-SCol+DRow+DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      break;
   case "r":
      Seen=0;
      if (Seen!=1)
         {
         for (SCol=DCol-1;SCol>-1;SCol--)
             { SRow=DRow; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      if (Seen!=1)
         {
         for (SCol=DCol+1;SCol<8;SCol++)
             { SRow=DRow; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      if (Seen!=1)
         {
         for (SRow=DRow-1;SRow>-1;SRow--)
             { SCol=DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      if (Seen!=1)
         {
         for (SRow=DRow+1;SRow<8;SRow++)
             { SCol=DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      break;
   case "q":
      Seen=0;
      if (Seen!=1)
         {
         for (SCol=DCol+1;SCol<DCol+8;SCol++)
             { SRow=SCol+DRow-DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      if (Seen!=1)
         {
         for (SCol=DCol-1;SCol>DCol-8;SCol--)
             { SRow=SCol+DRow-DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      if (Seen!=1)
         {
         for (SCol=DCol-1;SCol>DCol-8;SCol--)
             { SRow=-SCol+DRow+DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      if (Seen!=1)
         {
         for (SCol=DCol+1;SCol<DCol+8;SCol++)
             { SRow=-SCol+DRow+DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      if (Seen!=1)
         {
         for (SCol=DCol-1;SCol>-1;SCol--)
             { SRow=DRow; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      if (Seen!=1)
         {
         for (SCol=DCol+1;SCol<8;SCol++)
             { SRow=DRow; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      if (Seen!=1)
         {
         for (SRow=DRow-1;SRow>-1;SRow--)
             { SCol=DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
         }
      if (Seen!=1)
         {
         for (SRow=DRow+1;SRow<8;SRow++)
             { SCol=DCol; Seen=CheckAndEmpty(SRow,SCol,White,Piece);
             if ((Seen==-1) || (Seen==1)) break; }
          }
   }
}
//---------------------------------------------------------------------------------------------
