// $Id: network.js,v 1.17 2009/09/13 02:10:52 cross Exp $

var convertIndexToFile = ["a","b","c","d","e","f","g","h"];
function convertFileToIndex(file)  {  return "abcdefgh".indexOf(file);  }

/**
 * only good for chess
 */
var trimMatch = "pabcdefgh12345678qrnk"; // p most likely
function chessTrim(str)
{
    var buf = "";
    var k = 0;
    while (k < str.length)
    {
        var c = str.charAt(k);
        if (-1 != trimMatch.indexOf(c))
        {
            buf = buf.concat(c);
        }
        k = k + 1;
    }
    return buf;
} // chessTrim

var depth = 2;
var playerIsWhite = true;
var oldMove = "";
var replyFile = "games/" + sessionid + "reply.txt";
var lineFile  = "games/" + sessionid + "line.txt";
var queryPollTimer = new PollTimer(queryMove, 0);
var queryReply = null;

function computerFirst()
{
    playerIsWhite = false;
    postMove(0,0,0,0,""); // irrelevant what is passed
    return;
} // computerFirst

var makeMoveFirstTime = true;
function postMove(file, rank, oldFile, oldRank, promotion)
{
//  uncomment for movement testing
//  return;
    enableWhitePlayer(false);
    enableBlackPlayer(false);
    var move = escape(convertIndexToFile[oldFile] + (oldRank+1) +
                      convertIndexToFile[file] + (rank+1)) + promotion;
    var pmove = "&chmove=" + move;
    var indicator = playerIsWhite ? "bottommoveindicator" : "topmoveindicator";
    document.getElementById(indicator).innerHTML = move;
    var thinking = (!playerIsWhite) ? "bottommoveindicator" : "topmoveindicator";
    document.getElementById(thinking).innerHTML = "thinking ...";

    if (makeMoveFirstTime)
    {
        var pds = document.getElementById("plydepthselection");
        depth = pds.options[pds.selectedIndex].value;
        pds.disabled = true;

        pds = document.getElementById("computer");
        pds.disabled = true;

        document.getElementById("gtr_ut").disabled = true;
        document.getElementById("gtr_st").disabled = true;
        document.getElementById("gtr_b5").disabled = true;
        document.getElementById("gtr_l1").disabled = true;
        document.getElementById("gtr_ud").disabled = true;
        document.getElementById("gtr_time").disabled = true;
        timeEntryField.disabled = true;

        makeMoveFirstTime = false;
        if (!playerIsWhite) // computer is white and moves first
        {
            document.getElementById(indicator).innerHTML = "";
            pmove = "";
        }
    }
    var post = "sessionid=" + escape(sessionid) + pmove +
               "&plydepth=" + escape(depth);
    xmlhttpPost("trmit.php", post);
    setTimeout("firstqueryMove();",100);
    return;
} // postMove

function firstqueryMove()
{    
    queryMove();
    queryPollTimer.restart();
} 

function queryMove()
{
    try
    {
        queryReply = null;
        queryReply = getHttpRequest();
        queryReply.open('POST', replyFile, true);
        queryReply.onreadystatechange = getQueryReply;
        queryReply.send(null);
    } catch (e) { /* ignore */ }
    return;
} // queryMove

function getQueryReply()
{
    try
    {
        if ((4 == queryReply.readyState) && (200 == queryReply.status))
        {
            konatamove = queryReply.responseText;
            // parse konatamove to remove <pre> tag
            konatamove = konatamove.replace('<pre>\n', '');
            konatamove = konatamove.replace('\n</pre>', '');
            konatamove = konatamove.substr(konatamove.length - 6, 5).toLowerCase();
            konatamove = chessTrim(konatamove);
            if (konatamove != oldMove)
            {

                oldMove = konatamove;
                queryPollTimer.stop();
                queryReply.open("POST", lineFile, false);
	        queryReply.onreadystatechange = null;
                queryReply.send(null); // note we give some time for the response
                var indicator = playerIsWhite ? "topmoveindicator" : "bottommoveindicator";
                document.getElementById(indicator).innerHTML = konatamove;
                setReplyMove(konatamove);
                enableWhitePlayer(playerIsWhite);
                enableBlackPlayer(!playerIsWhite);

                document.getElementById("gamerecord").innerHTML = queryReply.responseText;
                queryReply = null; // gc
                return;
            }
        }
    } catch (e) { /* ignore */ }
    return;
} // getQueryReply

