////////////////////////////////////////////////////////////////////////
// These are Utility functions designed to solve type problems
////////////////////////////////////////////////////////////////////////
function isAlien(a) {
   return isObject(a) && typeof a.constructor != 'function';
};
function isArray(a) {
    return isObject(a) && a.constructor == Array;
};
function isBoolean(a) {
    return typeof a == 'boolean';
};
function isEmpty(o) {
    var i, v;
    if (isObject(o)) {
        for (i in o) {
            v = o[i];
            if (isUndefined(v) && isFunction(v)) {
                return false;
            }
        }
    }
    return true;
};
function isFunction(a) {
    return typeof a == 'function';
};
function isNull(a) {
    return typeof a == 'object' && !a;
};
function isNumber(a) {
    return typeof a == 'number' && isFinite(a);
};
function isObject(a) {
    return (a && typeof a == 'object') || isFunction(a);
};
function isString(a) {
    return typeof a == 'string';
};
function isUndefined(a) {
    return typeof a == 'undefined';
};





////////////////////////////////////////////////////////////////////////
// OBJECT:  OBJECT ACCESSOR
// PURPOSE: Provides a cross-platform solution for locating an object
// AUTHOR: John Loehrer
////////////////////////////////////////////////////////////////////////

/**
* Base constructor for the Object Accessor
*/
function ObjectAccessor() {}

/**
* find an object in the document. returns a reference to the object
*/
ObjectAccessor.prototype.find = function(n, d)
{
    var p,i,x;
    if (!d) d=document;
    
    if (d.getElementById) return d.getElementById(n);
    
    if ((p = n.indexOf("?")) > 0 && parent.frames.length) {
        d = parent.frames[n.substring(p+1)].document;
        n = n.substring(0,p);
    }
    if (!(x=d[n]) && d.all) x=d.all[n];
    for (i=0; !x && i < d.forms.length; i++) x=d.forms[i][n];
    for (i=0; !x && d.layers && i < d.layers.length; i++) x = this.find(n,d.layers[i].document);
    // if (!x && d.getElementById) x = d.getElementById(n);
    return x;
};

/**
* Set the value of a select box to a value
*/
ObjectAccessor.prototype.setSelectedValue = function(id, value ) 
{
    var list = this.find(id);
    if(!list) return;
    var srcLen = list.length;
    for (var i=0; i < srcLen; i++) {
        list.options[i].selected = false;
        if (list.options[i].value == value) list.options[i].selected = true;
    }
};

/**
* Set the value of a select box to a displayed name
*/
ObjectAccessor.prototype.setSelectedByName = function (id, name)
{
    var list = this.find(id);
    if(!list) return;
    var srcLen = list.length;
    for (var i=0; i < srcLen; i++) {
        list.options[i].selected = false;
        if (list.options[i].text == name) list.options[i].selected = true;
    }
};

/**
* Gets the selected value out of a select box
*/
ObjectAccessor.prototype.getSelectedValue = function(id) 
{
    var list = this.find( id );
    if(!list) return;
    var i = list.selectedIndex;
    if (i != null && i > -1) {
        return list.options[i].value;
    } else {
        return null;
    }
};

/**
* Gets the selected text out of a text box
*/
ObjectAccessor.prototype.getSelectedText = function(id) 
{
    var list = this.find(id);
    if(!list) return;
    i = list.selectedIndex;
    if (i != null && i > -1) {
        return list.options[i].text;
    } else {
        return null;
    }
};

// register a global OA
var _ObjectAccessor = new ObjectAccessor();


