/***************************************************************************************************
 * Copyright 2009 Thomson Reuters Global Resources.
 * All Rights Reserved.  Proprietary and confidential information of TRGR.
 * Disclosure, use, or reproduction without the written authorization of TRGR is prohibited.
 **************************************************************************************************/

/** Core functions that can be used on the client side of each page
**/

// called every time this javascript file is loaded
var cpFrame = findCheckpointFrame(window);
if(cpFrame == null){
	// if not found, this may be a popup window, so try the opener
	cpFrame = findCheckpointFrame(window.opener);
}
/**
 * Sets a variable value based on the type of browser found. Properties
 * include: nav7, nav7up, nav6, nav6up, nav5, nav4up, nav4,
 * ie6up, ie6, ie5_5up, ie5_5, ie5, ie4up, ie4
 * Will also set properties for type of operating system
 * includes: win, win95, mac
 * Example might be:
 * var is = new Is();
 * if (is.mac) { do mac specific code }
 * @return an object with various properties pertaining to the client browser environment
 */
function Is ()
{   // convert all characters to lowercase to simplify testing
	var agt=navigator.userAgent.toLowerCase()
	var app=navigator.appName.toLowerCase();

    // *** BROWSER VERSION ***
    this.major = parseInt(navigator.appVersion)

    this.nav  = ((agt.indexOf('mozilla')!=-1) && ((agt.indexOf('spoofer')==-1)
                && (agt.indexOf('compatible') == -1))) || (app.indexOf('netscape')!=-1);

	this.nav6 = (this.nav && (this.major == 5));
    this.nav6up = (this.nav && (this.major >= 5));
    this.nav5 = (this.nav && (this.major == 5));
    this.nav4up = this.nav && (this.major >= 4);
    this.nav4 = (this.nav && (this.major == 4));
    this.nav3up = this.nav && (this.major >= 3);
    this.nav3 = this.nav && (this.major == 3);
    this.nav3down = this.nav && (this.major <= 3);
	this.nav2 = this.nav && (!this.nav3up);

    this.ie   = (agt.indexOf("msie") != -1);

    this.ie6    = (this.ie && (this.major == 4) && (agt.indexOf("msie 6.")!=-1) );
    this.ie5_5  = (this.ie && (this.major == 4) && (agt.indexOf("msie 5.5") !=-1) );
    this.ie5  = (this.ie && (this.major == 4) && (agt.indexOf("msie 5.0")!=-1) );
    this.ie4  = (this.ie && (this.major == 4) && (agt.indexOf("msie 4")!=-1) );
    this.ie3 = (agt.indexOf("msie 3.") != -1);

    this.ie6up  = (this.ie && !this.ie3 && !this.ie4 && !this.ie5 && !this.ie5_5);
    this.ie5_5up =(this.ie && !this.ie3 && !this.ie4 && !this.ie5);
    this.ie5up  = (this.ie && !this.ie3 && !this.ie4);
    this.ie4up  = this.ie  && (this.major >= 4);
    this.ie3up  = this.ie  && (this.major >= 3);

    if( this.ie )
    {
		this.win = (agt.indexOf("windows") >= 1);
		this.win31 = (agt.indexOf("windows 3.1") >= 1);
		this.win95 = (agt.indexOf("windows 95") >= 1);
		this.winNT = (agt.indexOf("windows NT") >= 1);
		this.win98 = (agt.indexOf("windows 98") >= 1);
		this.mac = (agt.indexOf("mac") >= 1);
		this.mac68K = (agt.indexOf("mac_68000") >= 1);
		this.macPPC = (agt.indexOf("mac_PowerPC") >= 1);
		this.sun = (agt.indexOf("sunos") >= 1);
	}
	else
	{
		this.win = (agt.indexOf("win") >= 1);
		this.win31 = this.win && (agt.indexOf("win16") >= 1);
		this.win95 = this.win && (agt.indexOf("win95") >= 1);
		this.winNT = this.win && (agt.indexOf("winnt") >= 1);
		this.win98 = this.win && (agt.indexOf("win98") >= 1);
		this.mac = (agt.indexOf("mac") >= 1);
		this.mac68K = this.mac && (agt.indexOf("68k") >= 1);
		this.macPPC = this.mac && (agt.indexOf("ppc") >= 1);
	}

}

