//
// exportable functions used to implement tic ui
//

// var TICHost = "http://tichost/";

var TICToken = "";
var TICId = "";

// array of buffers to receive results
var TICRcvBufferSerial = 0;
var TICRPCDepth = 0;
var TICRcvBuffer = new Array();
var TICMsgSerial = 0;  // use this as a monotonically increasing serial number to defeat caching by some browsers

function TICRPCStart()
{
    TICRPCDepth++;
    TICRcvBufferSerial++;
    return TICRcvBufferSerial;
}

function TICRPCDone()
{
    if( 0 == --TICRPCDepth )
    {
        TICRcvBufferSerial = 0;
    }
}

function TICReceive( s, o )
{
    TICRcvBuffer[s] = o.ResultSet.result;
}

// recursively traverse DOM from element and set the focus to the first input, select, textarea, etc.,  element
function TICFocusFirst( e, seenFocus )
{
    if( e.nodeName == "FORM" )
    {
        seenFocus = true;
    }

    //alert( "nodeName = " + e.nodeName );
    if( seenFocus && ((e.nodeName == "INPUT" && e.type != "hidden") || e.nodeName == "TEXTAREA" || e.nodeName == "SELECT" ))
    {
        //e.focus();
	if( e.select != null )
	{
	    e.select();
	}
	else
	{
	    e.focus();
	}
	return true;
    } 

    // now go through the child elements
    e = e.firstChild;
    while( e != null )
    {
        if( TICFocusFirst( e, seenFocus ) )
	{
	    return true;
	}
        e = e.nextSibling;
    }

    return false;
}

var TICRPCCallback = function(o)
{
    // alert("TICRPCCallback() after getElementById(" + o.data.domElementName + ")");

    var d = document.getElementById( o.data.domElementName );

    if( d != null )
    {
	if( d.nodeName == "TBODY" )
	{
	    // M$ IE has this bug where the innerHTML attribute on a TBODY is READ ONLY
	    // What Maroons!
	    // So now we have to do this little dance...

	    // document.writeln( "<div id='TICSherman' ><table><tbody id='TICPeabody'>" + decodeURIComponent(TICRcvBuffer[o.data.serial]) + "</tbody></table>" );

	    // var x = document.getElementById( "TICSherman" );
	    x = document.createElement("div");

	    if( x != null )
	    {
	        // x.innerHTML = "<table><tbody id='TICPeabody'>" + decodeURIComponent(TICRcvBuffer[o.data.serial]) + "</tbody></table>";
		x.innerHTML = "<table><tbody>" + decodeURIComponent(TICRcvBuffer[o.data.serial]) + "</tbody></table>";
	    }
	    else
	    {
	        alert("Unable to create div element");
		return;
	    }

	    // var donorTbody = document.getElementById("TICPeabody");
	    donorTbody = x.firstChild.firstChild;

	    if( donorTbody != null && donorTbody.nodeName == "TBODY" )
	    {
	        // remove all the children of the destination tbody node

		var c = d.firstChild;
		while( c != null )
		{
		    var n = c.nextSibling;
		    d.removeChild( c );
		    c = n;
		}
		// scan the children of peabody and append clone nodes into destination node
		c = donorTbody.firstChild;
		while( c != null )
		{
		    d.appendChild( c.cloneNode(true) );
		    c = c.nextSibling;
		}
	    }
	    else
	    {
	        alert("unable to locate the tbody element");
		return;
	    }

	    // clean up
	    if( x != null )
	    {
	        // x.innerHTML = "";
		x = null;
	    }
	}
	else
	{
	    d.innerHTML = decodeURIComponent(TICRcvBuffer[o.data.serial]);
	}

	// alert('call back' + TICRcvBuffer[o.data.serial]);

	// now traverse the 'new' DOM and set the focus to the first input element found IFF it is a form...
	TICFocusFirst(d, false);
	// also trigger onchanges...
	TICTriggerOnChange(d);
    }
    // else
    // {
    //    alert("TICRPCCallback: unable to find dom element " + o.data.domElementName );
    // }
    TICRPCDone();
}

function TICdoRPC( module, action, argv, o )
{
    TICdoRPCDiv( module, action, argv, TICFindDiv( o ) );
}

