function RechargeEchiquier()
{
        problemLoading = true;
        document.write("Des problèmes sont survenus lors du chargement de l'échiquier. ");
        document.write("Veuillez <a href='JavaScript:window.location.reload();'>cliquer ici</a><br>pour recharger la page.");
}

function getImagePath()
{
         // variable containing the path to the images directory...
        var sRefImages = "";

        // check to see how far the HTML document is from the "/images" directory
        // count the number of "/" in the URL
        var nCount = 0;

        sURL = document.URL.toLowerCase();
        if (document.URL.toLowerCase().indexOf("http://") < 0)
        {
                // from local developement environment
                if (document.URL.toLowerCase().indexOf("file:///") < 0)
                {
                // Internet Explorer
                sURL = sURL.replace(/\\/g,"/");
                }
                var sDomain = "/site";
        }
        else
        {
                // from production environment
                var sDomain = document.domain.toLowerCase();
        }

        sTemp = sURL.substring(sURL.indexOf(sDomain) + sDomain.length);

        while (sTemp.indexOf("/") > -1)
        {
                sTemp = sTemp.substring(sTemp.indexOf("/") + 1);
                nCount++;
        }

        for (nInd = 0; nInd < nCount - 2; nInd++)
        {
                sRefImages = sRefImages + "../";
        }
    return sRefImages;
}

var sRefImages = getImagePath(); // variable containing the path to the images directory...
var problemLoading = false;
var aNotesWhite = new Array('',''); // array containing notes for White
var aNotesBlack = new Array(''); // array containing notes for Black
var aMovesWhite = new Array(); // array containing white's moves
var aMovesBlack = new Array(); // array containing black's moves
var aFromWhite = new Array();       // array containing the original location square of a white piece before a move
var aFromBlack = new Array();       // array containing the original location square of a black piece before a move
var aCapturesWhite = new Array();       // array containing the captured pieces by white
var aCapturesBlack = new Array();       // array containing the captured pieces by black
var board0 = new Array(-1,0);
var restr = new Array('1-0','0-1','1/2-1/2','*');
var Mypcs = " pnbrqk";
var files = "abcdefgh";
var ranks = "87654321";
var pieces = ' PCFTDR';
var BLACK_TO_MOVE = 1;
var initialMove = 0;
var curmov = 0;
var jbrd = 0;
var imgurl = sRefImages + "images/";
var nodraw = 0;
var atgm = -1;
var timerid = 0;
var timecall = 0;

function DessineEchiquier()
{
   if (!problemLoading)
   {
        document.write('<TABLE BORDER BORDERCOLOR="black" BACKGROUND="' + sRefImages + 'images/green.jpg" BORDER="1" CELLSPACING="0" CELLPADDING="0"><TR><TD>');
        document.write('<IMG SRC="' + sRefImages + 'images/br.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom name="brd0">');
        document.write('<IMG SRC="' + sRefImages + 'images/bn.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/bb.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/bq.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/bk.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/bb.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/bn.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/br.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom><BR>');

        for(i=0; i < 8; i++)
           document.write('<IMG SRC="' + sRefImages + 'images/bp.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<BR>');

        for(i=0; i < 8; i++)
           document.write('<IMG SRC="' + sRefImages + 'images/i.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<BR>');

        for(i=0; i < 8; i++)
           document.write('<IMG SRC="' + sRefImages + 'images/i.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<BR>');

        for(i=0; i < 8; i++)
           document.write('<IMG SRC="' + sRefImages + 'images/i.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<BR>');

        for(i=0; i < 8; i++)
           document.write('<IMG SRC="' + sRefImages + 'images/i.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<BR>');

        for(i=0; i < 8; i++)
           document.write('<IMG SRC="' + sRefImages + 'images/wp.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<BR>');

        document.write('<IMG SRC="' + sRefImages + 'images/wr.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/wn.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/wb.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/wq.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/wk.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/wb.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/wn.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom>');
        document.write('<IMG SRC="' + sRefImages + 'images/wr.gif" WIDTH=29 HEIGHT=29 ALIGN=bottom></TD></TR></TABLE>');
   }
}

