/********************
 * Global Variables *
 ********************/

var tuba_lastScrollH = 0;
var tuba_lastScrollV = 0;
var tuba_lastTextSelection = "";
var tuba_lastMouseX = -1;
var tuba_lastMouseY = -1;
var tuba_lastMouseTS = new Date();

// we only report mouse position if the mouse cursor stays at that position
// for a period of time (mouseMoveDelay in milliseonds).
var tuba_mouseMoveDelay = 2000;

xAddEventListener( window, "load", tuba_onload, false );
xAddEventListener( window, "resize", tuba_onresize, true );
window.setInterval( "tuba_onscroll()", 1000 );

xAddEventListener( document, "mouseup", tuba_onmouseup, true );
xAddEventListener( document, "mousedown", tuba_onmousedown, true );
xAddEventListener( document, "mouseover", tuba_onmouseover, true );
xAddEventListener( document, "mousemove", tuba_onmousemove, true );
xAddEventListener( document, "keypress", tuba_onkeypress, true );

/******************
 * Event Handlers *
 ******************/

function tuba_onload()
{
    tuba_lastScrollH = 0;
    tuba_lastScrollV = 0;
    tuba_lastTextSelection = "";
    tuba_lastMouseX = -1;
    tuba_lastMouseY = -1;
    tuba_lastMouseTS = new Date();
    tuba_mouseMoveDelay = 2000;

    for( var i = 0; i < document.forms.length; ++i )
    {
        for( var j = 0; j < document.forms[i].elements.length; ++j )
        {
            if( document.forms[i].elements[j].type )
            {
                var elType = document.forms[i].elements[j].type;
                if( elType == "select-one" || elType=="select-multiple" ||
                    elType=="text" || elType=="textarea" || elType=="file" ||
                    elType=="checkbox" || elType=="radio")
                {
                    xAddEventListener( document.forms[i].elements[j], "change", tuba_onchange, true );
                    xAddEventListener( document.forms[i].elements[j], "blur", tuba_onblur, true );
                    xAddEventListener( document.forms[i].elements[j], "focus", tuba_onfocus, true );
                }
            }
        }
    }
 
    tuba_log( "event=load&width=" + xClientWidth() + "&height=" + xClientHeight() );
}

function tuba_onresize()
{
    tuba_log( "event=resize&width=" + xClientWidth() + "&height=" + xClientHeight() );
}

function tuba_onscroll()
{
    var h = xScrollLeft( document );
    var v = xScrollTop( document );
    
    if( h != tuba_lastScrollH || v != tuba_lastScrollV )
    {
        tuba_lastScrollH = h;
        tuba_lastScrollV = v;
        tuba_log( "event=scroll&h=" + h + "&v=" + v );
    }
}

function tuba_onmouseup( e )
{
    var xe = new xEvent( e );
    var target = xe.target;
    var textSelection = window.getSelection ? window.getSelection() :
            document.getSelection ? document.getSelection() :
                document.selection.createRange().text;

    if( textSelection == "" && (target.type == "text" || target.type == "textarea") &&
        target.selectionStart != target.selectionEnd )
        textSelection = target.value.substring( target.selectionStart, target.selectionEnd );

    if( textSelection != "" && tuba_lastTextSelection != textSelection )
    {
        tuba_lastTextSelection = textSelection;
        tuba_log( "event=textselect&text=" + escape(textSelection) +
                  tuba_getNodeInfo(xe.target) );
    }
}

function tuba_onmousedown( e )
{
    var xe = new xEvent( e );
    var target = xe.target;

    if( target.nodeName.toLowerCase() == "select" ||
        target.nodeName.toLowerCase() == "option" ||
        target.type && target.type.toLowerCase() == "radio" ) return;

    tuba_log( "event=mousedown&button=" + xe.button +
              "&x=" + xe.offsetX + "&y=" + xe.offsetY +
              tuba_getNodeInfo(xe.target) );
}

