/*
#   Common functions
#
#   FUNCTIONS PROVIDED:
#       IsArray[Prototype]
#           - Determines if the given object is an array
#       IsObject[Prototype]
#           - Determines if the given object is an object
#       CountChildNodes(Element)
#           - Count the number of non-whitespace childnodes within Element
#       IsWhitespace(Text)
#           - Determines if given text is whitespace
#       HideElement(Element, Id)
#           - Sets display to none of Element or the element with an id of Id, if set.
#             Also sets display attribute.
#       ShowElement(Element, Id)
#           - Sets display to block or of display attribute of Element or element with
#             id of Id
#       ToggleDisplay(Element, Id)
#           - Either displays or hides Element or element with id of Id, depending on
#             the current display
#       SelectInputText(Element, Start, End, Id)
#           - Selects text from Start to End of Element or element with id of Id
#       Trim(Text)
#           - Removes whitespace from beginning and end of Text
#       ConvertLTGT(Text)
#           - Converts "<" and ">" to ASCII equivalents
#       UnconvertLTGT(Text)
#           - Converts ASCII equivalents to "<" and ">"
#       BreakToNewline(Text)
#           - Convert HTML breaks to new lines
#       NewlineToBreak(Text)
#           - Convert new lines to HTML breaks
#       MakeValueUsable(Value)
#           - Makes value usable in code
#       MakeValueDisplayable(Value)
#           - Makes value usable for display
#       EnableTextHighlighting
#           - Enables text highlighting for the window
#       DisableTextHighlighting
#           - Disables text highlighting for the window
#
#   Part of the Scout Portal Toolkit and based off
#       functions originally created by Tim Baumgard
#   Copyright 2004 Internet Scout Project
#   http://scout.wisc.edu
*/

function CountChildNodes(Element)
{
    // Counter for the number of children
    var NumOfChildren = 0;
    
    // Loop through each child
    for (i = 0; i < Element.childNodes.length; i++)
    {
        // If the child is not whitespace, count it
        if (Element.childNodes[i].innerHTML && IsWhitespace(Element.childNodes[i].innerHTML) === false)
        {
            NumOfChildren++;    
        }
    }
    
    return NumOfChildren;
}

function IsWhitespace(Text)
{
    if (Trim(Text) === "")
    {
        return true;
    }
    return false;
}

function HideElement(Element, Id){
    // Sets Id to false if not set
    Id = Id || false;

    // If an Id was passed instead of an element
    if (Id === true || !Element.nodeName){
        Element = new GetElement(Element);
    }

    // If the element isn't shown, exit
    if (Element.style.display == 'none'){
        return;
    }

    // Gets the current style attribute and sets it as an attribute
    Element.setAttribute("display", Element.style.display);

	// Hide the element
	Element.style.display = "none";
}

function ShowElement(Element, Id){
    // Sets Id to false if not set
    Id = Id || false;

    // If an Id was passed instead of an element
    if (Id === true || !Element.nodeName){
        Element = new GetElement(Element);
    }
	
	// If the element isn't hidden, exit
	if (Element.style.display != 'none'){
	    return;
	}
	
	// Gets any possible past display settings
	var Display = Element.getAttribute("display") ? 
	    Element.getAttribute("display") : 'block';
	
	// Show the element, using past display attribute if necessary
	if (Display === undefined || Display === ''){
	    Element.style.display = 'block';
	} else{
	    Element.style.display = Display;
	}
}

function ToggleDisplay(Element, Id){
    // Sets Id to false if not set
    Id = Id || false;

    // If an Id was passed instead of an element
    if (Id === true || !Element.nodeName){
        Element = new GetElement(Element);
    }

	// Gets any possible past display settings
	var Display = Element.getAttribute("display") ? 
	    Element.getAttribute("display") : 'block';

    // Gets the current style attribute and sets it as an attribute
    if (Element.style.display != 'none'){
        Element.setAttribute("display", Element.style.display);
    }

	// Hide or show the element
	if (Display != 'none' && Element.style.display != 'none'){
	    Element.style.display = 'none';
	} else{
	    Element.style.display = Display;
	}
}