function TICdoRPCDiv( module, action, argv, domElementName )
{
    var serial = TICRPCStart();
    var url = TICHost + "TICRPC.php?TICToken=" + encodeURIComponent(TICToken) + 
    	    "&TICId=" + encodeURIComponent(TICId) + 
    	    "&module=" + encodeURIComponent(module) +
    	    "&action=" + encodeURIComponent(action) + 
	    "&callback=TICReceive" + 
	    "&serial=" + serial + 
	    "&msgSerial=" + TICMsgSerial++;

    if( argv != null )
    {
	for( var name in argv )
	{
	    url += "&" + encodeURIComponent(name) + "=" + encodeURIComponent(argv[name]);
	}
    }

    YAHOO.util.Get.script(url, { "onSuccess": TICRPCCallback, "data": { "domElementName": domElementName, "serial": serial } } );
}

var TICDivMap = new Array();
// default (initial) mapping between div names and rpc modules, can be bypassed by modules calling TICdoRPC() directly
TICDivMap["SystemDemo"] = "demo";
TICDivMap["TroopDiv"] = "troopRoster";
TICDivMap["ListScoutDiv"] = "listScout";
TICDivMap["InteractiveRoster"] = "interactiveRoster";
TICDivMap["PositionList"] = "positionList";
//TICDivMap["EditScoutDiv"] = "editScout";

function TICFindDiv( o )
{
    // start with obj. while obj is not a div and not listed in the TICDivMap move on to the parent...
    // terminate when the parent equals null or the child
    // returns the div name or empty string
    var obj = o;
    var i = 0;
    while(obj != null)
    {
	if( (obj.nodeName == "DIV") && ("" != TICDivMap[obj.id]) )
	{
	    return obj.id;
	}

	obj = obj.parentNode;
	i++;
    }
    return "";
}

// dummy function to use as a href target in an anchor where we want to use the onclick method
function TICNOOP( o )
{
    //return false;
}

// dummy function to use as an onsubmit target in a form where we want to use the onclick method
function TICFORMNOOP( o )
{
    return false;
}

function TICFindForm( o )
{
    while( o != null )
    {
        if( o.nodeName == "FORM" )
	{
	    return o;
	}
	o = o.parentNode;
    }

    return null;
}

// generic function for form cancel buttons
function TICFORMCancel( o )
{
    // find enclosing form
    var f = TICFindForm( o );

    // find cancelAction hidden input
    var a = (f.cancelAction != null ? f.cancelAction.value : "");

    // find enclosing div
    var dname = TICFindDiv( o );

    if( f != null && dname != "" && a != "" )
    {
        // start an AJAX call on the cancel action targeting the div
	TICdoRPCDiv( a, "display", null, dname );
    }
}

// generic function for form submit buttons
function TICFORMSubmit( o )
{
    // find enclosing form
    var f = TICFindForm( o );

    // find enterAction hidden input value
    var a = (f.enterAction != null ? f.enterAction.value : "" );

    // build up list of form element (INPUT, TEXTAREA, etc.) values
    var args = null;
    if( f.elements.length > 0 )
    {
	args = new Array();
        var i;
        for( i = 0; i < f.elements.length; i++ )
	{
	    var e = f.elements[i];
	    var key = null;
	    var value = null;

	    if( e.name != null && e.name != "" && e.value != null && e.disabled != true )
	    {
	        if( e.type == "checkbox" )
		{
		    // a checkbox is only present in the args if checked, value doesn't matter
		    if( e.checked )
		    {
		        // args[e.name] = "";
			key = e.name;
			value = "";
		    }
		}
		else if( e.nodeName == "SELECT" && e.multiple == true )
		{
		    var acc = "";
		    var opts = e.options;
		    var j;
		    for( j = 0; j < opts.length; j++ )
		    {
		        if( opts[j].selected == true )
			{
			    if( acc != "" )
			    {
			        acc = acc + "," + opts[j].value;
			    }
			    else
			    {
			        acc = opts[j].value;
			    }
			}
		    }
		    if( acc != "" )
		    {
		        key = e.name;
		        value = acc;
		    }
		}
		else
		{
	            // args[e.name] = e.value;
		    key = e.name;
		    value = e.value;
		}
	    }

	    if( key != null )
	    {
	        // check to see if key is already in args
		if( args[key] != null && value != "" )
		{
		    // multi select
		    args[key] = args[key] + "," + value;
		    // args[key] = value;
		}
		else
		{
		    // fresh select
		    args[key] = value;
		}
	    }

	}
    }

    // find enclosing div
    var dname = TICFindDiv( o );

    // start an AJAX call to the enter action
    if( f != null && dname != "" && a != "" )
    {
        TICdoRPCDiv( a, "enter", args, dname );
    }
}