/**
 * Checks to make sure the value given is a digit.
 * @param ch The value to be checked.
 * @return true if the value is a digit, otherwise false
 */
function isDigit(ch)
{
    if ((ch == '0') || (ch == '1') || (ch == '2') || (ch == '3') || (ch == '4') ||
        (ch == '5') || (ch == '6') || (ch == '7') || (ch == '8') || (ch == '9')) {
        return true;
    } else {
        return false;
    }
}

/**
 * Will set the given object as the focus the browser.
 * @param FocusObject The object to gain focus.
 */
function SetFocusObject( FocusObject )
{
	var is = new Is();

	if (FocusObject != null)
	{
		if (is.nav3up)
		{
			window.focus();
		}
		FocusObject.focus();
	}
}

/**
 * Sets focus to the given text input field and selects any text within it.
 * @param textInputField a text input field within a form
 */
function setFocusAndSelectText(textInputField) {
    if (textInputField.createTextRange) {
        // Internet Explorer
        var range = textInputField.createTextRange();
        range.moveStart("character", 0);
        range.moveEnd("character", textInputField.value.length - 1);
        range.select();
    } else if (textInputField.setSelectionRange) {
        // Mozilla browsers
        textInputField.setSelectionRange(0, textInputField.value.length);
    }
    textInputField.focus();
}

/**
 * Appends the name and value pair onto the given url
 * @param url The url to append the name value pair onto.
 * @param name The name to append
 * @param value The value associated with the name to be appended
 */
function appendUrlParm( url, name, value)
{
    var insertHere = url.lastIndexOf('#');
    var beforeBookMark;
    var bookMark;
    if (insertHere > 0){
        beforeBookMark = url.substring(0, insertHere);
        bookMark = url.substring(insertHere);
    }else{
        beforeBookMark = url;
        bookMark = "";
    }
    var connector = (url.lastIndexOf('?') > 0)? "&": "?";

    url = beforeBookMark + connector + encodeUtf8(name) + "=" + encodeUtf8(value) + bookMark;
    return url
}
/**
* Use UTF-8 complient metnod to encode url value
*/
function encodeUtf8(value) {
	return encodeURIComponent(value);
}
/**
* Use UTF-8 complient metnod to decode url value
*/
function decodeUtf8(value) {
	return decodeURIComponent(value);
}
/**
 * Parse the feature from the url.
 * @param mURL the url.
 * @return the feature.
 */
function parseFeature(mURL)
{
    var feature = null;
    var featureParm = mURL.match(/feature=(\w)*/g);
    if(featureParm != null) {
        var theFeatureParm = featureParm[0].split("=");
        feature = theFeatureParm[1].trim();
    }
    return feature;
}

/**
 * Get the checkpoint frame that the given frame is contained within.
 * @param The frame to begin searching in
 * @return The frame or false if the checkpoint frame was not found
 */
function findCheckpointFrame( aFrame )
{
	if (!aFrame) {
		return null;
	}

	var checkpointFrame;
	var done = false;

	do{
		// ... looking for checkpoint's top frame
		if (aFrame.checkpointTop == true){
			return aFrame;
		}

		// not found yet, so try the parent of the current frame
		if (aFrame.parent && aFrame.parent != aFrame){
			aFrame = aFrame.parent;

		}else{
			// either the current frame did not have a parent,
			// or it was already the top frame (like a popup)
			// in which case the parent would equal the current frame
			done = true;
		}
	}
	while(!done);

	// if we got here, the frame was not found
	return null;
}

/* Navigates the top Checkpoint frameset to the given location. */
function navigateTopFrameset(url) {
    cpFrame.location = url;
    return false;
}

/**
* Checks the children windows of the frame until it finds and
* window that is not null and returns that window.
* @param currentWindow The window to check
* @param aFrame The frame in the window to check
* @return The first children window that is not null
*/
function checkChildrenWindows(currentWindow, aFrame )
{
	var win = currentWindow[aFrame];
	if (win != null) {
		return win;
	}
	if (currentWindow.frames.length > 0) {
		for (var i=0; i<currentWindow.frames.length; i++) {
            //alert(currentWindow.frames[i].name);
            win = checkChildrenWindows(currentWindow.frames[i], aFrame);
			if (win != null) {
				return win;
			}
		}
	}
	return win;
}

