
GFMoveManager = function(gameid)
{
    var FORMAT_PARAM    = "format";
    var currGameId      = gameid;
    var moveQueue       = new Array();

    return {
        // Makes the move to the server.
        // Handles the following:
        //
        // 1. Posts the move as a request.
        // 2. Server can return -1, 0 or 1 to indicate move failure, move
        // success or move queueing.
        // 3. The server can also crash and fail so in this case it is an
        // error and perhaps an error function needs to be called.
        // 4. If server returned a -1, moveFailure is called (with value),
        // 5. If server returns 0, moveSuccess is called (with value)
        // 6. If server returns 1, we wait and keep polling for the move to
        // finish - this is transparent to the caller.  Only moveSuccess
        // and moveFailure are called to indicate completion of the move.
        // Upto the caller to ensure code revolves around these.
        makeMove:           function(move_data, moveSuccess, moveFailure)
        {
            function moveSuccessCallback(json)
            {
                var code = json['code'];
                if (code == 1)
                {
                    alert("Move Call back returned 1 (queued).  What to do?");
                }
                else if (code < 0)
                {
                    moveFailure(json);
                }
                else
                {
                    moveSuccess(json['value']);
                }
            }

            function moveFailureCallback(json)
            {
                ajaxErrorHandler(json);
                moveFailure(-2, "System error");
            }

            // make an ajax request to the server now to save the game.
            $.ajax({
                url: '/moves/create/' + currGameId + "/?__method__=put&format=json",
                type: 'POST',
                dataType: 'json',
                data: "move_data=" + JSON.stringify(move_data),
                timeout: 60000,
                error: moveFailureCallback,
                success: moveSuccessCallback });
        },

        //
        // Fetches the result of one or more moves in a range.
        //
        // For each move the server returns:
        //
        // -1 if move index is invalid
        // 0 + move.status - if move.status is "completed", the move result
        // is also returned.
        // 1    If not allowed to view the move - ie by a different user -
        // ok in games with fogs of war.
        //
        getMove:       function(first_move_index, last_move_index,
                                resultSuccessCallback, resultFailureCallback)
        {
            if (last_move_index < first_move_index)
                return ;

            var currMoveIndex = first_move_index;

            function move_callback(json)
            {
                if (json['code'] < 0)
                {
                    resultFailureCallback(currMoveIndex, json['code'], json['value']);
                }
                else if (json['code'] == 0)
                {
                    resultSuccessCallback(currMoveIndex, json['code'], json['value']);
                }
                else
                {
                    alert("Move Status Call back returned 1.  What to do?");
                }

                currMoveIndex++;
                get_curr_move_status();
            }

            function move_failure(json)
            {
                ajaxErrorHandler(json);
                resultFailureCallback(currMoveIndex, -1, "Server error.");
                currMoveIndex++;
                get_curr_move_status();
            }

            function get_curr_move_status()
            {
                if (currMoveIndex <= last_move_index)
                {
                    // make an ajax request to the server now to save the game.
                    $.ajax({
                        url: '/moves/' + currGameId + "/" + currMoveIndex + "?format=json",
                        type: 'GET',
                        dataType: 'json',
                        timeout: 10000,
                        error: move_failure,
                        success: move_callback });
                }
            }

            get_curr_move_status();
        },

        /**
         * Does the polling till it is this caller's turn.
         * Once this is done, the callback is called.
         */
        waitForTurn: function(moveReadyCallback)
        {
            function turn_update_poll_failure(json)
            {
                // if updating failed then wait a bit longer before trying again
                // TODO: is the scope right?
                setTimeout(function wft() { waitForTurn(moveReadyCallback); }, 20000);
            }

            function turn_update_poll_success(json)
            {
                if (json['code'] == 0)
                {
                    if (json['value'].length == 0)
                    {
                        setTimeout(function wft() { waitForTurn(moveReadyCallback); }, 5000);
                    }
                    else 
                    {
                        moveReadyCallback(json['value']);
                    }
                }
                else
                {
                    alert("Error in wait for turn: " + json['code'] + " - " + json['value']);
                }
            }

            // then we start polling the server to see when our turn is!
            // make an ajax request to the server now to save the game.
            $.ajax({
                url: '/moves/' + currGameId + "?format=json",
                type: 'GET',
                dataType: 'json',
                timeout: 10000,
                error: turn_update_poll_failure ,
                success: turn_update_poll_success});
        }
    };
};