function TICEnableDisableControls( e, state )
{
    if( e == null )
    {
        return;
    }

    if( (e.nodeName == "INPUT" && e.type != "hidden") || e.nodeName == "TEXTAREA" || e.nodeName == "SELECT" )
    {
	e.disabled = state;
	return;
    } 

    // now go through the child elements
    e = e.firstChild;
    while( e != null )
    {
        TICEnableDisableControls( e, state );
	
        e = e.nextSibling;
    }

    return false;

}

// this function checks the state of this obj (a checkbox) and sets the visibility of that obj

function TICTrack( thatObjNameOrArray, state )
{
    if( thatObjNameOrArray instanceof Array )
    {
	thatObj = document.getElementById( thatObjNameOrArray[0] );
	thatNotObj = document.getElementById( thatObjNameOrArray[1] );
    }
    else
    {
	thatObj = document.getElementById( thatObjNameOrArray );
	thatNotObj = null;
    }

    // var thatObj = document.getElementById( thatObjName );

    // gray out the text and control
    if( thatObj != null )
    {
        if( state )
	{
	    //thatObj.style.visibility = "visible";
	    thatObj.style.opacity = 1.0;
	}
	else
	{
	    //thatObj.style.visibility = "hidden";
	    thatObj.style.opacity = 0.7;
	}
    }

    if( thatNotObj != null )
    {
        if( !state )
	{
	    //thatObj.style.visibility = "visible";
	    thatNotObj.style.opacity = 1.0;
	}
	else
	{
	    //thatObj.style.visibility = "hidden";
	    thatNotObj.style.opacity = 0.7;
	}
    }

    // disable the contained control(s)
    TICEnableDisableControls( thatObj, !state );
    if( thatNotObj != null )
    {
        TICEnableDisableControls( thatNotObj, state );
    }
}

function TICCheckLastName( obj )
{
    TICdoRPCDiv( "sharedAddrOptions", "list", { last_name : obj.value }, "shared_address_control" );
}

// do the AJAX call to fill in the address portion of the edit panel
function TICFetchAddrBlock( obj )
{
    // alert("TICFetchAddrBlock entered");
    var ab = document.getElementById( "addrRow" );
    if( ab == null )
    {
        alert("Error: Unable to locate addrRow element");
	return;
    }

    // disable controls until the AJAX call returns
    TICEnableDisableControls( ab, false );
    // alert("TICFetchAddrBlock disabled controls");

    TICdoRPCDiv( "fetchAddrRow", "list", { address_id : obj.value }, "addrRow" );
    // alert("TICFetchAddrBlock ajax called");
}

// this function will be called on all HTML segments that come in from async calls
function TICTriggerOnChange( obj )
{
    if( obj.onchange != null )
    {
        //alert( "object " + obj.nodeName + " has an onchange method " + obj.onchange);
	obj.onchange();
    }
    else if( obj.type == "checkbox" && obj.onclick != null )
    {
	obj.onclick();
    }

    var e = obj.firstChild;
    while( e != null )
    {
        TICTriggerOnChange( e );
	e = e.nextSibling;
    }
}

function TICExport()
{
    var f = document.getElementById("exportForm");
    var url = TICHost + "rosterExport.csv";
    f.action = url;
    // alert(url);
    f.submit();
}

function TICinit()
{
    // alert("In TICinit()");
    // look for TIC special names in the DOM and cause them to be filled in
    for( var divName in TICDivMap )
    {
        if( null != document.getElementById(divName) )
	{
	    TICdoRPCDiv(TICDivMap[divName],"display",null,divName);
	}
    }
}

YAHOO.util.Event.onDOMReady(TICinit);