/**
* This method will find the descendant frame within the parent frame.
* This is the right way to find the descendant frame/windows instead
* of the code in checkChildrenWindows().
* @param parentFrame the frame to search
* @param frameName the name of the frame to search
* @return Frame/Window object or null
*/
function findChildFrame(parentFrame, frameName)
{
    var win = null;
    if (parentFrame.frames.length > 0) {
        // check first the immediate children if it has the frame with the name
        // as what's being searched.
        for(var fCount = 0; fCount < parentFrame.frames.length && win == null; fCount++)
        {
            if(parentFrame.frames[fCount].name == frameName) {
                win = parentFrame.frames[fCount];
            }
        }
        if(win == null)
        {
            // if the frame could not be found in the immediate childred of
            // the parent, recurse through the parents children.
            for (var i=0; i<parentFrame.frames.length && win == null; i++) {
                win = findChildFrame(parentFrame.frames[i], frameName);
            }
        }
    }
	return win;
}

/**
 * Get the window name that the frame is contained within
 * @param aFrame The name of the frame window
 */
function getWindowByName( aFrame )
{
	if (cpFrame == null){
		return null;
	}
	var win = null;
	if (aFrame == "_top" || aFrame == "checkpoint") {
		win = cpFrame;
	} else if (aFrame == "Details") {
		win = cpFrame.Details;
	} else if (aFrame == "mainNav") {
		win = cpFrame.mainNav;
	} else if (cpFrame.Details != null) {
		if (aFrame == "subNav") {
			win = cpFrame.Details.subNav;
		} else if (aFrame == "content") {
			win = cpFrame.Details.content;
		} else if (aFrame == "toolbar") {
            win = cpFrame.Details.content.toolbar;
        }
	}
	if (win == null) {
		win = checkChildrenWindows(cpFrame, aFrame);
	}
	return win;
}

/**
 * compute the horizontal location of a window.
 * @param windowWidth the width of the window that would be centered
 */
function computeHorizontalLocation(theWindow, windowWidth) {
	return computeLocation(theWindow.screen.width, windowWidth);
}

/**
 * compute the vertical location of a window.
 * @param windowHeight the height of the window that would be centered
 */
function computeVerticalLocation(theWindow, windowHeight) {
	return computeLocation(theWindow.screen.height, windowHeight);
}

function computeLocation(screenLocation, offset) {
	var midLocation = screenLocation / 2;
	var midOffset   = offset / 2;

	return midLocation - midOffset;
}

/** 
* Function that returns an array of values of a checkbox element in
* within the document form.  Accepts the form name.
*/ 
function getCheckBoxValues(formName) 
{
	var count = 0;
	var valueArray = new Array();
	var form = document.forms[formName];
	var allElements = form.elements;
	var totalElements = form.elements.length;
	for(var index = 0; index < totalElements; index++)
	{
		var elem = allElements[index];
		if (elem.type == "checkbox" && elem.checked) 
		{ 
			valueArray[count] = elem.value;
			count++;
		}
	}
	return valueArray;
}

function selectAll(formName) {
	var count = 0;
	var form = document.forms[formName];
	var totalElements = form.elements.length;
	var allElements = form.elements;
	var elem = null;
	for( index=0; index < totalElements; index++ )
	{
		elem = allElements[index];
	        if( !elem.checked ){
	        	elem.checked = true;
	        }
	        if (elem.type == "select-multiple") {
	        	var options = elem.options;
	        	for ( optsIndex=0; optsIndex < options.length; optsIndex++) {
	        		options[optsIndex].selected = true;
	        	}
	        }
	}
}

/**
 * Clears all checkboxes and multi-select dropdowns in a form.
 *
 * @param formName The form to clear.
 */
function clearAll(formName) {

	var count = 0;
	var form = document.forms[formName];
	var totalElements = form.elements.length;	
	var allElements = form.elements;
	var elem = null;
	for( index=0; index < totalElements; index++ ) {
		elem = allElements[index];
		
        if( elem.checked ){
        	elem.checked = false;
        }
        if (elem.type == "select-multiple") {
        	var options = elem.options;
        	for ( optsIndex=0; optsIndex < options.length; optsIndex++) {
        		options[optsIndex].selected = false;
        	}
        }
	}
}

