// setup namespace
LLO = new Object();

LLO.IdPrefix = "";

LLO.SetIdPrefix = function( prefix )
{
	LLO.IdPrefix = prefix;
}

LLO.GetElementById = function( id )
{
	return document.getElementById( LLO.IdPrefix + id );
}

// utility functions
LLO.Util = new Object();

/******************************************************************************
*                                                                             *
*  setAttribute/getAttribute/hasAttribute                                     *
*                                                                             *
*    These functions provide cross-browser compatible methods of setting,     *
*  accessing, and checking for attributes on DOM nodes.                       *
*                                                                             *
******************************************************************************/
LLO.Util.GetAttribute = function( node, pAttr )
{
	if ( node == null )
	{
		alert( "Tried to get an attribute on a null node: " + pAttr );
		return;
	}

	if ( typeof( node.getAttribute ) != "undefined" )
		return node.getAttribute( pAttr );
	else if ( typeof( node.attributes ) != "undefined" )
		return node.attributes[pAttr].value;

	alert( "Your browser does not support retrieving attributes from DOM nodes." );
	return "";
}

LLO.Util.SetAttribute = function( node, pAttr, pVal )
{
	if ( node == null )
	{
		alert( "Tried to set an attribute on a null node: " + pAttr + ", " + pVal );
		return;
	}

	if ( typeof( node.setAttribute ) != "undefined" )
		node.setAttribute( pAttr, pVal );
	else if ( typeof( node.attributes ) != "undefined" )
		node.attributes[pAttr].value = pVal;
	else
		alert( "Your browser does not support setting attributes on DOM nodes." );
}

// TODO this may not actually work...
LLO.Util.HasAttribute = function( node, pAttr )
{
	if ( node == null )
	{
		alert( "Tried to check an attribute on a null node: " + pAttr );
		return;
	}

	if ( typeof( node.getAttribute ) != "undefined" )
	{
		var val = node.getAttribute( pAttr );
		return val != null && val != "";
	}
	else if ( typeof( node.attributes ) != "undefined" )
		node.attributes[pAttr].value != null;
	else
		alert( "Your browser does not support getting attributes from DOM nodes." );
}

LLO.Util.TrimEmptyNodes = function( root )
{
	var depth;
	if ( arguments.length < 2 )
		depth = 100;
	else
		depth = arguments[ 1 ];

	if ( depth == 0 )
		return;
	depth--;

	for ( var i = 0; i < root.childNodes.length; )
	{
		var node = root.childNodes[i];
		if ( node.nodeName == "#text" && LLO.Util.Trim( node.nodeValue ) == "" )
			root.removeChild( node );
		else
		{
			LLO.Util.TrimEmptyNodes( node, depth );
			++i;
		}
	}
}

LLO.Util.LTrim = function( str )
{
	return str.replace(/^\s+/g, "" );
}

LLO.Util.RTrim = function( str )
{
	return str.replace(/\s+$/g, "" );
}

LLO.Util.Trim = function( str )
{
	return LLO.Util.RTrim( LLO.Util.LTrim( str ) );
}

/******************************************************************************
*                                                                             *
*  XmlHttp                                                                 *
*                                                                           *
*  XmlHttp is a cross-platform wrapper that returns a valid              *
*  XmlHttpRequest regardless of what browser it is run on. (Currently tested  *
*  for IE, Firefox, and Opera)                                                *
*                                                                             *
******************************************************************************/

LLO.Util.XmlHttp = function()
{
	var xmlhttp;
	
	function Init()
	{
	    try { xmlhttp = new ActiveXObject( "Msxml3.XMLHTTP" ); }
	    catch ( exc )
	    {
		    try { xmlhttp = new ActiveXObject( "Msxml2.XMLHTTP" ); }
		    catch ( exc )
		    {
			    try { xmlhttp = new ActiveXObject( "Microsoft.XMLHTTP" ); }
			    catch ( exc )
			    {
				    try { xmlhttp = new XMLHttpRequest(); }
				    catch ( exc )
				    {
					    alert( "your browser appears not to support XmlHttpRequest" );
				    }
			    }
		    }
	    }

	    return xmlhttp;
    }
    Init();
    if (xmlhttp == null)
    {
        throw "Can't create XmlHttp object.";
    };
    
    this.Open = function(method, url, async)
    {
        xmlhttp.open(method, url, async);
    };
    
    this.Send = function(body, callback, data)
    {
    		xmlhttp.onreadystatechange = function()
		{
			if (xmlhttp.readyState == 4) //READY_STATE_COMPLETED
			{
				callback(xmlhttp, data);
			}
		};
		xmlhttp.send(body);
    };
    
	this.SetContentHeader = function(header, value)
	{
		xmlhttp.setRequestHeader(header, value);
	}    
}