function SelectInputText(Element, Start, End, Id){
    // Sets Id to false if not set
    Id = Id || false;

    // If an Id was passed instead of an element
    if (Id === true || typeof(Element) == "string"){
        Element = new GetElement(Element);
    }
    
    // Select the text. Depends on browser ability
    if (Element.createTextRange){
        var Range = Range.createTextRange();
        Range.moveStart('character', Element.value.length);
        Range.select();
    } else if (Element.setSelectionRange){
        Element.setSelectionRange(Start, End);
    }
    
    // Focus the element, which focuses the selection
    Element.focus();
}

function Trim(Text)
{
    return Text.replace(/^\s*|\s*$/g, "");
}

function ConvertLTGT(Text)
{
    return Text.replace(/</gi, "&lt;").replace(/>/gi, "&gt;");
}

function UnconvertLTGT(Text)
{
    return Text.replace(/&lt;/gi, "<").replace(/&gt;/gi, ">");
}

function BreakToNewline(Text)
{
    // Return converted text
    return Text.replace(/<br \/>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<br>/gi, "\n");
}

function NewlineToBreak(Text)
{
    // Return converted text
    return Text.replace(/\n/gi, "<br />");
}

function MakeValueUsable(Value)
{
    return NewlineToBreak(ConvertLTGT(Trim(String(Value))));
}

function MakeValueDisplayable(Value)
{
    return BreakToNewline(UnconvertLTGT(Trim(String(Value))));
}

function EnableTextHighlighting()
{
    var Body = document.body;
    if (typeof(Body.onselectstart) != "undefined")
    {
        Body.onselectstart = null;
    }
    else if (typeof(Body.style.MozUserSelect) != "undefined")
    {
        Body.style.MozUserSelect = null;
	}
    else
    {
	    Body.onmousedown = null;
    }
}

function DisableTextHighlighting()
{
    var Body = document.body;
    if (typeof(Body.onselectstart) != "undefined")
    {
	    Body.onselectstart = function(){return false;};
	}
    else if (typeof(Body.style.MozUserSelect) != "undefined")
    {
	    Body.style.MozUserSelect = "none";
	}
    else
    {
	    Body.onmousedown = function(){return false;};
    }
}

/*
#   Common DOM functions
#
#   FUNCTIONS PROVIDED:
#       GetElement(ElementName)
#           - Gets the element with id of ElementName
#       GetElementsByClass(Class, Node, Tag)
#           - Get all elements with class name of Class, and optionally within node Node
#             with tag of Tag
#       GetElementsByTag(Tag, Node)
#           - Get all elements with tag of Tag and optionally within node Node
#       GetNextSibling(Element, Id)
#           - Get the next non-whitespace sibling of Element or element with id of Id
#       GetElementSize(Element, Id)
#           - Get the size of Element or of element with id of Id
#       GetWindowSize
#           - Get the current size of the window
#       GetWindowOffsets
#           - Gets the left/top offsets of the window to the current scrolled area
#       GetElementPosition(Element, Id)
#           - Get the position of Element or of element with id of Id
#       GetKeyCode(Event)
#           - Gets and returns the Unicode value of the keypressed. Must supply the event.
#       GetMousePosition(Event)
#           - Gets and returns an array [X,Y] of the X/Y position of the cursor. Must supply
#             the event.
#       GetMouseOffset(Element, Event)
#           - Get the offset betweent the mouse and Element
#       SetElementPosition(Element, X, Y, Id)
#           - Sets the position of Element or of element with id of Id to (X, Y)
#   Part of the Scout Portal Toolkit and based off
#       functions originally created by Tim Baumgard
#   Copyright 2004 Internet Scout Project
#   http://scout.wisc.edu
*/
function GetElement(ElementName){
    // Depending on the broswer, return the element
    if (document.getElementById){
        return document.getElementById(ElementName);
    } else if (document.all){
        return document.all[ElementName];
    } else if (document.layers){
        return documet.layers[ElementName];
    }
}