/**
 * Clears ALL fields in a form.  
 * Useful only when resetting ALL types of fields, including text boxes.
 *
 * @param formName The form to clear.
 */
function clearForm(formName) {

	var form = document.forms[formName];
	var totalElements = form.elements.length;	
	var allElements = form.elements;
	var elem = null;
	for( index=0; index < totalElements; index++ ) {
		elem = allElements[index];
		
		// clear checkboxes & radio buttons
        if (elem.checked ){
        	elem.checked = false;
        }
        // clear all select fields
        if (elem.type == "select-multiple" || elem.type == "select-one") {
        	var options = elem.options;
        	for (optsIndex=0; optsIndex < options.length; optsIndex++) {
        		options[optsIndex].selected = false;
        	}
        }
        // clear text boxes
        if (elem.type == "text") {
        	elem.value = "";
        }
	}
	
}

// Unchecks ALL checkboxes with the given name
function uncheckAll(form, name)
{
    var totalElements = form.elements.length;
	var allElements = form.elements;
	var elem = null;
	for( index=0; index < totalElements; index++ ) {
		elem = allElements[index];

		// clear checkboxes
        if (elem.name == name){
        	elem.checked = false;
        }
	}
}

// Checks ALL checkboxes with the given name
function checkAll(form, name)
{
    var totalElements = form.elements.length;
	var allElements = form.elements;
	var elem = null;
	for( index=0; index < totalElements; index++ ) {
		elem = allElements[index];

		// clear checkboxes
        if (elem.name == name){
        	elem.checked = true;
        }
	}
}

// Checks or unchecks ALL of the checkboxes in the given form to match the state of the given checkbox
function checkOrUncheckAll(formName, checkboxName)
{
	var form = document.forms[formName];
	if (form[checkboxName].checked) {
		selectAll(formName);
	} else {
		clearAll(formName);
	}
}

// Checks or unchecks ALL of the checkboxes in the given form within the given
// range of hidden fields to match the state of the given checkbox
function checkOrUncheckGroup(form, allCheckbox, startName, endName) {
	var do_action = 0;
	for (i = 0; i < form.elements.length; i++) {
		if (form.elements[i].name == startName) {
			do_action = 1;
		}
		if (form.elements[i].name == endName) {
			do_action = 0;
		}
		if (do_action) {
			if (form.elements[i].type == "checkbox") {
				if (allCheckbox.checked) {
					form.elements[i].checked = true;
				} else {
					form.elements[i].checked = false;
				}
			}
		}
	}
}

// Checks or unchecks ALL of the checkboxes in the given form with the given
// name to match the state of the given "all" checkbox.
function checkOrUncheckGroupByName(form, allCheckbox, commonName) {
	for (i = 0; i < form.elements.length; i++) {
		if ((form.elements[i].type == "checkbox") &&
            (form.elements[i].name == commonName)) {
			if (allCheckbox.checked) {
				form.elements[i].checked = true;
			} else {
				form.elements[i].checked = false;
			}
		}
	}
}

// Un-checks the given checkbox if it's currently checked
function uncheck(thisCheckbox)
{
	if (thisCheckbox.checked) {
		thisCheckbox.checked = false;
	}
}

// Un-checks the checkbox with the given value in the given form
function uncheckByVal(form, checkboxVal)
{
	for (i = 0; i < form.elements.length; i++) {
		if ((form.elements[i].type == "checkbox") &&
			(form.elements[i].value == checkboxVal) &&
			 form.elements[i].checked) {
			form.elements[i].checked = false;
			return;
		}
	}
}


/**
 * Displays all of the properties of the given object in an alert dialog box.
 * Useful ONLY for development and debugging. Should NEVER be called in
 * production code.
 *
 * @param objectToDisplay   The object whose properties should be displayed.
 */
function displayObjectProperties(objectToDisplay)
{
    var sz = "";
    for (i in objectToDisplay)
        sz += i + ": " + objectToDisplay[i] + "\n";
    alert(sz);
}