function DessineNavigateur()
{
   if (!problemLoading)
   {
	document.write('<MAP NAME="map0">');
        document.write('<AREA COORDS="9,7,31,25" HREF="javascript:void(0)" onClick="GoStart(); return false">');
        document.write('<AREA COORDS="32,7,54,25" HREF="javascript:void(0)" onClick="Back5(); document.frmEchiquier.game0.value=MvStr(); return false">');
	document.write('<AREA COORDS="55,7,77,25" HREF="javascript:void(0)" onClick="Back(); document.frmEchiquier.game0.value=MvStr(); return false">');
	document.write('<AREA COORDS="78,7,100,25" HREF="javascript:void(0)" onClick="Forward(); document.frmEchiquier.game0.value=MvStr(); return false">');
	document.write('<AREA COORDS="101,7,123,25" HREF="javascript:void(0)" onClick="Forward5(); document.frmEchiquier.game0.value=MvStr(); return false">');
	document.write('<AREA COORDS="124,7,146,25" HREF="javascript:void(0)" onClick="GoEnd(); document.frmEchiquier.game0.value=MvStr(); return false">');
	document.write('<AREA COORDS="147,7,169,25" HREF="javascript:void(0)" onClick="Flip(); return false;">');
	document.write('</MAP>');
        document.write('<IMG SRC="' + sRefImages + 'images/conpanfa.jpg" BORDER="0" USEMAP="#map0"></P>');
        document.write('<FONT SIZE="2">Coup</FONT> <INPUT TYPE=text name="game0" VALUE="" SIZE=20>');
   }
}

function DrawPc(pc, sqr)
{
 var color, piece;
 if(nodraw)
   return;
 piece = Mypcs.charAt(pc & 7);
 color = (pc & 8) ? "b" : "w";
 if(piece == ' '){
   piece = "i";
   color = "";
   }
 if(board0[64] & 1)
   sqr = 63 - sqr;
 document.images[jbrd + sqr].src = imgurl + color + piece + ".gif";
 setTimeout("", 50);
}

function InitBoard()
{
if (typeof board0 == 'undefined')
  RechargeEchiquier();
 for(i=0; i<=64; i++)
    board0[i] = initposn[i];
}

function FindScrBrd()
{
 j=0;
 for(i=0;i < document.images.length; i++)
    if(document.images[i].name != "")
      if(document.images[i].name == 'brd' + j.toString()){
         jbrd = i;
         return;
         }
}

function DrawBoard()
{
 for(i=0; i<64; i++)
    DrawPc(board0[i], i);
}

function DoMv(pc, to, from)
{
 board0[to] = pc;
 board0[from] = 0;
 DrawPc(0, from);
 DrawPc(pc, to);
}

function Flip()
{
 board0[64] ^= 1;
 DrawBoard();
}

function GetOrds(sqr, flags)
{
 var co = "";
 if(flags & 0x40)
   co = files.charAt(sqr & 7);
 if(flags & 0x80)
   co = co + ranks.charAt((sqr & 0x38) >> 3);
 return co;
}

function Forward5()
{
 var i = 0;
 var bEnd = false;
 while( (curmov < aMovesWhite.length * 2) && (i < 10) && !bEnd)
 {
    Forward();
    if (curmov == aMovesWhite.length + aMovesBlack.length - 2 )
    {
        bEnd = true;
    }
    i++;
 }
}

function Back5()
{
 for(i=0; curmov > initialMove && i < 10; i++)
    Back();
}


function GoStart()
{
 curmov = initialMove;
 InitBoard();
 DrawBoard();
 document.frmEchiquier.game0.value = "";
 ShowComment(0);
}

function GoEnd()
{
 nodraw=1;
 while((curmov < aMovesWhite.length + aMovesBlack.length - 2) || (curmov == 0))
      Forward();
 nodraw=0;
 DrawBoard();
}