///////////////
// OBJECT: User Agent Detector
// PURPOSE: Provides a universal access to a single UA identifier for things such as repaint needs
//////
/*
UA function: User Agent Detection
sIFR v2.0.1 SOURCE
Copyright 2004 - 2005 Mike Davidson, Shaun Inman, Tomas Jogin and Mark Wubben
This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
*/
__UA = function() {
    var sUA = navigator.userAgent.toLowerCase();
    var oReturn =  {
        bIsWebKit : sUA.indexOf("applewebkit") > -1,
        bIsSafari : sUA.indexOf("safari") > -1,
        bIsKonq: navigator.product != null && navigator.product.toLowerCase().indexOf("konqueror") > -1,
        bIsOpera : sUA.indexOf("opera") > -1,
        bIsXML : document.contentType != null && document.contentType.indexOf("xml") > -1,
        bHasTransparencySupport : true,
        bUseDOM : true,
        nFlashVersion : null,
        nOperaVersion : null,
        nGeckoBuildDate : null,
        nWebKitVersion : null
    };
    
    oReturn.bIsKHTML = oReturn.bIsWebKit || oReturn.bIsKonq;
    oReturn.bIsGecko = !oReturn.bIsWebKit && navigator.product != null && navigator.product.toLowerCase() == "gecko";
    if(oReturn.bIsGecko){ oReturn.nGeckoBuildDate = new Number(sUA.match(new RegExp("/.*gecko\\/(\\d{8}).*/"))[1]) };
    oReturn.bIsIE = sUA.indexOf("msie") > -1 && !oReturn.bIsOpera && !oReturn.bIsKHTML && !oReturn.bIsGecko;
    oReturn.bIsIEMac = oReturn.bIsIE && sUA.match(new RegExp("/.*mac.*/")) != null;
    if(oReturn.bIsOpera){ oReturn.nOperaVersion = new Number(sUA.match(new RegExp("/.*opera(\\s|\\/)(\\d+\\.\\d+)/"))[2]) };
    if(oReturn.bIsIE || (oReturn.bIsOpera && oReturn.nOperaVersion < 7.6)){ oReturn.bUseDOM = false };
    if(oReturn.bIsWebKit){ oReturn.nWebKitVersion = new Number(sUA.match(new RegExp("/.*applewebkit\\/(\\d+).*/"))[1]) };
    if(window.hasFlash && (!oReturn.bIsIE || oReturn.bIsIEMac)){ 
        var flashDescription = (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description;
        oReturn.nFlashVersion = parseInt(flashDescription.charAt(flashDescription.indexOf(".") - 1));
    };
    if(sUA.match(/.*(windows|mac).*/) == null || 
    oReturn.bIsIEMac || oReturn.bIsKonq || 
    (oReturn.bIsOpera && oReturn.nOperaVersion < 7.6) || 
    (oReturn.bIsSafari && oReturn.nFlashVersion < 7) ||
    (!oReturn.bIsSafari && oReturn.bIsWebKit && oReturn.nWebKitVersion < 124) || 
    (oReturn.bIsGecko && oReturn.nGeckoBuildDate < 20020523)){
        oReturn.bHasTransparencySupport = false;
    };

    if(!oReturn.bIsIEMac && !oReturn.bIsGecko && document.createElementNS){
        try {
            document.createElementNS(sNameSpaceURI, "i").innerHTML = "";
        } catch(e){
            oReturn.bIsXML = true;
        };
    };
    
    oReturn.bUseInnerHTMLHack = oReturn.bIsKonq || (oReturn.bIsWebKit && oReturn.nWebKitVersion < 312) || oReturn.bIsIE;
    
    return oReturn;
};

_UserAgent = __UA();

/*
hasFlash function: Flash Detection Script
sIFR v2.0.1 SOURCE
Copyright 2004 - 2005 Mike Davidson, Shaun Inman, Tomas Jogin and Mark Wubben
This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
*/
_UserAgent.hasFlash = function(nRequiredVersion) {
    if (nRequiredVersion == null) {
		nRequiredVersion = 7;
	}
    
    if(navigator.appVersion.indexOf("MSIE") != -1 && navigator.appVersion.indexOf("Windows") > -1){
        document.write('<script language="VBScript"\> \non error resume next \nhasFlash = (IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash." & ' + nRequiredVersion + '))) \n</script\> \n');
        /*    If executed, the VBScript above checks for Flash and sets the hasFlash variable. 
            If VBScript is not supported it's value will still be undefined, so we'll run it though another test
            This will make sure even Opera identified as IE will be tested */
        if(window.hasFlash != null){
            return window.hasFlash;
        };
    };
    
    if(navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"] && navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){
        var flashDescription = (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description;
        return parseInt(flashDescription.charAt(flashDescription.indexOf(".") - 1)) >= nRequiredVersion;
    };
    
    return false;
};








////////////////////////////////////////////////////////////////////////
// OBJECT: DEBUG
// PURPOSE: Provides debugging information to the client when enabled
// AUTHOR: Jakob Heuser
////////////////////////////////////////////////////////////////////////

/**
* Debug - an object used for providing a "trace" window like in Flash
* @param bool enable when set to true, debug information will be generated (default = false)
*/
function Debug(enable)
{
    this.enable = false;
    if (enable) this.enable = true;
    
	
    this.linebreak = document.all?'<br />\n':'\n';
    this.indent = '   ';
    
    this.debugWindow = null;
};

/**
* Writes to the debug window.
* If the window does not exist or was closed, it will be reopened with the new data
* @param String message The message to write to the window
*/
Debug.prototype.write = function(message)
{

    if (!this.enable) return;

    if (this.debugWindow && this.debugWindow.open && !this.debugWindow.closed) {
        // empty
    } else {
        this.debugWindow = window.open("", "output", "width=300,innerWidth=400,height=300,innerHeight=200,resizable=1,scrollbars=1");
        this.debugWindow.document.open("text/html", "replace");
        this.debugWindow.document.write("<html><head><title>debug</title></head><body bgcolor=#000000 text=#cccccc><pre><div id=\"debug\"></div></pre></body></html>");
        this.debugWindow.document.close();
    }
    
    // have a window
    var dspace = this.debugWindow.document.getElementById('debug');
    dspace.innerHTML += message + this.linebreak ; // + this.linebreak
    try {
        this.debugWindow.focus();
    } catch (e) {} // empty catch, firefox bug
    
};

/**
* Clear the debug log.
*/
Debug.prototype.clear = function()
{
    var dspace = this.debugWindow.document.getElementById('debug');
    dspace.innerHTML = '';
};

/**
* Emulation of PHP's var_dump().  Used for capturing variable data
* @param mixed theObj the object to var_dump
* @param int depth The depth of recursion [recursion only]
* @param buffer The buffer for prefixing [recursion only]
* @return string String containing the var_dump information
*/
Debug.prototype.var_dump = function(theObj, depth, buffer)
{
    if (depth == null) depth = 0;
    if (buffer == null) buffer = '';
    
    if(isArray(theObj) || isObject(theObj)) {
        for(var p in theObj) {
            if(isArray(theObj[p]) || isObject(theObj[p])) {
                var objType = "object";
                if (isArray(theObj)) var objType = "array";
                
                buffer += this.get_var_dump_spaces(depth)+"["+p+"] => "+objType+this.linebreak;
                buffer += this.var_dump(theObj[p], depth+1);
            } else {
                buffer += this.get_var_dump_spaces(depth)+"["+p+"] => "+theObj[p]+this.linebreak;
            }
        }
    } else {
        buffer += this.get_var_dump_spaces(depth)+"("+typeof(theObj)+") = "+theObj+this.linebreak;
    }
    return buffer;
};

/**
* Generate the spaces for padding an indent
* @param int depth Number of itterations to do
* @access private
*/
Debug.prototype.get_var_dump_spaces = function(depth)
{
    if(depth == null || depth == 0) return '';
    var spaces = '';
    for (var i=0; i < depth; i++) {
        spaces += this.indent;
    }
    return spaces;
};

function escapeAll(xmldata) {
    var encodedHtml = escape(xmldata);
    encodedHtml = encodedHtml.replace(new RegExp("/\\//g"),"%2F");
    encodedHtml = encodedHtml.replace(new RegExp("/\\?/g"),"%3F");
    encodedHtml = encodedHtml.replace(new RegExp("/=/g"),"%3D");
    encodedHtml = encodedHtml.replace(new RegExp("/&/g"),"%26");
    encodedHtml = encodedHtml.replace(new RegExp("/@/g"),"%40");
    
    return encodedHtml;
}








// schedules an event to run
function schedule(objectID, functionCall)
{
    // check for OA
    if (!_ObjectAccessor) {
        setTimeout("schedule('" + objectID + "', '" + functionCall + "')", 1);
    }
    
    // break up objectID
    if (objectID.indexOf(',') == -1) {
        // single entry
        var entries = new Array(objectID);
    } else {
        var entries = objectID.split(/, ?/);
    }
    
    var check;
    for (var i=0; i<entries.length; i++) {
        check = entries[i].substring(3,entries[i].length);
        // alert(check);
        // check files, then js vars, then html ids
        if (entries[i].indexOf('fl:') != -1) {
            if ( (typeof(ch_scripts) != "object") || (ch_scripts[check] != true) ) {
                setTimeout("schedule('" + objectID + "', '" + functionCall + "')", 1);
                return;
            }
        } else if (entries[i].indexOf('js:') != -1) {
            // alert('checking js: '+entries[i].substring(3,entries[i].length));
            if ( (isUndefined(check)) || (isNull(check)) ) {
                setTimeout("schedule('" + objectID + "', '" + functionCall + "')", 1);
                return;
            }
        } else if (entries[i].indexOf('id:') != -1) {
            // alert('checking js: '+entries[i].substring(3,entries[i].length));
            if (!_ObjectAccessor.find(check)) {
                setTimeout("schedule('" + objectID + "', '" + functionCall + "')", 1);
                return;
            }
        }
    }
    
    eval(functionCall);
    return true;
}

function attatchOnLoad(funcCall) {
    if(window.attachEvent){
        window.attachEvent("onload", funcCall);
    } else if(!gfheader.ua.bIsKonq && (document.addEventListener || window.addEventListener)){
        if(document.addEventListener){
            document.addEventListener("load", funcCall, false);    
        };
        if(window.addEventListener){
            window.addEventListener("load", funcCall, false);    
        };
    } else {
        if(typeof window.onload == "function"){
            var fOld = window.onload;
            window.onload = function(){ fOld(); eval(funcCall+'();'); };
        } else {
            window.onload = funcCall;
        };
    };
}

// mouse listener
// because of gaia's interactive nature, we want to catch mouse x/y at any time.
// Set Netscape up to run the "captureMousePosition" function whenever
// the mouse is moved. For Internet Explorer and Netscape 6, you can capture
// the movement a little easier.
if (document.layers) { // Netscape
    document.captureEvents(Event.MOUSEMOVE);
    document.onmousemove = captureMousePosition;
} else if (document.all) { // Internet Explorer
    document.onmousemove = captureMousePosition;
} else if (document.getElementById) { // Netcsape 6
    document.onmousemove = captureMousePosition;
}
// Global variables
xMousePos = 0; // Horizontal position of the mouse on the screen
yMousePos = 0; // Vertical position of the mouse on the screen
xMousePosMax = 0; // Width of the page
yMousePosMax = 0; // Height of the page

function captureMousePosition(e) {
    if (document.layers) {
        // When the page scrolls in Netscape, the event's mouse position
        // reflects the absolute position on the screen. innerHight/Width
        // is the position from the top/left of the screen that the user is
        // looking at. pageX/YOffset is the amount that the user has 
        // scrolled into the page. So the values will be in relation to
        // each other as the total offsets into the page, no matter if
        // the user has scrolled or not.
        xMousePos = e.pageX;
        yMousePos = e.pageY;
        xMousePosMax = window.innerWidth+window.pageXOffset;
        yMousePosMax = window.innerHeight+window.pageYOffset;
    } else if (document.all) {
        // When the page scrolls in IE, the event's mouse position 
        // reflects the position from the top/left of the screen the 
        // user is looking at. scrollLeft/Top is the amount the user
        // has scrolled into the page. clientWidth/Height is the height/
        // width of the current page the user is looking at. So, to be
        // consistent with Netscape (above), add the scroll offsets to
        // both so we end up with an absolute value on the page, no 
        // matter if the user has scrolled or not.
        if (window.event && document.body && window.event.x && document.body.scrollLeft)
		{
	        xMousePos = window.event.x+document.body.scrollLeft
			xMousePosMax = document.body.clientWidth+document.body.scrollLeft
			yMousePos = window.event.y+document.body.scrollTop
	        yMousePosMax = document.body.clientHeight+document.body.scrollTop
		}
    } else if (document.getElementById) {
        // Netscape 6 behaves the same as Netscape 4 in this regard 
        xMousePos = e.pageX;
        yMousePos = e.pageY;
        xMousePosMax = window.innerWidth+window.pageXOffset;
        yMousePosMax = window.innerHeight+window.pageYOffset;
    }
}

function addslashes(text) {
    text += ""; // force to string
    text = text.split("\\").join("\\\\"); //slashes
    text = text.split("'").join("\\'"); // single quotes
    text = text.split('"').join('\\"'); // double quotes
    return text;
}




// constant for counting script load
if (typeof ch_scripts != 'object') ch_scripts = new Object();
ch_scripts["common.js"] = true;

var ch_scripts_n;