function setReplyMove(simpleMove)
{
    var promotion = (5 == simpleMove.length);

    var f = convertFileToIndex(simpleMove.charAt(0));
    var r = parseInt(simpleMove.charAt(1)) - 1;
    var piece = getPiece(f, r);
    if (promotion)
    {
        setPromotion(piece, simpleMove.charAt(4));
	    piece = getPiece(f, r); // must getPiece again for promotion
    }

    f = convertFileToIndex(simpleMove.charAt(2));
    r = parseInt(simpleMove.charAt(3)) - 1;
    var capturePiece = getPiece(f, r);

    // check for castle; rank/color is irrelevant here
    if ((piece instanceof King) && (2 == Math.abs(piece.file - f)))
    {
        // 2 is queen side
        var ff  = (2 == f) ? 0 : 7;
        var rook = getPiece(ff, r);

        ff = (2 == f) ? 3 : 5; // the moved to ff
        setPositionFR(rook.element, ff, r);
        rook.setMove(ff, r);
    }

    // check for en passant; we just set a new capturePiece
    // Pawn, empty, diagonal - color, rank irrelevant
    if ((piece instanceof Pawn) && !capturePiece &&
        (Math.abs(piece.file - f) == Math.abs(piece.rank - r)))
    {
        // piece.file - f = -1 for white; +1 for black
        var ff  = f + (piece.file - f); // behind pawn
        capturePiece = getPiece(ff, r); // same rank
    }
    if (capturePiece)
    {
        capturePiece.element.hide();
    }
    setPositionFR(piece.element, f, r);
    piece.setMove(f, r);
    return;
} // setReplyMove

function setPromotion(piece, lastChar)
{
    var abcd = "abcd";
    var rnbq = "rnbq";
    var index = abcd.charAt(rnbq.indexOf(lastChar));

    index = index + (piece.isWhite() ? "w" : "b") + lastChar; // ex: "awr"
    var oldZornImage = dd.elements[index];
    oldZornImage.copy();
    var newZornImage = oldZornImage.copies[oldZornImage.copies.length - 1];
    if ("q" == lastChar)
    {
        np = promote(new Queen(newZornImage, piece.file, piece.rank,
                          piece.color, piece.myKing));
    }
    else if ("n" == lastChar)
    {
        np = promote(new Knight(newZornImage, piece.file, piece.rank,
                           piece.color, piece.myKing));
    }
    else if ("b" == lastChar)
    {
        np = promote(new Bishop(newZornImage, piece.file, piece.rank,
                           piece.color, piece.myKing));
    }
    else // r
    {
        np = promote(new Rook(newZornImage, piece.file, piece.rank,
                         piece.color, piece.myKing));
    }
    newZornImage.myPiece = np;
    piece.element.hide();
    piece.element.myPiece = null;
    piece.element = null;
    piece = null; // gc
    np.element.show();
    setPositionFR(np.element, np.file, np.rank);
    return;
} // setPromotion

function xmlhttpPost(urlString, queryString) 
{
    var xmlHttpReq = null;
    try
    {
        xmlHttpReq = getHttpRequest();
        xmlHttpReq.open('POST', urlString, true);
        xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlHttpReq.send(queryString);
        xmlHttpReq.onreadystatechange = function()  {  /* ignore */  }
    }
    finally
    {
        xmlHttpReq = null; // gc
    }
    return;
} // xmlhttpPost

/**
 * @return false if impossible, otherwise the request object
 */
function getHttpRequest()
{
    if (window.XMLHttpRequest)
    {
        return new XMLHttpRequest();
    }
    else if(window.ActiveXObject)
    {
        try
        {
            return new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch(e)
        {
            try
            {
                return new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch(e){}
        }
    }
    alert("Giving up :( Cannot create an XMLHTTP instance");
    return false;
} // getHttpRequest


function examineTimeField(id)
{
    var textField = document.getElementById(id);
    var str = textField.value;
    var len = str.length;
    var index = 0;
    var minutes = false;
    while (index < len)
    {
        var x = str.charAt(index);
        if (":" == x)  {  minutes = true;  }
        if (":" != x)
        {
            if (isNaN(x))
            {
                textField.value = str.substr(0, index) + str.substring(index+1, len);
                examineTextField(id);
                return;
            }
        }
        index++;
    } // while

    var h = 0 + parseInt(str);
    var m = 0;
    if (!minutes)
    {
        if (h < 60)
        {
            m = h;
            h = 0;
        }
        else
        {
            var t = h;
            h = Math.floor(t / 60);
            m = t % 60;
        }
    }
    else /* hh:mm pattern */
    {
        var M = str.substring(str.indexOf(":")+1, str.length);
        m = parseInt(M);
        if (m > 59)  {  m = 59;  }
        if (1 == M.length)  {  m = m*10;  }
    }
    textField.value = h.toString(10) + ":" + ((m > 9) ? m.toString(10) : "0" + m.toString(10));
    return;
} // examineTimeField