function Forward()
{
  if ((curmov < aMovesWhite.length + aMovesBlack.length - 2) || (curmov == 0))
  {
   var bWhite = false;
      if(curmov%2 == 0)
      {
        // white's move
        n = (curmov+2)/2;
        sMove = aMovesWhite[n];
        bWhite = true;
      }
      else
      {
        // black's move
        n = (curmov+1)/2;
        sMove = aMovesBlack[n];
        bWhite = false;
      }

    if (sMove.toUpperCase().indexOf("O-O-O") >= 0 )
    {
      // castling long...
        DoMv((bWhite ? 6 : 14), (bWhite ? 58 : 2), (bWhite ? 60 : 4));
        DoMv((bWhite ? 4 : 12), (bWhite ? 59 : 3), (bWhite ? 56 : 0));
        if (bWhite)
          aFromWhite[n] = 56;
        else
          aFromBlack[n] = 0;
    }
    else
    {
      if (sMove.toUpperCase().indexOf("O-O") >= 0 )
      {
        // castling short...
        DoMv((bWhite ? 6 : 14), (bWhite ? 62 : 6), (bWhite ? 60 : 4));
        DoMv((bWhite ? 4 : 12), (bWhite ? 61 : 5), (bWhite ? 63 : 7));
        if (bWhite)
          aFromWhite[n] = 63;
        else
          aFromBlack[n] = 7;

      }
      else
      {
        var to = GetTo(sMove, bWhite);
        var from = GetFrom(sMove, to, bWhite, n);
        var piece = board0[from];
        // Is it a promotion?
        if (sMove.indexOf("=") > 0)
                piece = GetPromotedPiece(sMove, bWhite);

        // finally, move the piece...
        DoMv(piece, to, from);
        if (bWhite)
                aFromWhite[n] = from;
        else
                aFromBlack[n] = from;
      }
    }    

    curmov++;
  }
}

function Back()
{
 if(curmov > initialMove)
 {
   var bWhite = false;

      if(curmov%2 == 1)
      {
        // white's move
        n = (curmov+1)/2;
        sMove = aMovesWhite[n];
        bWhite = true;
      }
      else
      {
        // black's move
        n = (curmov)/2;
        sMove = aMovesBlack[n];
        bWhite = false;
      }
    if (sMove == "O-O")
    {
      // castling short...
        DoMv((bWhite ? 6 : 14), (bWhite ? 60 : 4), (bWhite ? 62 : 6));
        DoMv((bWhite ? 4 : 12), (bWhite ? 63 : 7), (bWhite ? 61 : 5));
    }

    if (sMove == "O-O-O")
    {
      // castling long...
        DoMv((bWhite ? 6 : 14), (bWhite ? 60 : 4), (bWhite ? 58 : 2));
        DoMv((bWhite ? 4 : 12), (bWhite ? 56 : 0), (bWhite ? 59 : 3));
    }

    if (sMove.indexOf("O-O") < 0)
    {
      var to;
      var from;
      var piece;

      if (bWhite)
      {
        to = aFromWhite[n];
        from = GetTo(sMove, bWhite);
      }
      else
      {
        to = aFromBlack[n];
        from = GetTo(sMove, bWhite);
      }
      piece = board0[from];

      // Was it a promotion?
      if (sMove.indexOf("=") > 0)
        piece = (bWhite ? 1 : 9);

      // finally, move the piece...
      DoMv(piece, to, from);
      board0[to] = piece;

      // if it was a capture, then replace the piece back on the board...
      if (sMove.indexOf("x") > 0)
      {
         if (bWhite)
         {
           // was it a capture "en passant"?
           if (isNaN(aCapturesWhite[n]) && aCapturesWhite[n] != "" && aCapturesWhite[n] != null)
             from = aCapturesWhite[n].substr(aCapturesWhite[n].indexOf("s")+1);
           board0[from] = piece = aCapturesWhite[n];
         }
         else
         {
           if (isNaN(aCapturesBlack[n]) && aCapturesBlack[n] != "" && aCapturesBlack[n] != null)
             from = aCapturesBlack[n].substr(aCapturesBlack[n].indexOf("s")+1);
           board0[from] = piece = aCapturesBlack[n];
         }
         DrawPc(piece, from);
       }
    }
   curmov--;
 }
}