LLO.Util.WebService = function(url)
{

	this.Call = function(method, params, callback)
	{
		var xmlHttp = new LLO.Util.XmlHttp();

		var completeUrl = url + "/" + method;
		var body = "";
		if (params)
		{
			for (var p in params)
			{
				if (body != "")
				{
					body += "&";
				}
				body += encodeURIComponent(p) + "=" + encodeURIComponent(params[p]);
			}
		}
		xmlHttp.Open("POST", completeUrl, true);
		xmlHttp.SetContentHeader("Content-Type", "application/x-www-form-urlencoded");
		xmlHttp.SetContentHeader("x-s-r-f", "1");
		xmlHttp.Send(body, callback);
	}	
}

LLO.Util.DeserializeDateTime = function (json)
{
    var dateObject;
    var njson = '';
    try
    {
        njson = json.replace(/\//g,'');
        dateObject = eval("new " + njson);  
    }
    catch (exception)
    {
        return null;
    }
    return dateObject;
};

LLO.Util.GetBrowserDimension = function() 
{
    var x = 0, y = 0;
    if ( typeof( window.innerWidth ) == 'number' ) 
    {
        //Non-IE
        x = window.innerWidth;
        y = window.innerHeight;
    } 
    else if ( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) 
    {
        //IE 6+ in 'standards compliant mode'
        x = document.documentElement.clientWidth;
        y = document.documentElement.clientHeight;
    } 
    else if ( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) 
    {
        //IE 4 compatible
        x = document.body.clientWidth;
        y = document.body.clientHeight;
    }
    return { x:x, y:y };
};

LLO.Util.RemoveChildrenRecursively = function(node)
{
    if (!node) return;
    while (node.hasChildNodes()) 
    {
        LLO.Util.RemoveChildrenRecursively(node.firstChild);
        node.removeChild(node.firstChild);
    }
};

LLO.Util.ParseUrlQuery = function(query)
{
    var keyValuePairs = new Array();

    if (!query)
    {
        return keyValuePairs;
    }
    
    var local = LLO.Util.Trim(query);
    if (query && local.length == 0)
    {
        return keyValuePairs;
    }

    if (local.charAt(0) == '?' && local.length > 1)
    {
        local = local.substring(1);
    }
    
    var pairs = local.split('&');
    var parsedKVP;
    
    for (i=0; i < pairs.length; i++)
    {
        parsedKVP = pairs[i].split('=');
        keyValuePairs.push({ key:parsedKVP[0], value:parsedKVP[1] });
    }
    return keyValuePairs;
};

LLO.Util.GetKeyValuePair = function(key, query)
{
    var value = null;

    if (!query)
    {
        return { key:key, value:value };
    }
    
    var local = LLO.Util.Trim(query);
    if (query && local.length == 0)
    {
        return { key:key, value:value };
    }

    if (local.charAt(0) == '?' && local.length > 1)
    {
        local = local.substring(1);
    }
    
    var pairs = local.split('&');
    var parsedKVP;
    
    for (i=0; i < pairs.length; i++)
    {
        parsedKVP = pairs[i].split('=');
        if (parsedKVP.length == 2 && parsedKVP[0] == key)
        {
            return { key:key, value:parsedKVP[1] };           
        }
    }
    return { key:value, value:value }; // key was not found either
};

LLO.Util.AttachEvent = function(obj, evCode, callback)
{
	if (obj.attachEvent)
	{
		obj.attachEvent('on' + evCode, callback);
    }
	else if (obj.addEventListener)
	{
		obj.addEventListener(evCode, callback, true);
    }
	else
	{
		obj['on' + evCode] = callback;
    }
};

LLO.Util.DetachEvent = function(obj, evCode, callback)
{
    if (obj.detachEvent)
    {
        obj.detachEvent('on' + evCode, callback);    
    }
    else if (obj.removeEventListener) 
    {
        obj.removeEventListener(evCode, callback, true);
    }
    else 
    {
		obj['on' + evCode] = null;    
    }
};

LLO.Util.GetCookie = function(name) 
{
    var cookies = document.cookie;
    var prefix = name + "=";        
    var begin = cookies.indexOf(prefix);
    
    if (begin == -1) 
    {
        return null;
    }
    else
    {
        var end = cookies.indexOf(";", (begin + prefix.length));
        if (end == -1)
        {
            end = cookies.length;
        }
        var cookieValue = cookies.substring(begin, end);
        return decodeURIComponent(cookieValue);
    } 
}


function GetNonTextChildElements(parent)
{
    var result = new Array();
    var childNodes = parent.childNodes;
    var length = childNodes.length;
    for(var i = 0; i < length; i++)
    {
        var element = childNodes[i];
        if (element && element.nodeType!=3)
        {
            result.push(element);
        }
        element = null;
    }
    
    return result;
}

function FixPng(img) 
{
    if (navigator.userAgent.toLowerCase().indexOf("msie 6") != -1)
    {
        //Image must be wrapped in a div tag so height and width can be set
        //if it's not then image might look weird, so just let it display with the gray background.
        if (img.parentNode.tagName.toLowerCase() == "div")
        {
            img.parentNode.style.width = img.offsetWidth;
            img.parentNode.style.height = img.offsetHeight;
            img.parentNode.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale src='" + img.src + "')";
            img.style.visibility = "hidden";
            img.parentNode.style.cursor = "pointer";
            
        }
    }
}