/**
 * Attach a trim/normalized function to the String object.
 * Returns the original string with leading and trailling space
 * remove and also folds multi-space into one space.
*/
String.prototype.trim = function()
{
    var inStr = this.toString();

    // Regular expressions for normalizing white space.
    var whtSpEnds = new RegExp("^\\s*|\\s*$", "g");
    var whtSpMult = new RegExp("\\s\\s+", "g");

    inStr = inStr.replace(whtSpMult, " ");  // Collapse any multiple whites space.
    inStr = inStr.replace(whtSpEnds, "");   // Remove leading or trailing white
                                            // space.
    return inStr;
}
/**
 * Returns a string length inclusive of the CR/LF.
 * Javascript would not count this pair.
*/
String.prototype.getLengthCRLFInclusive = function()
{
    var inStr = this.toString();
    var crlf = new RegExp("\\r|\\n|\\t]", "g");
    var returnLength = this.length;

    var crlfArray = inStr.match(crlf);
    if(crlfArray && crlfArray.length) {
        returnLength += crlfArray.length;
    }
    return returnLength;
}
/**
 * Truncate string inclusive of CR/LF.
*/
String.prototype.truncateCRLFInclusive = function(truncateLength)
{
    var inStr = this.toString();
    var actualLength = this.getLengthCRLFInclusive();
    var crlfCnt = actualLength - this.length;
    if (actualLength > truncateLength) {
        inStr =  inStr.substr(0, truncateLength - crlfCnt);
    }
    return inStr;
}