function GoMv(mv)
{
 nodraw = 1;
 if(curmov > mv)
   while(curmov > mv)
        Back();
 else
   while(curmov < mv)
        Forward();
 nodraw = 0;
 DrawBoard();
 document.frmEchiquier.game0.value = MvStr();
}

function InitSys(initMove)
{
 if (initMove == null)
   initialMove = 0;
 else
{
   initialMove = initMove;
}
 curmov = initialMove;
 FindScrBrd();
 InitBoard();
 DrawBoard();
 document.frmEchiquier.game0.value = "";
 ShowComment(0);
}

function MvStr()
{
  var n = 0;
  var sMove = "";

    if (curmov <= initialMove)
      sMove = "";
    else
      if(curmov%2 == 1)
      {
        // white's move
        n = (curmov+1)/2;
        sMove = n + ". " + aMovesWhite[n];
      }
      else
      {
        // black's move
        n = curmov/2;
        sMove = n + "... " + aMovesBlack[n];
      }

    // Afficher le commentaire dans la boîte de commentaires
    ShowComment(curmov);
    return sMove;
}

function ShowComment(n)
{
    // Premier élément du tableau est réservé pour les commentaires de début de partie...
    if (n == 0)
      document.frmEchiquier.txtComments.value = aNotesWhite[n];
    else
      if(n%2 == 1)
      {
        // white's move
        n = (n+1)/2;
        document.frmEchiquier.txtComments.value = aNotesWhite[n];
      }
      else
      {
        // black's move
        n = n/2;
        document.frmEchiquier.txtComments.value = aNotesBlack[n];
      }
}

 function TranslatePGN()
 {
    var nPosStart = 0;
    var nPosEnd = 0;
    var sPgn = "";
    var sAlgNot = "";
    var sMoveWhite = "";
    var sMoveBlack = "";
    var nStartWhite = 0;
    var nStartBlack = 0;
    var nMoveNo = 0;
    var sSpace = "";
    var bEnd = false;
    var nCount = 0;
    var nInd = 0;
    var bBlack = false;

    sPgn = document.frmEchiquier.pgn.value;
    // get rid of the carriage returns and line feed...
    nInd = 0;
    while(nInd < sPgn.length)
    {
      if((sPgn.charAt(nInd) == "\r") || (sPgn.charAt(nInd) == "\n"))
      {
        if(sPgn.charAt(nInd+1) != " ")
          sSpace = " ";
        else
          sSpace = "";
        sPgn = sPgn.substr(0, nInd) + sSpace + sPgn.substr(nInd+1);
      }
      else
        nInd++;

    }

    // remove extra blank spaces...
    sPgn = sPgn.replace("  "," ");

    while(!bEnd)
    {
      // first, extract each comment and put it in an array

      // find the position of the first "{"
      nPosStart = (sPgn.indexOf("{") < 0 ? sPgn.length : sPgn.indexOf("{"));

      if ((nPosStart == sPgn.length) && (sPgn.length <= 0 ))
        bEnd = true;
      else
      {
        // get the algebric anotation that may be contained between two comments...
        if (isNaN(sPgn.charAt(0)))
        {
          // there migth be a comment before the first move...
          nPos = -1;
        }
        else
        {
          sAlgNot = sTrim(sPgn.substring(0, nPosStart));
          nPos = sAlgNot.indexOf(".");
        }

        bBlack = sAlgNot.indexOf("...") >= 0 ;
        sAlgNot = sAlgNot.replace("  "," ");

        while (nPos >= 0)
        {
          nMoveNo = sTrim(sAlgNot.substring(0,nPos));
          if (!bBlack)
          {
            // here, the first move is for white...
            aNotesWhite[nMoveNo] = "";
            aNotesBlack[nMoveNo] = "";

            nStartWhite = sAlgNot.indexOf(" ",nPos)+1;
            sMoveWhite = sAlgNot.substring(nStartWhite, (sAlgNot.indexOf(" ",nStartWhite) < 0) ? sAlgNot.length : sAlgNot.indexOf(" ",nStartWhite));
            nStartBlack = sAlgNot.indexOf(" ",nStartWhite)+1;
            if(nStartBlack > 0)
            {
              // if there is a move after white's move
              sMoveBlack = sTrim(sAlgNot.substring(nStartBlack, (sAlgNot.indexOf(" ",nStartBlack) < 0) ? sAlgNot.length : sAlgNot.indexOf(" ",nStartBlack)));
              sAlgNot = sAlgNot.substring((sAlgNot.indexOf(" ",nStartBlack) < 0 ) ? sAlgNot.length : sAlgNot.indexOf(" ",nStartBlack)+1);
            }
            else
            {
              sAlgNot = "";
              sMoveBlack = "";
            }
          }
          else
          {
            nStartBlack = sAlgNot.indexOf(" ",nPos)+1;
            sMoveBlack = sTrim(sAlgNot.substring(nStartBlack, (sAlgNot.indexOf(" ",nStartBlack) < 0) ? sAlgNot.length : sAlgNot.indexOf(" ",nStartBlack)));
            sAlgNot = sAlgNot.substring((sAlgNot.indexOf(" ",nStartBlack) < 0 ) ? sAlgNot.length : sAlgNot.indexOf(" ",nStartBlack)+1);
          bBlack = false;
          }
          aMovesWhite[nMoveNo] = sMoveWhite;
          if (sMoveBlack != "")
            aMovesBlack[nMoveNo] = sMoveBlack;
          nPos = sAlgNot.indexOf(".");
        }
        // find the position of the first "}" if there is one...
        nPosEnd = (sPgn.indexOf("}") < 0 ? sPgn.length : sPgn.indexOf("}"));

        // extract the characters in between these delimeters to put in the array
        if(sMoveBlack == "")
          aNotesWhite[nMoveNo] = sPgn.substring(nPosStart+1, nPosEnd);
        else
          aNotesBlack[nMoveNo] = sPgn.substring(nPosStart+1, nPosEnd);

        sPgn = sTrim(sPgn.substring(nPosEnd+1, sPgn.length));
        nCount ++;
      }
    }
 }