function GetElementsByClass(Class, Node, Tag){
    // Set values if they're not set
    if (Node === null || Node === undefined){
        Node = document;
    }
    if (Tag === null || Tag === undefined){
        Tag = '*';
    }
    
    // Initialize variables
    var ClassElements = [];
    var Elements      = Node.getElementsByTagName(Tag);
    var Pattern       = new RegExp('(^|\\s)'+ Class +'(\\s|$)');
    
    // Loop through the elements. Save the ones wanted
    for (i = 0, j = 0; i < Elements.length; i++){
        if (Pattern.test(Elements[i].className) &&
            Elements[i].nodeType == 1 && Elements[i].innerHTML !== null){
                ClassElements[j] = Elements[i];
                j++;
        }
    }
    return ClassElements;
}

function GetElementsByTag(Tag, Node){
    // Set values if they're not set
    if (Node === null){
        Node = document;
    }
    
    // Get the elements
    var Elements = Node.getElementsByTagName(Tag);
    
    return Elements;
}

function GetNextSibling(Element, Id){
    // Sets Id to false if not set
    Id = Id || false;

    // If an Id was passed instead of an element
    if (Id === true || !Element.nodeName){
        Element = new GetElement(Element);
    }
    
    // Loops through siblings, skipping whitespace
    while (Element.nodeType != 1){
        Element = Element.nextSibling;
    }
    
    // Return the sibling
    return Element;
}

function GetElementSize(Element, Id){
    // Sets Id to false if not set
    Id = Id || false;

    // If an Id was passed instead of an element
    if (Id === true || !Element.nodeName){
        Element = new GetElement(Element);
    }

    return {Height:Element.offsetHeight,
            Width:Element.offsetWidth};
}

function GetWindowSize()
{
    if (self.innerWidth)
    {
        return {Height:self.innerHeight, Width:self.innerWidth};
    }
    else
    {
        return {Height:document.body.clientHeight, Width:document.body.clientWidth};
    }
}

function GetWindowOffsets()
{
    if (window.innerHeight)
    {
        return {X:window.pageXOffset, Y:window.pageYOffset};
    }
    else if (document.documentElement && document.documentElement.scrollTop)
    {
        return {X:document.documentElement.scrollLeft, Y:document.documentElement.scrollTop};
    }
    else (document.body)
    {
        return {X:document.body.scrollLeft, Y:document.body.scrollTop};
    }
}

function GetElementPosition(Element, Id){
    // Sets Id to false if not set
    Id = Id || false;

    // If an Id was passed instead of an element
    if (Id === true || !Element.nodeName){
        Element = new GetElement(Element);
    }

    // Return the position, if available
    if (Element.offsetParent){
        var Top  = Element.offsetTop;
        var Left = Element.offsetLeft;
        while (Element = Element.offsetParent){
            Top  += Element.offsetTop;
            Left += Element.offsetLeft;
        }
        return {Top:Top, Left:Left};
    }
    
    // Else return (0,0)
    return {Top:0, Left:0};
}

function GetKeyCode(Event){
    // Get the proper event
    Event = Event || window.event;
    
    // Return the proper key code
	if (Event.keyCode){
	    KeyCode = Event.keyCode;
        return Event.keyCode;
	}
	else if (Event.which){
	    KeyCode = Event.which;
        return Event.which;
	}
}

function GetMousePosition(Event){
    // Get the proper event
	Event = Event || window.event;

    // Return the proper position, or (0,0)
	if (Event.pageX || Event.pageY){
		return {X:Event.pageX, Y:Event.pageY};
	} else if (Event.clientX || Event.clientY){
		return {X:Event.clientX + document.body.scrollLeft
		        + document.documentElement.scrollLeft,
		        Y:Event.clientY + document.body.scrollTop
			    + document.documentElement.scrollTop};
	} else{
	    return {X:0, Y:0};
	}
}

