var debug = true;
var chatTimer = -1;

var now = new Date();
var lastAction = now.getTime();
var updateTimeout = 5;
var timerTask = 0;

var params = new Object();
params.vars = new Object( {'state' : 'display' } );

var lastSentID = 0;         //1 is always first sent id, 0 implies none sent
var nextReceivedID = 0;

$(document).ready(function() {
    send();
    
    if( plat == 'turnplay' ) {
      $.historyInit( followhistory );
    }
});

function followhistory( hash ) {

    if( hash == '' ) {
    
      hash = 'callbacks=intro,quickmenu,footer';
    }

    var ahref = hash.replace( /^#/, '' );
    
    if( ahref.indexOf( '::' ) != -1 ) {
    
      var hrefParts = ahref.split( '::' );
      ahref = hrefParts[0];
      
      var pieces = hrefParts[1].split( '&' );
      for( var i = 0; i < pieces.length; i++ ) {
    
          var varVal = pieces[i].split( '=' );
          var variable = varVal[0];
          var val = varVal[1];
    
          params.hvars = new Object();
    
          if( variable == 'callbacks' ) {
    
              params.hcallbacks = val.split( ',' );
          } else if( variable.length > 0 ) {
          
              eval( "params.hvars." + variable + " = val;" );
          }
      }
    }

    //If preserve is not set then clear all variables!!!!!!!!
    if( ahref.indexOf( 'preserve=1' ) == -1 ) {

        params.vars = new Object( {'state' : 'display' } );
    }

    createrequest( ahref );
    delete params.hcallbacks;
    delete params.hvars;
}

function createrequest( ahref ) {

  var pieces = ahref.split( '&' );
  for( var i = 0; i < pieces.length; i++ ) {

      var varVal = pieces[i].split( '=' );
      var variable = varVal[0];
      var val = varVal[1];

      if( variable == 'callbacks' ) {

          params.callbacks = val.split( ',' );
      } else if( variable.length > 0 ) {
      
          eval( "params.vars." + variable + " = val;" );
      }
  }
  
  send( true );
}

/**
* In a valid response a few items are expected
*   areas - a key/val array of areas and their content to display
*   callbacks - an array of callbacks to be setup
*/
function response( json ) {

    if( json.vars.requestID < nextReceivedID ) {
    
      return;
    } else {
    
      nextReceivedID = json.vars.requestID;
    }

    // Sync the javascript variables with the PHP variables
    params.vars = json.vars;
    // Iterate over the set of items to display and display them if they have changed (is the check necessary?)
    $.each( json.display, function( key, val ) {

        clean( key );
        $("#"+key).each( function() { this.innerHTML = val; });
        //$( "#" + key ).html( val );
        setup( key );
    });

    // If callbacks are present then send a request out for those items (this should be unecessary, looping done in PHP)
    if( json.callbacks.length ) {

        params.callbacks = json.callbacks;
        send();
    }

    // If delayed callbacks are present setup a timeout for them
    if( json.dcallbacks.length ) {

        params.dcallbacks = json.dcallbacks;

        now = new Date();
        var lastActionDiff = (now - lastAction ) / 1000;

        if( lastActionDiff <= 60 ) updateTimeout = 10;
        else if( lastActionDiff <= 120 ) updateTimeout = 15;
        else if( lastActionDiff <= 480 ) updateTimeout = 30;
        else if( lastActionDiff <= 1680 ) updateTimeout = 60;
        else updateTimeout = 120;

        //Clear any existing timeout first!
        if( timerTask ) {
        
            window.clearTimeout( timerTask );
        }
        timerTask = window.setTimeout( delayedCallback, updateTimeout * 1000 );
    }

    // If there are javascript items to evaluate from PHP then evaluate them!
    if( json.vars.eval.length ) {

        for( var i = 0; i < json.vars.eval.length; i++ ) {  
         
            eval( json.vars.eval[i] );
        }

        params.vars.eval = Array();
    }

    bindStickyNote();

    $( "#loadbox" ).hide();
    $( "#loadbox" ).html( "Loading..." );
}

function delayedCallback() {

    if( params.dcallbacks.length ) {

        params.vars.delayedCallback = true;
        params.callbacks = params.dcallbacks;
        send();
    }
}

function clean( ident ) {

    //Cleanup click event for links
    $( '#' + ident + ' a' ).each( function() {

        $( this ).unbind( 'click' );
    });

    $( '#' + ident + ' form' ).each( function() {

        $( this ).unbind( 'submit' );
    });
}

function setup( ident ) {

    bindLinks( ident );
    bindForms( ident );
}

function bindLinks( ident ) {

    $( '#' + ident + ' a' ).click( function() {

        var ahref = $( this ).attr( 'href' );
        if( ahref.indexOf( 'callbacks=' ) != -1 ) {

            var lastSlashIndex = ahref.lastIndexOf("/");
            if (lastSlashIndex != -1) {
                ahref = ahref.substr( ( lastSlashIndex + 1 ) );
            }
           
            if( $( this ).attr( 'rel' ) != 'nohistory' && plat == 'turnplay' ) {
            
              var hash = ahref;
              if( $( this ).attr( 'rel' ) != undefined ) {
              
                hash += '::' + $( this ).attr( 'rel' );
              }
              $.historyLoad( hash );
            }
            
            //If preserve is not set then clear all variables!!!!!!!!
            if( ahref.indexOf( 'preserve=1' ) == -1 ) {

                params.vars = new Object( {'state' : 'display' } );
            }

            var pieces = ahref.split( '&' );
            for( var i = 0; i < pieces.length; i++ ) {

                var varVal = pieces[i].split( '=' );
                var variable = varVal[0];
                var val = varVal[1];

                if( variable == 'callbacks' ) {

                    params.callbacks = val.split( ',' );
                } else {
                    eval( "params.vars." + variable + " = val;" );
                }
            }
            send( true );

            return false;

        } else if( ahref.indexOf( '#' ) == 0 || 
                   ahref.indexOf( '#' ) == (ahref.length - 1) ) {

            return false;
        }
    });

}

function bindForms( ident ) {

    //Have to unbind previous events so that redudant submit handlers do not exist
    $( '#' + ident + ' form' ).submit( function() {

      //Setup proper callbacks based off the action of the form
      var ahref = jQuery( this ).attr('action');

      if( ahref.indexOf( 'callbacks=' ) != -1 ) {
        //Translate the form elements into an object
        params.vars.form = jQuery(this).formToObject();
  
  
        
        //Hack for opera as it will prepend the domain
        var lastSlashIndex = ahref.lastIndexOf( "/" );
        if( lastSlashIndex != -1 ) {
  
            ahref = ahref.substr( ( lastSlashIndex + 1 ) );
        }
  
        //Set the state of the callback to action
        params.vars.state = 'action';
  
        var pieces = ahref.split( '&' );
        for( var i = 0; i < pieces.length; i++ ) {
  
            var varVal = pieces[i].split( '=' );
            var variable = varVal[0];
            var val = varVal[1];
  
            if( variable == 'callbacks' ) {
  
                params.callbacks = val.split( ',' );
            } else {
  
                eval( "params.vars." + variable + " = val;" );
            }
        }
  
        //Send the request
        send( true );
  
        return false;
      } else if( ahref.indexOf( '#' ) != -1 ) {

        return false;
      }
    });
}

/**
* Binds anchor tags to an ajax request. To bind as an ajax request the 
* href of the anchor must being with 'callbacks=' else it will be treated
* as a normal URL.
*
* Note: forward slashes (/) are not allowed in anchor tags that are to be bound.
*/
/*function bindLinks() {

    $( 'a' ).each( function( index ) {

        var ahref = $( this ).attr( 'href' );
        if( ahref.indexOf( 'callbacks=' ) != -1 ) {

            $( this ).click( function() {

                var lastSlashIndex = ahref.lastIndexOf("/");
                if (lastSlashIndex != -1) {
                    ahref = ahref.substr( ( lastSlashIndex + 1 ) );
                }

                //If preserve is not set then clear all variables!!!!!!!!
                if( ahref.indexOf( 'preserve=1' ) == -1 ) {

                    params.vars = new Object( {'state' : 'display' } );
                }

                var pieces = ahref.split( '&' );
                for( var i = 0; i < pieces.length; i++ ) {

                    var varVal = pieces[i].split( '=' );
                    var variable = varVal[0];
                    var val = varVal[1];

                    if( variable == 'callbacks' ) {

                        params.callbacks = val.split( ',' );
                    } else {
                        eval( "params.vars." + variable + " = val;" );
                    }
                }
                send( true );

                return false;
            });
        } else if( ahref.indexOf( '#' ) != -1 ) {

            //This is done to avoid following links when the site is included within another domain
            $( this ).attr( 'href', 'javascript:void(0);' );
        }
    });
}*/

jQuery.fn.formToObject = function() {

    var inputs = new Object();
    if (this.length == 0) return a;

    var form = this[0];
    var els = form.elements;
    if (!els) return inputs;
    for(var i=0, max=els.length; i < max; i++) {
        var el = els[i];
        var n = el.name;
        if (!n) continue;

        var v = jQuery.fieldValue(el, true);
        if (v === null) continue;
        if (v.constructor == Array) {
            for(var j=0, jmax=v.length; j < jmax; j++)
                a.push({name: n, value: v[j]});
        }
        else 
            eval( "inputs = jQuery.extend( inputs, { "+n+":v } );" );
            //a.push({name: n, value: v});
    }

    return inputs;
};

function send() { send( false ); }
function send( _action ) {

    lastSentID++;

    params.vars.requestID = lastSentID;
    params.vars.isAction = _action;
    params.vars.location = document.location.href;
    var variables = { params : $.toJSON( params ) };

    $.ajax( { type      : 'POST', 
              url       : url + '/ajaxrequest.php', 
              cache     : false,
              success   : response, 
              error     : failure,
              //timeout   : 15*1000,
              data      : variables,
              dataType  : 'json'
            } );

    if( _action ) {

        $( "#loadbox" ).show();

        now = new Date();
        lastAction = now.getTime();
        //Clear any existing timeout first!
        if( timerTask ) {
        
            window.clearTimeout( timerTask );
        }
        
        /*if( params.callbacks.length > 0 ) {
          window.setTimeout( function () {
          
            urchinTracker( '/' + params.callbacks[params.callbacks.length-1] + '.html' );
          }, 1000 );
        }  */
    }
}

function failure( request, errorstring, exceptionobject ) {

    switch( errorstring ) {
      case 'parseerror':
        //Parse errors shouldn't occur unless in development, don't try to resend this.
        break;
      case 'error':
      default:
        //If the failure was on the last sent item then resend it.
        //It will only resend once as lastSentID will be incremented with the send() call
        if( nextReceivedID+1 == lastSentID ) {
          
          send();
        }
    }
}

/******************************/
function clicked_chess( event ) {

    var state = $( this ).attr( 'name' );

    if( state == 'clickable' ) {

        $( ".clickable" ).attr( 'name', '' );
        $( this ).addClass( "clicked" );
        $( ".clickable" ).removeClass( "clickable" ).addClass( "wasClickable" );
        $( this ).attr( 'name', 'clicked' );
    
    
        //Setup the possible move spots
        var myid = $( this ).attr( 'id' );
        eval( "var moves = params.vars.moves." + myid + ";" );

        $.each( moves, function( position, move ) {

            if( move.constructor.toString().indexOf( 'Array' ) != -1 ) {

                $( "#" + position ).addClass( "moveTo" ).click( function() {

                    $( '#chesspromotion' ).show();
                    $.each( move, function( index, actualMove ) {

                        piece = actualMove.charAt( actualMove.indexOf( '=' ) + 1 ).toLowerCase();
                        $( '#promote' + piece ).click( function() { 

                            //Stop double clicks (multiple move submissions
                            $( ".clickable" ).attr( 'name', '' );
                            $( ".clicked" ).attr( 'name', '' );

                            $( '#chesspromotion' ).hide();
                            $( "#gamemove" ).show();
                            $( "#loadbox" ).html( "Storing..." );
                      
                            params.vars.state = 'action';
                            params.vars.moveTo = actualMove;
                            params.vars.preserve = 1;
                            params.callbacks = new Array( event.data.callback );
                            send(true);
            
                            return false; 
                        } );
                    } );
                } );
            } else {
                var callback = event.data.callback;
                $( "#" + position ).addClass( "moveTo" ).click( function() {
                    
                    //Stop double clicks (multiple move submissions
                    $( "table.chess a" ).unbind().click( function() { return false; });
                    $( ".clickable" ).attr( 'name', '' );
                    $( ".clicked" ).attr( 'name', '' );

                    $( "#gamemove" ).show();
                    $( "#loadbox" ).html( "Storing..." );

                    $( this ).removeClass( "moveTo").addClass( "clicked" );

                    params.vars.state = 'action';
                    params.vars.moveTo = move;
                    params.vars.preserve = 1;
                    params.callbacks = new Array( callback );
                    send(true);
    
                    return false;
                } );    
            }
        });
    } else if( state == 'clicked' ) {

        $( this ).removeClass( "clicked" )
        $( ".wasClickable" ).addClass( "clickable" ).removeClass( "wasClickable" ).attr( 'name', 'clickable' );
        $( ".moveTo" ).removeClass( "moveTo" ).unbind();
        $( this ).attr( 'clickable' );
    }

    return false;
}

/******************************/
function clicked_chinese( event ) {

    var state = $( this ).attr( 'name' );

    if( state == 'clickable' ) {

        $( ".clickable" ).attr( 'name', '' );
        $( this ).addClass( "clicked" );
        $( ".clickable" ).removeClass( "clickable" ).addClass( "wasClickable" );
        $( this ).attr( 'name', 'clicked' );
    
    
        //Setup the possible move spots
        var myid = $( this ).attr( 'id' );
        //eval( "var moves = params.vars.moves." + myid + ";" );
        var moves = params.vars.moves[myid];
        $.each( moves, function( i, move ) {

            var callback = event.data.callback;
            $( "#" + move ).addClass( "moveTo" ).click( function() {
                
                //Stop double clicks (multiple move submissions
                $( "table.chinese a" ).unbind().click( function() { return false; });
                $( ".clickable" ).attr( 'name', '' );
                $( ".clicked" ).attr( 'name', '' );

                $( "#gamemove" ).show();
                $( "#loadbox" ).html( "Storing..." );

                $( this ).removeClass( "moveTo").addClass( "clicked" );

                params.vars.state = 'action';
                params.vars.moveTo = myid + move;
                params.vars.preserve = 1;
                params.callbacks = new Array( callback );
                send(true);
    
                return false;
            } );    
        });
    } else if( state == 'clicked' ) {

        $( this ).removeClass( "clicked" )
        $( ".wasClickable" ).addClass( "clickable" ).removeClass( "wasClickable" ).attr( 'name', 'clickable' );
        $( ".moveTo" ).removeClass( "moveTo" ).unbind();
        $( this ).attr( 'clickable' );
    }

    return false;
}

function clicked_checkers( event ) {

    var state = $( this ).attr( 'name' );

    if( state == 'clickable' ) {

        $( ".clickable" ).attr( 'name', '' );
        $( this ).addClass( "clicked" );
        $( ".clickable" ).removeClass( "clickable" ).addClass( "wasClickable" );
        $( this ).attr( 'name', 'clicked' );
    
    
        //Setup the possible move spots
        var myid = $( this ).attr( 'id' );
        eval( "var moves = params.vars.moves." + myid + ";" );
        setupmove_checkers( moves, event.data.callback );

    } else if( state == 'clicked' ) {

        $( ".clicked" ).removeClass( "clicked" )
        $( ".wasClickable" ).addClass( "clickable" ).removeClass( "wasClickable" ).attr( 'name', 'clickable' );
        $( ".moveTo" ).removeClass( "moveTo" ).unbind();
        $( this ).attr( 'clickable' );
    }

    return false;
}

function setupmove_checkers( moves, callback ) {

    $.each( moves, function( position, move ) {

        $( "#" + position ).addClass( "moveTo" ).click( function() {

            //More moves available
            if( move.constructor.toString().indexOf( 'Object' ) != -1 ) {
    
                $( this ).unbind().addClass( 'clicked' ).removeClass( 'moveTo' );
                setupmove_checkers( move, callback );            
            } else {
    
                //Stop double clicks (multiple move submissions
                $( "table.checkers a" ).unbind().click( function() { return false; });
                $( ".clickable" ).attr( 'name', '' );
                $( ".clicked" ).attr( 'name', '' );

                $( "#gamemove" ).show();
                $( "#loadbox" ).html( "Storing..." );

                $( this ).addClass( 'clicked' ).removeClass( 'moveTo' );

                params.vars.state = 'action';
                params.vars.moveTo = move;
                params.vars.preserve = 1;
                params.callbacks = new Array( callback );
                send(true);

                return false;
            }
        });
    });
}

function clicked_connect4( event ) {

    var state = $( this ).attr( 'name' );

    if( state == 'clickable' ) {
        
        //Stop double clicks (multiple move submissions
        $( ".clickable" ).attr( 'name', '' );

        $( "#gamemove" ).show();
        $( "#loadbox" ).html( "Storing..." );

        //Setup the possible move spots
        $( this ).addClass( 'clicked' ).removeClass( 'clickable' ).removeClass( 'moveTo' );

        var myid = $( this ).attr( 'id' );
        params.vars.state = 'action';
        params.vars.moveTo = myid;
        params.vars.preserve = 1;
        params.callbacks = new Array( event.data.callback );
        send(true);
    }

    return false;
}

function clicked_reversi( event ) {

    var state = $( this ).attr( 'name' );

    if( state == 'clickable' ) {
        
        //Stop double clicks (multiple move submissions
        $( ".clickable" ).attr( 'name', '' );

        $( "#gamemove" ).show();
        $( "#loadbox" ).html( "Storing..." );

        //Setup the possible move spots
        $( this ).addClass( 'clicked' ).removeClass( 'clickable' ).removeClass( 'moveTo' );

        var myid = $( this ).attr( 'id' );
        params.vars.state = 'action';
        params.vars.moveTo = myid;
        params.vars.preserve = 1;
        params.callbacks = new Array( event.data.callback );
        send(true);
    }

    return false;
}

function pass_reversi( plugin ) {

    var state = $( "#reversi_pass" ).attr( 'name' );

    if( state == 'passlink' ) {

        //Stop double clicks (multiple move submissions
        $( "#reversi_pass" ).attr( 'name', '' );

        $( "#gameinformation" ).hide(); // TP
        $( "#info" ).hide();            // FB
        $( "#gamemove" ).show();
        $( "#loadbox" ).html( "Storing..." );
        
        //Send pass "move"
        params.vars.state = 'action';
        params.vars.moveTo = '-';
        params.vars.preserve = 1;
        params.callbacks = new Array( plugin );
        send(true);
    }

    return false;
}

function clicked_go( event ) {

    var state = $( this ).attr( 'name' );
    var myid = $( this ).attr( 'id' );
    var imagename = $( this ).attr( 'imagename' );

    if( state == 'clickable' ) {

        //Stop double clicks (multiple move submissions
        $( ".clickable" ).attr( 'name', '' );

        $( "#gamemove" ).show();
        $( "#loadbox" ).html( "Storing..." );

        //Change moveTo css to highlite square
        var marker = ($( this ).attr( 'onmouseover' ) + "").match( 'marker' );
        if ( marker != 'marker' ) {

            marker = "";
        }

        var boardsize = ($( this ).attr( 'onmouseover' ) + "").match( 'small' );
        if ( boardsize != 'small' ) {

            boardsize = "";
        }

        $( this ).attr( 'onmouseover', '' ).attr( 'onmouseout', '' ).removeClass( 'clickable' );
        $( "#" + myid + " div" ).css( 'backgroundImage', 'url( \'./images/go/' + boardsize + 'board_rollover' + marker + '.gif\')' );

        params.vars.state = 'action';
        params.vars.moveTo = myid;
        params.vars.preserve = 1;
        params.callbacks = new Array( event.data.callback );
        send(true);

    } else if ( state == 'markable' || state == 'marked' ) {
 
        markstone_go( myid, state, imagename);

        $( "#go_markcomplete" ).show();
        $( "#go_pass" ).hide();
    }

    return false;
}

function markstone_go( myid, state, imagename ) {

    if ( state == 'markable' ) {

        $( "#" + myid ).addClass( 'marked' ).attr( 'name', 'marked' );
        var color = $( "#" + myid + " div" ).attr( 'name' );
        if ( color == 'white' ) {
            $( "#" + myid + " div" ).css( 'backgroundImage', 'url( \'./images/go/' + imagename + '_white_x.gif\')' );
        } else {
            $( "#" + myid + " div" ).css( 'backgroundImage', 'url( \'./images/go/' + imagename + '_black_x.gif\')' );
        }
        $( "#" + myid ).show();
    
     } else {
    
        $( "#" + myid ).removeClass( 'marked' ).attr( 'name', 'markable' );
        var color = $( "#" + myid + " div" ).attr( 'name' );
        if ( color == 'white' ) {
            $( "#" + myid + " div" ).css( 'backgroundImage', 'url( \'./images/go/' + imagename + '_white.gif\')' );
        } else {
            $( "#" + myid + " div" ).css( 'backgroundImage', 'url( \'./images/go/' + imagename + '_black.gif\')' );
        }
        $( "#" + myid ).show();
    }

    return false;
}


function dead_go( plugin ) {

    var state = $( "#go_markcomplete" ).attr( 'name' );

    if ( state == 'completelink' ) {

        var markedStones = $( ".marked" );
        var deadStones = new Array();

        $.each( markedStones, function( i, stoneID ) { 

            deadStones.push( $( stoneID ).attr( 'id' ) );
        });

        $( "#gamemove" ).show();
        $( "#loadbox" ).html( "Storing..." );

        //Send dead stones
        params.vars.state = 'completeMark';
        params.vars.dead = deadStones.join('');
        params.vars.preserve = 1;
        params.callbacks = new Array( plugin );
        send(true);
    }

    return false;
}


function checkscore_go( plugin ) {

    var state = $( "#go_checkscore" ).attr( 'name' );

    if ( state == 'checkscorelink' ) {

        var markedStones = $( ".marked" );
        var deadStones = new Array();

        $.each( markedStones, function( i, stoneID ) { 

            deadStones.push( $( stoneID ).attr( 'id' ) );
        });

        $( "#gamemove" ).show();
        $( "#loadbox" ).html( "Storing..." );

        //Send dead stones
        params.vars.state = 'checkScore';
        params.vars.dead = deadStones.join('');
        params.vars.preserve = 1;
        params.callbacks = new Array( plugin );
        send(true);
    }

    return false;
}


function pass_go( plugin ) {

    var state = $( "#go_pass" ).attr( 'name' );

    if( state == 'passlink' ) {

        //Stop double clicks (multiple move submissions
        $( "#go_pass" ).attr( 'name', '' );

        $( "#gameinformation" ).hide(); // TP
        //$( "#info" ).hide();            // FB
        $( "#gamemove" ).show();
        $( "#loadbox" ).html( "Storing..." );
        
        //Send pass "move"
        params.vars.state = 'action';
        params.vars.moveTo = '--';
        params.vars.preserve = 1;
        params.callbacks = new Array( plugin );
        send(true);
    }

    return false;
}

function clicked_pente( event ) {

    var state = $( this ).attr( 'name' );
    var myid = $( this ).attr( 'id' );

    if( state == 'clickable' ) {

        //Stop double clicks (multiple move submissions
        $( ".clickable" ).attr( 'name', '' );

        $( "#gamemove" ).show();
        $( "#loadbox" ).html( "Storing..." );

        //Setup the possible move spots
        var marker = ($( this ).attr( 'onmouseover' ) + "").match( 'marker' );
        if ( marker != 'marker' ) {

            marker = "";
        }

        $( this ).attr( 'onmouseover', '' ).attr( 'onmouseout', '' ).removeClass( 'clickable' );
        $( "#" + myid + " div" ).css( 'backgroundImage', 'url( \'./images/go/board_rollover' + marker + '.gif\')' );
        
        params.vars.state = 'action';
        params.vars.moveTo = myid;
        params.vars.preserve = 1;
        params.callbacks = new Array( event.data.callback );
        send(true);

    } 

    return false;
}

function clicked_oware( event ) {

  var move = $( this ).attr( 'id' );
 
  $( 'div.clickable' ).unbind().attr( 'onmouseover', '' ).attr( 'onmouseout', '' );
 
  $( '#piece_' + move ).show(); 

 
  params.vars.state = 'action';
  params.vars.moveTo = move;
  params.vars.preserve = 1;
  params.callbacks = new Array( 'oware' ); //can hardcode it as there is only 1
  send(true);
}

function clicked_backgammon( event ) {

  var state = $( this ).attr( 'name' );
  
  if( state == 'moveable' ) {

    //Change the checker image so it appears selected
    var oldSrc = $( this ).attr( 'src' );
    var newSrc = oldSrc.replace( 'checker', 'checker_selected' );
    $( this ).attr( 'name', 'selected' ).attr( 'src', newSrc );
    
    //Ensure none of the other pieces are clickable!!!
    $( "#backgammon img[name='moveable']" ).removeClass( 'clickable' ).attr( 'name', 'wasMoveable' );
    
    //Show the spots that the piece can be moved to
    var myid = $( this ).attr( 'id' );
    var moves = params.vars.moves[myid];
    $.each( moves, function( i, move ) {
    
      $( "#to" + move ).show().click( function() {

        //Unbind all the move to points so double moves cannot occur!!!
        $.each( moves, function( j, moveA ) {
        
          $( "#to" + moveA ).unbind( "click" ).hide();
        });

        $( this ).show();

        var from = parseInt( myid ) + 1;
        var to = move + 1;
        $( "#gamemove" ).show();
        $( "#loadbox" ).html( "Storing..." );

        //Setup the possible move spots
        params.vars.state = 'action';
        params.vars.moveTo = from + '/' + to;
        params.vars.preserve = 1;
        params.callbacks = new Array( 'backgammon' ); //can hardcode it as there is only 1
        send(true);
      });
    });
    
  } else if( state == 'selected' ) {
  
    //Change the image back to its original
    var oldSrc = $( this ).attr( 'src' );
    var newSrc = oldSrc.replace( 'checker_selected', 'checker' );  
    $( this ).attr( 'name', 'moveable' ).attr( 'src', newSrc );
    
    //Ensure all of the other pieces are clickable!!!
    $( "#backgammon img[name='wasMoveable']" ).addClass( 'clickable' ).attr( 'name', 'moveable' );
    
    
    var myid = $( this ).attr( 'id' );
    var moves = params.vars.moves[myid];
    $.each( moves, function( i, move ) {
    
      $( "#to" + move ).hide().unbind( 'click' );
    });
  }
}

function pass_backgammon() {

  //Setup the possible move spots
  params.vars.state = 'action';
  params.vars.moveTo = 'pass';
  params.vars.preserve = 1;
  params.callbacks = new Array( 'backgammon' );
  send(true); 
}

/*
 * This is a for tab scrolling, etc
 */

var tabIndex = 0;
var tabMax = 5;
/* $( "#tabs ul li : lt( i )" ).hide() */

function tabRight() {
    var tabs = $( "#tabs ul li a.gameTab" );
    var tabCount = tabs.size();
    tabIndex++;
    if( ( tabCount - tabIndex ) < tabMax ){

        tabIndex = tabCount - tabMax;
    }
    displayTabs( tabCount, false );
}

function tabLeft() {
    var tabs = $( "#tabs ul li a.gameTab" );
    var tabCount = tabs.size();
    tabIndex--;
    if( tabIndex < 0 ) {
        tabIndex = 0;
    }
    displayTabs( tabCount, true );
}

function tabJump( new_index ) {
    var tabs = $( "#tabs ul li.game" );
    var tabCount = tabs.size();

    tabIndex = new_index;
    if( ( tabCount - tabIndex ) < tabMax ){

        tabIndex = tabCount - tabMax;
    }
    displayTabs( tabCount, false );
}

function displayTabs( tabCount, rev ) {

    var tabs = $( "#tabs ul li.game" );

    if( !rev ) {

        for( i=0; i<tabCount; i++ ) {
            if( ( i < tabIndex ) || ( i >= ( tabIndex + tabMax ) ) ) {
                $( tabs[i] ).hide();
            } else {
                $( tabs[i] ).show();
            }
        }
    } else {

        for( i=tabCount-1; i>=0; i-- ) {
            if( ( i < tabIndex ) || ( i >= ( tabIndex + tabMax ) ) ) {
                $( tabs[i] ).hide();
            } else {
                $( tabs[i] ).show();
            }
        }
    }

    if( tabIndex == 0 ) {

        $( "#goleft" ).attr( 'src', 'images/arrow_left_disabled.gif' );
        $( "#goright" ).attr( 'src', 'images/arrow_right.gif' );
    } else if( (tabCount - tabIndex ) <= tabMax ) {

        $( "#goright" ).attr( 'src', 'images/arrow_right_disabled.gif' );
        $( "#goleft" ).attr( 'src', 'images/arrow_left.gif' );
    } else {

        $( "#goright" ).attr( 'src', 'images/arrow_right.gif' );
        $( "#goleft" ).attr( 'src', 'images/arrow_left.gif' );
    }
}

function tabClose( game_id, preserve ) {

    params.vars.state = 'close';
    params.vars.close_id = game_id;
    params.vars.preserve = preserve;
    params.callbacks = new Array( 'tabs' );
    send(true);
}

function correctPNG() {}

jQuery.fn.ajaxupload = function( options ) {

  $( this ).click( function() {

      $( '#profilesettingsstatus' ).hide();
      $( '#profilephotostatus' ).show();

      var frm = $( '#profilephotoform' ).unbind( 'submit' );

      //Get the original action/target for the form so we don't mess up anything!
      var originalAction = $( frm ).attr( 'action' );
      if( originalAction == undefined ) originalAction = '';
      var originalTarget = $( frm ).attr( 'target' );
      if( originalTarget == undefined ) originalTarget = '';

      //Point the form to the correct iframe and submit the form
      var newAction = url + '/?callbacks=profilesettings&state=submit&ajax=false';
      var newTarget = 'profilephotouploader';
      $( frm ).attr( 'action', newAction ).attr( 'target', newTarget ).submit();

      //Reset the form to point to its original action/target
      $( frm ).attr( 'action', originalAction ).attr( 'target', originalTarget );

      //Clear the input field
      //$( this ).attr( 'value', '' );

      return false;
  });
};

function fileuploaded( status ) {

    params.vars.state = 'display';
    params.vars.status = status;
    params.callbacks = new Array( 'profilesettings' );
    send(true);
}

function removeNews( newsID ) {

  params.vars.state = 'removeNews';
  params.vars.newsID = newsID;
  params.callbacks = new Array( 'userprofile' );
  send( true );
}

function viewHistory( moveNumber, callback ) {

  var scrollAmount = 0;
  $( ".movelist" ).each( function() { scrollAmount = this.scrollTop; } );

  params.vars.state        = 'viewhistory';
  params.vars.moveNumber   = moveNumber;
  params.vars.scrollAmount = scrollAmount;
  params.vars.preserve     = 1;
  params.callbacks = new Array( callback );
  send( true );
}

/**** STICKY NOTES **********/
var stickyTimer = 0;

function bindStickyNote() {

  saveSticky = false;
  
  // Support dragging and saving new position
  $( '#stickynote' ).draggable( { stop : saveStickyNote } );
                                  
  // Support saving upon editing
  $( '#stickynotetext' ).keyup( saveStickyNote );
}

function eraseStickyNote() {

  if( $( '#stickynotetext' ).val() == '' ) {
  
    return;
  }
  
  $( '#stickynotetext' ).val( '' );
  saveStickyNote();
}

function showStickyNote() {

  $( '#stickynote' ).toggle();
  saveStickyNote();

  return false;
}

function saveStickyNote() {

  if( timerTask ) {
          
    window.clearTimeout( stickyTimer );
  }
  stickyTimer = window.setTimeout( commitStickyNote, 1000 );
}

function commitStickyNote() {

  if( $( '#stickynote' ).css( 'display' ) != 'none' ) {
  
    var position = $( '#stickynote' ).position();
    params.vars.x       = position.left;
    params.vars.y       = position.top;
  }
  
  params.vars.state = 'save';
  params.vars.user_id = $( '#stickyuser' ).val();
  params.vars.key     = $( '#stickykey' ).val();

  params.vars.text    = $( '#stickynotetext' ).val();
  params.vars.display = $( '#stickynote' ).css( 'display' );
  params.vars.preserve = 1;
  params.callbacks = new Array( 'stickynote' );
  send();
}