function WriteGame()
{
    document.write("<p>" + aNotesWhite[0] + "</p>");
    document.write("<table border=0 >");
    document.write("<tr>");
    document.write("<td width=\"2%\">&nbsp;</td>");
    document.write("<td width=\"49%\"><b><u>Blancs</u></b></td>");
    document.write("<td width=\"49%\"><b><u>Noirs</u></b></td>");
    document.write("</tr>");
    for (var nInd = 1; nInd < aMovesWhite.length; nInd++)
    {
      document.write("<tr>");
      document.write("<td width=\"2%\" nowrap valign=top><b>" + nInd + ".</b></td>");
      document.write("<td width=\"49%\" nowrap valign=top><b>" + aMovesWhite[nInd] + "</b></td>");
      document.write("<td width=\"49%\" nowrap valign=top><b>" + aMovesBlack[nInd] + "</b></td>");
      document.write("</tr>");
      document.write("</tr>");
      document.write("<td>&nbsp;</td>");
      document.write("<td width=\"49%\" valign=top><i>" + aNotesWhite[nInd] + "</i></td>");
      document.write("<td width=\"49%\" valign=top><i>" + aNotesBlack[nInd] + "</i></td>");
      document.write("</tr>");

      //a bit of spacing...
      document.write("<tr>");
      document.write("<td colspan=3 >&nbsp;</td>");
      document.write("</tr>");
    }
    document.write("</table>");
}