function GetMouseOffset(Element, Event)
{
    Event = Event || window.event;
    var ElementPosition = GetElementPosition(Element);
    var MousePosition = GetMousePosition(Event);
    return {X:MousePosition.X - ElementPosition.Left,
        Y:MousePosition.Y - ElementPosition.Top};
}

function SetElementPosition(Element, X, Y, Id){
    // Sets Id to false if not set
    Id = Id || false;

    // If an Id was passed instead of an element
    if (Id === true || !Element.nodeName){
        Element = new GetElement(Element);
    }

    // Set the position of the element    
    Element.style.left = (X * 1) + "px";
    Element.style.top  = (Y * 1) + "px";
}


/*
#   Common XML-like attribute functions
#
#   FUNCTIONS PROVIDED:
#       GetAttribute(Element, Attr)
#           - Get the specified attribute Attr from Element
#       GetAttributes(Element)
#           - Get all attributes from Element
#       SetAttribute(Element, Attr, NewValue)
#           - Set attribute Attr of Element to NewValue
#
#   Part of the Scout Portal Toolkit
#   Copyright 2004 Internet Scout Project
#   http://scout.wisc.edu
*/
function GetAttribute(Element, Attr)
{
    return UnconvertLTGT(GetElement(Element.id + "_Attr").innerHTML);
}

function GetAttributes(Element)
{        
    // Initialize the Attr variable to an empty array
    var Attr = [];
       
    // Get the attribute layer using the prefix and place in AttrLayer
    var AttrLayer = new GetElement(Element.id + "_Attr");

    // For every sibling, take the class name, use it as a key in the Attr array and use its HTML as the value
    for (i = 0; i < AttrLayer.childNodes.length; i++)
    {
       Attr[AttrLayer.childNodes[i].id.replace(Element.id+"_", "")] = UnconvertLTGT(AttrLayer.childNodes[i].innerHTML);
    }

    // Return the Attr array
    return Attr;
}

function SetAttribute(Element, Attr, NewValue)
{
    GetElement(Element.id + "_" + Attr).innerHTML = ConvertLTGT(NewValue);
}


/*
#   Common AJAX functions
#
#   FUNCTIONS PROVIDED:
#       CreateRequestObject
#           - Creates and returns a browser-specific request object
#       SendRequest(FileName, Actions, ResponseFunction)
#           - Sends an AJAX request to FileName with the GET actions in Actions. 
#             It then calls ResponseFunction with the response as a parameter
#
#   Part of the Scout Portal Toolkit
#   Copyright 2004 Internet Scout Project
#   http://scout.wisc.edu
*/

// Necessary variables
var CurrentDate = ""; // Prevents button-mashing bug in Firefox
var http = [];
var undefined;

function CreateRequestObject()
{
    var RequestObject;
    var Browser = navigator.appName;
    if (Browser == "Microsoft Internet Explorer")
    {
        RequestObject = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else
    {
        RequestObject = new XMLHttpRequest();
    }
    return RequestObject;
}

function SendAJAXRequest(FileName, Parameters, ResponseFunction) 
{
    CurrentDate = new Date(); // To update the date
    http[CurrentDate] = new CreateRequestObject();
    
    // In case an object was passed to hold parameters
    if (typeof(Parameters) == "object")
    {
        var TempParameters = "";
        for (var i in Parameters)
        {
            TempParameters += i + "=" + Parameters[i] + "&";
        }
        Parameters = TempParameters;
    }
    
    http[CurrentDate].open('get', FileName+'?'+Parameters);
    http[CurrentDate].onreadystatechange = function()
        {
            if(http[CurrentDate].readyState == 4)
            {
                var Response = http[CurrentDate].responseText;
                return ResponseFunction(Response);
            }
        };
    http[CurrentDate].send(null);
}