String.prototype.validEmail = function() {
    var emailIsvalid   = true;
    /**
    * This method will check whether an email address is valid or not.  However, it does not
    * guarantee that the email address is legitimate.
    * For example:
    *	- junk@checkpoint.com 		===> valid email address but not legitimate
    *	- test@@westgroup.com 		===> invalid email address
    *	- joe.user@westgroup.com 	===> valid and legitimate address
    *	- juser@123.34.45.01 			===> valid but not legitimate address
    * - jane.user@westgroup.c1 	===> not valid address
    */
    var nameFilter = /^(\"?)([a-zA-Z0-9_\.\-\~\`\!\#\$\%\^\&\*\+\=\{\}\|\'\?\/]){1,64}\1\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z])+$/;
    var ipFilter   = /^(\"?)([a-zA-Z0-9_\.\-\~\`\!\#\$\%\^\&\*\+\=\{\}\|\'\?\/]){1,64}\1\@\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/;
    var emailAddresses = this.toLowerCase().split(/[;,]/);  // Multiple e-mail addresses may be separated by ; or ,
    /** check if an array was returned */
    if(emailAddresses.sort && emailAddresses.length > 0)
    {
        for(index = 0; index < emailAddresses.length && emailIsvalid; index++)
        {
            var email = emailAddresses[index];
            emailIsvalid = (nameFilter.test(email) || ipFilter.test(email)) && (email.charAt(0) != '.');
        }
    }
    else {
        /** validate the string passed in */
        emailIsvalid = (nameFilter.test(this.toLowerCase()) || ipFilter.test(this.toLowerCase())) &&
                (this.charAt(0) != '.');
    }
    return emailIsvalid;
}

var CPElement = {
        /**
          * Retrieves document (HTML DOM) elements by Id.
          * @param n number of element id as string
          * @return an arry of element found by id.
          */
        $Ids: function() {
            var elements = new Array();
            for (var i = 0; i < arguments.length; i++) {
                var element = arguments[i];
                if (typeof element == 'string') {
                    element = document.getElementById(element);
                }
                if (element)
                    elements.push(element);
            }
            return elements;
        },
        /**
          * Retrieves document (HTML DOM) elements by name.
          * @param n number of element name as string or * for all element with name attribute
          * @return an arry of element found by name.
          */
        $Names: function() {
            var elements = new Array();
            var children = document.getElementsByTagName('*') || document.all;
            if(arguments.length == 1 && (typeof arguments[0] == "string" && arguments[0] == "*")) {
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    if(child.name) elements.push(children[i]);
                }
            }
            else {
                for(var i = 0; i < arguments.length; i++) {
                    var element = arguments[i];
                    if(typeof element == 'string') {
                        for (var z = 0; z < children.length; z++) {
                            var child = children[z];
                            if(child.name && child.name == element) {
                                elements.push(child);
                            }
                        }
                    } else {
                        elements.push(element);
                    }
                }
            }
            return elements;
        },
        /**
          * Retrieves document (HTML DOM) span elements by class name.
          * @param class name as string
          * @return an arry of element found by class name.
          */
        $SpanByClassName: function(elClassName) {
            var elements = new Array();
            var children = document.getElementsByTagName('span');
            for (var z = 0; z < children.length; z++) {
                var child = children[z];
                if(child.className && child.className == elClassName) {
                    elements.push(child);
                }
            }
            return elements;
        }
}

var CPClipboard = {
        /*
            If IE, arguments[0] should be the element id that needs to be
            copied to the clipboard.  Otherwise, data is the string.
          */
        paste: function() {
            /** check for IE & MZ */
            if (window.getSelection && arguments.length > 0) {
                copy2MZClip(arguments[0]);
            } else if (window.document.body.createTextRange &&  arguments.length > 0) {
                copy2IEClip(arguments[0]);
            } else if(arguments.length > 0) {
                alert("Browser not supported.")
            }

            function copy2MZClip(data2Copy)
            {
                var clipSuccess = false;
                try
                {
                    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
                    var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
                    if (trans)
                    {
                        trans.addDataFlavor("text/html");
                        trans.addDataFlavor("text/unicode");

                        var textWrapper = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
                        var htmlWrapper = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
                        if( textWrapper && htmlWrapper )
                        {
                            // get the data
                            textWrapper.data = data2Copy;
                            htmlWrapper.data = data2Copy;

                            // set data objects to transferable
                            trans.setTransferData ( "text/html", htmlWrapper, data2Copy.length*2 );  // double byte data (len*2)
                            trans.setTransferData ( "text/unicode", textWrapper, data2Copy.length*2 );

                            var clipid = Components.interfaces.nsIClipboard;
                            var clip = Components.classes["@mozilla.org/widget/clipboard;1"].getService(clipid);
                            if (clip)
                            {
                                clip.setData(trans,null,clipid.kGlobalClipboard);
                                clipSuccess = true;
                            }
                        }
                    }
                } catch (err) {
                    showCopyErrMessage();
                }
            }

            function copy2IEClip(elementId2Copy)
            {
                /**
                * The TextRange object would always return true, even if IE security does not
                * allow copying to the clipboard.  To solve this, use the clipboardData object
                * of the window and try to write an empty string to the clipboard.  If it returns
                * true, then use the TextRange object to copy the html.  Otherwise, if you use the
                * clipboardData to copy the html to the clipboard, it would only copy plain text
                * and url (HTML formatting would be lost).
                */
                var copySuccess = window.clipboardData.setData("Text", "");
                if(copySuccess)
                {
                    var txtRange = document.body.createTextRange();
                    if(txtRange && txtRange.queryCommandEnabled("Copy") && txtRange.queryCommandSupported("Copy"))
                    {
                        var element2Copy  = document.getElementById(elementId2Copy);
                        if(element2Copy) {
                            txtRange.moveToElementText(element2Copy);
                            txtRange.execCommand("Copy");
                        } else {
                            alert("Element to be copied can't be found.")
                        }
                    } else {
                        showCopyErrMessage();
                    }
                }
                else {
                    showCopyErrMessage();
                }
            }

            function showCopyErrMessage()
            {
                alert("Your browser security settings prevents copying text to your clipboard." +
                      "\nPlease use the browser's menu to copy & paste.");
            }
        }
}

function addEvent(obj, sType, fn){
    if (obj.addEventListener){
        obj.addEventListener(sType, fn, false);
    } else if (obj.attachEvent) {
        var r = obj.attachEvent("on"+sType, fn);
    } else {
        alert("Handler could not be attached");
    }
}

function fnExist(typeofFn) {
    var hasFunction = true;
    if(typeofFn == "unknown" || typeofFn == "undefined") {
        hasFunction = false;
    }
    return hasFunction;
}

/**
 * Check if a given variable exists in the scope of the script.
 * In javascript a variable exists if it's a defined and assigne
 * a value.  Defining a variable without assigning an initial value
 * does not consider to be in existence.
 * E.g.
 * var x (not exist)
 * var x = null (exist)
 * Obviously, non-defined variable doesn't exist.
 * E.g.
 * typeof y (where y is not defined anywhere in the scope is non-existence)
 */
function exists(variable_scope) {
    return typeof variable_scope != "unknown" &&
           typeof variable_scope != "undefined";
}
        
function hasInvalidChars(textString) {
    var invalid = false;
    if (textString != null && textString.trim().length >= 0) {
        if ( textString.indexOf("<") > -1 ||
             textString.indexOf(">") > -1 ||
             textString.indexOf("&") > -1 ||
             textString.indexOf("\\") > -1 ||
             textString.indexOf("\"") > -1 ) {
            invalid = true;
        }
    }
    return invalid;
}
/**
    These 2 functions is for a bug fix specifically
    for IE 6.  If a dropdown/select tag has a label
    tag associated with it, clicking the label text
    would reset the value of the dropdown.
*/
//Set a temp expando to store the current selectedIndex
function selectLabelFocusIn() {
    if(window.event) {
        var eSrc = window.event.srcElement;
        if (eSrc)
            eSrc.tmpIndex = eSrc.selectedIndex;
    }
}
//restore the selectedIndex
function selectLabelOnFocus() {
    if(window.event) {
        var eSrc = window.event.srcElement;
        if (eSrc)
            eSrc.selectedIndex = eSrc.tmpIndex;
    }
}
// compare a key code value to the event key
function isKey(event, key) {
    // Get the implicit event object, or IE's explicit event object (window.event).
    if (!event) {
        event = window.event
    }
    // Get the charCode if defined (FireFox), or keyCode (IE)
    return key == (event.charCode ? event.charCode : event.keyCode);
}

/**
Function to get the selected value from a radio button group.
Takes the fully-qualified name of the button group as input.
*/
function getSelectedRadioValue(buttonGroup) {
   // returns the value of the selected radio button or "" if no button is selected
   var i = getSelectedRadio(buttonGroup);
   if (i == -1) {
      return "";
   } else {
      if (buttonGroup[i]) { // Make sure the button group is an array (not just one button)
         return buttonGroup[i].value;
      } else { // The button group is just the one button, and it is checked
         return buttonGroup.value;
      }
   }
}

/**
Function to get the selected item from a radio button group.
Takes the fully-qualified name of the button group as input.
Usually this will be used in conjuction with getSelectedRadioValue().
*/
function getSelectedRadio(buttonGroup) {
   // returns the array number of the selected radio button or -1 if no button is selected
   if (buttonGroup[0]) { // if the button group is an array (one button is not an array)
      for (var i=0; i<buttonGroup.length; i++) {
         if (buttonGroup[i].checked) {
            return i
         }
      }
   } else {
      if (buttonGroup.checked) { return 0; } // if the one button is checked, return zero
   }
   // if we get to this point, no radio button is selected
   return -1;
}

function colorstripe_init() {
	// Find all tables with class alternate class name
	if (!document.getElementsByTagName) return;
	tbls = document.getElementsByTagName("table");
	for (ti=0;ti<tbls.length;ti++) {
		thisTbl = tbls[ti];
		if (((' '+thisTbl.className+' ').indexOf("colorstripe") != -1) && (thisTbl.id)) {
			alternate(thisTbl);
		}
	}
}

function alternate(table) {
	// Take object table and get all it's tbodies.
	var tableBodies = table.getElementsByTagName("tbody");
	// Loop through these tbodies
	for (var i = 0; i < tableBodies.length; i++) {
		// Take the tbody, and get all it's rows
		var tableRows = tableBodies[i].getElementsByTagName("tr");
		// Loop through these rows
		// Start at 1 because we want to leave the heading row untouched
		for (var j = 0; j < tableRows.length; j++) {
			// Check if j is even, and apply classes for both possible results
			if ( (j % 2) == 0  ) {
				if ( !(tableRows[j].className.indexOf('odd') == -1) ) {
					tableRows[j].className = tableRows[j].className.replace('odd', 'even');
				} else {
					if ( tableRows[j].className.indexOf('even') == -1 ) {
						tableRows[j].className += " even";
					}
				}
			} else {
				if ( !(tableRows[j].className.indexOf('even') == -1) ) {
					tableRows[j].className = tableRows[j].className.replace('even', 'odd');
				} else {
					if ( tableRows[j].className.indexOf('odd') == -1 ) {
						tableRows[j].className += " odd";
					}
				}
			}
		}
	}
}