function ConvertAlgToMv()
{
  var nInd = 1;
  var nStartFile = 0;
  var nTo = 0;
  var nFrom = 0;
  var nAdjust = 0;

 while(nInd <= aMovesWhite.length)
  {
    // get the moves...
   if (files.indexOf(aMovesWhite[nInd].charAt(0)) >= 0)
    {
      // it's a pawn move...
      // get the final position of the pawn
      nTo = ConvertAlgToPos(aMovesWhite[nInd]);

      //get the actual position of the pawn by searching backward on the file...
      nStartFile = GetStartingFileNumber(aMovesWhite[nInd].charAt(0));
      nFrom = 0;
      nAdjust = nTo + 8;
      while(nFrom == 0)
      {
        if(board0[nAdjust] != 1)
          nAdjust += 8;
        else
          nFrom = nAdjust;
      }
    }
    nInd++;
  }
}

function GetStartingFileNumber(sFile)
{
   if(sFile == 'a')
      return 56;
   if(sFile == 'b')
      return 57;
   if(sFile == 'c')
      return 58;
   if(sFile == 'd')
      return 59;
   if(sFile == 'e')
      return 60;
   if(sFile == 'f')
      return 61;
   if(sFile == 'g')
      return 62;
   if(sFile == 'h')
      return 63;
}

function ConvertAlgToPos(sAlg)
{
   // first, get rid of the bad characters...
   sAlg = GetRidOfBadChars(sAlg);

   // can this move be done by more than one piece at a time (i.e. move like R1d1)?
   if(sAlg.length >= 3)
     sAlg = sAlg.substr(1,3);

   var nReturn = (GetStartingFileNumber(sAlg.charAt(0)) - ((sAlg.charAt(1) - 1)*8));
   return nReturn;
}

function GetRidOfBadChars(sAlg)
{
      // is it a piece other than a pawn?
      if(Mypcs.toUpperCase().indexOf(sAlg.charAt(0)) > 0)
        sAlg = sAlg.substr(1);

      // is it a capture?
      if(sAlg.indexOf("x") >= 0)
        sAlg = sAlg.substr(0, sAlg.indexOf("x")) + sAlg.substr(sAlg.indexOf("x")+1);

      // is it a check?
      if(sAlg.indexOf("+") >= 0)
        sAlg = sAlg.substr(0, sAlg.indexOf("+"));

      // is it a promotion?
      if(sAlg.indexOf("=") >= 0)
        sAlg = sAlg.substr(0, sAlg.indexOf("="));

      // is it a description char?
      if(sAlg.indexOf("!") >= 0)
        sAlg = sAlg.substr(0, sAlg.indexOf("!"));
      if(sAlg.indexOf("?") >= 0)
        sAlg = sAlg.substr(0, sAlg.indexOf("?"));
      if(sAlg.indexOf("!?") >= 0)
        sAlg = sAlg.substr(0, sAlg.indexOf("!?"));
      if(sAlg.indexOf("?!") >= 0)
        sAlg = sAlg.substr(0, sAlg.indexOf("?!"));
      if(sAlg.indexOf("??") >= 0)
        sAlg = sAlg.substr(0, sAlg.indexOf("??"));
      if(sAlg.indexOf("!!") >= 0)
        sAlg = sAlg.substr(0, sAlg.indexOf("!!"));
      if(sAlg.indexOf("#") >= 0)
        sAlg = sAlg.substr(0, sAlg.indexOf("#"));

      return sAlg;
}