function tuba_onmouseover( e )
{
    var xe = new xEvent( e );
    if( xe.target.href )
        tuba_log( "event=mouseover" + tuba_getNodeInfo(xe.target) );
}

function tuba_onmousemove( e )
{
    var xe = new xEvent( e );

    if( tuba_lastMouseX == -1 || tuba_lastMouseY == -1 )
    {
        tuba_lastMouseX = xe.offsetX;
        tuba_lastMouseY = xe.offsetY;
        tuba_lastMouseTS = new Date();
        return;
    }
    
    var currentTime = new Date();
    if( currentTime.getTime() - tuba_lastMouseTS.getTime() > tuba_mouseMoveDelay )
        tuba_log( "event=mousemove&x=" + tuba_lastMouseX + "&y=" + tuba_lastMouseY );
 
    tuba_lastMouseX = xe.offsetX;
    tuba_lastMouseY = xe.offsetY;
    tuba_lastMouseTS = currentTime;
}
    
function tuba_onkeypress( e )
{
    var xe = new xEvent( e );
    var keycode = xe.target.type == "password" ? 0 : xe.keyCode;
    tuba_log( "event=keypress&keycode=" + keycode + "&shift=" + xe.shiftKey +
                "&ctrl=" + xe.ctrlKey + "&alt=" + xe.altKey +
                tuba_getNodeInfo(xe.target) );
}

function tuba_onchange( e )
{
    var xe = new xEvent( e );
    var target = xe.target;

    var msg = "event=change";
    
    if( target.type == "select-multiple" )
    {
        for( var i=0 ; i < target.options.length ; ++i )
            if( target.options[i].selected)
                msg += "&selectedIndex=" + i +
                       "&selectedValue=" + escape(target.options[i].value);
    }
    
    if( target.type == "select-one" )
    {
        msg += "&selectedIndex=" + target.selectedIndex +
               "&selectedValue=" + escape(target.options[target.selectedIndex].value);
    }
    
    if( target.type == "text" || target.type == "textarea" || target.type == "file" )
    {
        msg += "&inputValue=" + target.value;
    }
    
    if( target.type == "checkbox" )
    {
        if( target.length > 1 )
            for ( i=0 ; i < target.length ; ++i )
                if( target[i].checked )  
                    msg += "&selectedIndex=" + i + "&selectedValue=" + target[i].value;
    }
    
    tuba_log( msg + tuba_getNodeInfo(target) );
}

function tuba_onfocus( e )
{
    var xe = new xEvent( e );
    tuba_log( "event=focus" + tuba_getNodeInfo(xe.target) );
}

function tuba_onblur( e )
{
    var xe = new xEvent( e );
    tuba_log( "event=blur" + tuba_getNodeInfo(xe.target) );
}

/*****************
 * Event Logging *
 *****************/

function dummy() {}

function tuba_log( msg )
{
    var params = msg + "&url=" + window.location;

    var display = xGetElementById( "tuba_display" );
    if( display ) display.innerHTML += params + "<br/>";

    var xhr = new xHttpRequest();
    xhr.send( "GET", "/tuba/EventLogger", params, null, false, false, "dummy", dummy );
}

/*********************
 * Utility Functions *
 *********************/

function tuba_getNodeInfo( node )
{
    var nodeInfo = "&nodeName=" + node.nodeName;    
    if( node.type ) nodeInfo += "&nodeType=" + node.type;
    if( node.id ) nodeInfo += "&id=" + node.id;
    if( node.name ) nodeInfo += "&name=" + node.name;

    if( node.nodeName.toLowerCase() == "img" )
    {
        nodeInfo += "&img=" + (node.src || node.href);
        if( node.parentNode.href )
          nodeInfo += "&link=" + node.parentNode.href;
    }
    
    if( node.nodeName.toLowerCase() == "a" )
        nodeInfo += "&link=" + node.href + "&linkText=" + (node.innerText || node.text);
    
    return nodeInfo;
}