function GetFrom(sAlgNot, nTo, bWhite, nMove)
{
   var nFrom = 0;
   var nAdjust = 0;
   var nPiece = 0;
   var sFirstChar = "";  // char identifying the piece
   var bCapture = false; // flag identifying a capture
   var sFileRank = "";   // indicates the file or rank of a piece when a move can be done by more than one piece at a time (i.e. move like R1d1)

   // first, initialize some indentifiers
   sFirstChar = sAlgNot.charAt(0);
   bCapture = (sAlgNot.indexOf("x") > 0);

   // if this is a capture, put the captured piece in the corresponding array
   if (bCapture)
     if (bWhite)
       aCapturesWhite[nMove] = board0[nTo];
     else
       aCapturesBlack[nMove] = board0[nTo];

   // second, get rid of the bad characters...
   sAlgNot = GetRidOfBadChars(sAlgNot);

   // can this move be done by more than one piece at a time (i.e. move like R1d1)?
   if(sAlgNot.length >= 3)
     sFileRank = sAlgNot.charAt(0);

  if (files.indexOf(sFirstChar) >= 0)
    {
      // it's a pawn move...
      nPiece = (bWhite ? 1 : 9);

      // is it a capture?
      if(bCapture)
      {
        // look for the diagonal backward squares
        nAdjust = (bWhite ? nTo + 7 : nTo - 7);
        if ((board0[nAdjust] == nPiece) && (nAdjust%8 == GetStartingFileNumber(sFirstChar)%8))
          nFrom = nAdjust;
        else
          nFrom = (bWhite ? nTo + 9 : nTo - 9);

        // is a it a capture "en passant"?
        if(board0[nTo] == 0)
        {
          // simulates a move to get rid of the captured piece...
          DoMv(0, (bWhite ? nTo + 8 : nTo - 8) , nTo);

          // indicates the square of the captured piece to be able to put it back on the board if needed...
          if (bWhite)
            aCapturesWhite[nMove] = ("9s" + nTo);
          else
            aCapturesBlack[nMove] = ("1s" + nTo);
        }

      }
      else
      {
        //get the actual position of the pawn by searching backward on the file...
        nStartFile = GetStartingFileNumber(sAlgNot.charAt(0));
        nFrom = 0;
        nAdjust = (bWhite ? nTo + 8 : nTo - 8);
        while(nFrom == 0)
        {
          if(board0[nAdjust] != nPiece)
            nAdjust += (bWhite ? 8 : -8);
          else
            nFrom = nAdjust;
        }
      }
    }

    if(sFirstChar == "B")
    {
      // it's a bishop
      nPiece = (bWhite ? 3 : 11);
      //get the actual position of the bishop by searching all the squares having the same color of the target square
      nFrom = 0;
      nAdjust = nTo + (nTo%8 < 6 ? 2 : (nTo%8 == 6 ? 3 : 1));
      nAdjust = (nAdjust > 63 ? (nAdjust == 64 ? 0 : 1) : nAdjust);
      while(nFrom == 0)
      {
        if(board0[nAdjust] != nPiece)
        {
          nAdjust += (nAdjust%8 < 6 ? 2 : (nAdjust%8 == 6 ? 3 : 1));
          nAdjust = (nAdjust > 63 ? (nAdjust == 64 ? 0 : 1) : nAdjust);
        }
        else
          nFrom = nAdjust;
      }
    }

    if((sFirstChar == "Q") || (sFirstChar == "K"))
    {
      // it's the queen or the king
      nPiece = (bWhite ? (sFirstChar == "Q" ? 5 : 6) : ((sFirstChar == "Q" ? 13 : 14)));

      //get the actual position of the piece
      bFlag = true;  
      nFrom = 0;
      nAdjust = 0;
      while(bFlag)
      {
        if(board0[nAdjust] != nPiece)
        {
          nAdjust++;
        }
        else
        {
          nFrom = nAdjust;
          bFlag = false;
        }
      }
    }

    if(sFirstChar == "N")
    {
      // it's a knight

      var aAdjust = new Array(8);
      aAdjust[0] = new Array(-6,-15,10,17);
      aAdjust[1] = new Array(-6,-15,-17,10,15,17);
      aAdjust[2] = new Array(-6,-10,-15,-17,6,10,15,17);
      aAdjust[3] = new Array(-6,-10,-15,-17,6,10,15,17);
      aAdjust[4] = new Array(-6,-10,-15,-17,6,10,15,17);
      aAdjust[5] = new Array(-6,-10,-15,-17,6,10,15,17);
      aAdjust[6] = new Array(-17,-15,-10,6,15,17);
      aAdjust[7] = new Array(-17,-10,6,15);
      var nInd = 0;

      nPiece = (bWhite ? 2 : 10);

      //get the actual position of the knight
      nFrom = 0;

      while(nFrom == 0)
      {
        nAdjust = nTo + aAdjust[nTo%8][nInd];
        if ((nAdjust < 64) && (nAdjust > 0) && (!isNaN(nAdjust)))
        {
          if(board0[nAdjust] != nPiece)
          {
            nInd++;
          }
          else
          {
            nFrom = GetTrueLocation(sFileRank, nAdjust, nFrom);
            nInd++;
          }
        }
        else
            nInd++;
      }

    }

    if(sFirstChar == "R")
    {
      // it's a rook
      var nFile = -1;
      var nRank = -1;
      nPiece = (bWhite ? 4 : 12);

      //look on the same file as the target square...
      nAdjust = nTo + 8;
      while(nAdjust < 64)
      {
          if((board0[nAdjust] != nPiece) && (board0[nAdjust] == 0))
          {
            nAdjust += 8;
          }
          else
          {
              if(board0[nAdjust] == nPiece)
              {
                nFile = GetTrueLocation(sFileRank, nAdjust, nFile);
              }
            nAdjust = 64;
          }
      }
      if (nFile < 0 )
      {
        nAdjust = nTo - 8;
        while(nAdjust > -1 )
        {
            if((board0[nAdjust] != nPiece) && (board0[nAdjust] == 0))
            {
              nAdjust -= 8;
            }
            else
            {
              if(board0[nAdjust] == nPiece)
              {
                nFile = GetTrueLocation(sFileRank, nAdjust, nFile);
              }
              nAdjust = -1;
            }
        }
      }
      // now look on the same rank as the target square...
      nAdjust = nTo - 1;
      while(nAdjust >= (nTo - nTo%8))
      {
          if((board0[nAdjust] != nPiece) && (board0[nAdjust] == 0))
          {
            nAdjust--;
          }
          else
          {
              if(board0[nAdjust] == nPiece)
              {
                nRank = GetTrueLocation(sFileRank, nAdjust, nRank);
              }
            nAdjust = -1;
          }
      }
      if (nRank < 0)
      {
        nAdjust = nTo + 1;
        while(nAdjust <= (nTo - nTo%8 + 7))
        {
            if((board0[nAdjust] != nPiece) && (board0[nAdjust] == 0))
            {
              nAdjust ++;
            }
            else
            {
              if(board0[nAdjust] == nPiece)
              {
                nRank = GetTrueLocation(sFileRank, nAdjust, nRank);
              }
              nAdjust = 64;
            }
        }
      }
      nFrom = (nFile < 0 ? nRank : nFile)
    }

   return nFrom;
}

function GetTo(sAlgNot, bWhite)
{
    var nTo = ConvertAlgToPos(sAlgNot);
    return nTo;
}

function GetTrueLocation(sFileRank, nAdjust, nReturn)
{
  // have to find the proper piece in the
  // case of a move that can be done by 2 pieces...
  if ((sFileRank != "") && !isNaN(sFileRank))
  {
        if (sFileRank == (8 - (nAdjust-nAdjust%8)/8))
          nReturn = nAdjust;
  }
  else
  {
    if ((sFileRank != "") && isNaN(sFileRank))
    {
      if (nAdjust%8 == (GetStartingFileNumber(sFileRank)%8))
        nReturn = nAdjust;
    }
    else
      nReturn = nAdjust;
  }

  return nReturn;
}

function GetPromotedPiece(sMove, bWhite)
{
   var sPiece = sMove.substr(sMove.indexOf("=") + 1,1);

   if(sPiece == 'Q')
      return (bWhite ? 5 : 13);
   if(sPiece == 'R')
      return (bWhite ? 4 : 12);
   if(sPiece == 'B')
      return (bWhite ? 3 : 11);
   if(sPiece == 'K')
      return (bWhite ? 2 : 10);

}



