/**
 * Developed by James Munroe
 */
 
/** 
 * Object.create is a design pattern courtesy of Douglas Crockford, www.crockford.com (senior JavaScript architect at Yahoo!
 * and author of RFC 4627 which describes the JSON format), that takes an existing object as a parameter
 * and returns a derived object.
 * Although there are other methods of doing this, this pattern avoids polluting the global namespace and also
 * doesn't clobber an Object.create() method inadvertently created by someone else.
 */
if(typeof Object.create !== 'function') {
    Object.create = function(o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

var GoVenture = {
    name: 'GoVenture',
    Toolkit: {
        name : 'GoVenture.Toolkit',
        isIE : Boolean(navigator.appName.indexOf('Microsoft') > -1),
        alert : function(str) {alert(this.name);},
        getElementsByTagLike : function() {
            var tagname = arguments[0];
            var regexpStr = arguments[1];
            var parentElem = document;
            if(arguments.length > 2) {
                parentElem = arguments[2];
            }
            var elements = [];
            var oNodeList = parentElem.getElementsByTagName(tagname);
            for(var i = 0; i < oNodeList.length; i++) {
                elements.push(oNodeList[i]);
            }
            var regex = new RegExp(regexpStr);
            for(var i = 0; i < elements.length; i++) {
                var elem = elements[i];
                if(!regex.test(elem.id)) {
                    elements.splice(i, 1);
                    --i;
                }
            }
            return elements;
        },

        /**
         * following method def is based on getElementsByClassName v.101 developed by Robert Nyman, http://www.robertnyman.com
         * Code/licensing: http://code.google.com/p/getelementsbyclassname/
         **************************************************
         * Usage
         *************************************************
         * How to call it and parameters
         * Parameters

         * className
         *     One or several class names, separated by space. Multiple class names demands that each match have all of the classes  * specified. Mandatory.
         * tag
         *     Specifies the tag name of the elements to match. Optional.
         * elm
         *     Reference to a DOM element to look amongst its children for matches. Recommended for better performance in larger documents. Optional.

         * Call examples

         * To get all elements in the document with a "info-links" class.
         *     getElementsByClassName("info-links");
         * To get all div elements within the element the id of which is "container", with a "col" class.
         *     getElementsByClassName("col", "div", document.getElementById("container")); 
         * To get all elements in the document with a "click-me" and a "sure-thang" class.
         *     getElementsByClassName("click-me sure-thang"); 
        */
        getElementsByClassName : function (className, tag, elm) {
            var returnElements = [];
            if (document.getElementsByClassName) {
                elm = elm || document;
                var elements = elm.getElementsByClassName(className),
                    nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
                    current;
                for(var i=0, il=elements.length; i<il; i+=1){
                    current = elements[i];
                    if(!nodeName || nodeName.test(current.nodeName)) {
                        returnElements.push(current);
                    }
                }
            }
            else if (document.evaluate) {
                tag = tag || "*";
                elm = elm || document;
                var classes = className.split(" "),
                    classesToCheck = "",
                    xhtmlNamespace = "http://www.w3.org/1999/xhtml",
                    namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
                    elements,
                    node;
                for(var j=0, jl=classes.length; j<jl; j+=1){
                    classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
                }
                try	{
                    elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
                }
                catch (e) {
                    elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
                }
                while ((node = elements.iterateNext())) {
                    returnElements.push(node);
                }
            } else {
                tag = tag || "*";
                elm = elm || document;
                var classes = className.split(" "),
                    classesToCheck = [],
                    elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
                    current,
                    match;
                for(var k=0, kl=classes.length; k<kl; k+=1){
                    classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
                }
                for(var l=0, ll=elements.length; l<ll; l+=1){
                    current = elements[l];
                    match = false;
                    for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
                        match = classesToCheck[m].test(current.className);
                        if (!match) {
                            break;
                        }
                    }
                    if (match) {
                        returnElements.push(current);
                    }
                }
            };
            return returnElements;
        },

        /**
         * Make sure the parameter you pass in as "elem" in your call to the following method
         * is the main menu's button div that you're testing to see if it contains a link
         * identical to the current document.
         */
        selectIfActiveMenuButton : function(elem) {
            elem.className = elem.className.replace(/\s+nav_bg2\b/, "");
            var oNodeList = GoVenture.Toolkit.getElementsByTagLike("a", ".*", elem);
            for(var x = 0; x < oNodeList.length; x++) {
                var linkHref = oNodeList[x].href.toLowerCase();
                var docHref = document.location.href.replace(/\?.*/, "").toLowerCase();
                if(linkHref == docHref || linkHref == docHref + "home.aspx" 
                    || linkHref == docHref.replace(/default.aspx$/i, "") + "home.aspx")
                {
                    //alert("typeof(oNodeList[x]): " + typeof(oNodeList[x]));
                    //alert("typeof(oNodeList[x].id): " + typeof(oNodeList[x].id));
                    GoVenture.Toolkit.depressMainMenuButton(elem.id, oNodeList[x].id);
                    //alert("just depressed main menu button in 'if' clause");
                    /*
                } else {
                    oNodeList[x].onclick = function() {
                        alert("typeof(oNodeList[x]) from onclick: " + typeof(oNodeList[x]));
                        alert("typeof(oNodeList[x].id) from onclick: " + typeof(oNodeList[x].id));
                        GoVenture.Toolkit.depressMainMenuButton(elem.id, oNodeList[x].id);
                    };
                    */
                }
            }
        },
        
        removeClass : function(elem, classname) {
            var oRegExp = new RegExp();
            oRegExp.compile("/\s*\b" + classname + "\b/", "g");
            elem.className = elem.className.replace(oRegExp, "");
        },
        
        addClass : function(elem, classname) {
            GoVenture.Toolkit.removeClass(elem, classname);
            elem.className = elem.className + " " + classname;
        },
        
        removeInlineStyleAttribute : function(elem, attributeName) {
            if(typeof(elem.style.cssText) == 'string' && elem.style.cssText.length > 0)
            {
                var oRegExp = new RegExp();
                oRegExp.compile("\s*\b" + attributeName + "\b", "g");
                elem.style.cssText = elem.style.cssText.replace(oRegExp, "");
            }
        },
        
        depressMainMenuButton : function(divId, anchorId) {
            var div = document.getElementById(divId);
            var anchor = document.getElementById(anchorId);
            GoVenture.Toolkit.removeClass(div, "nav_bg1");
            GoVenture.Toolkit.addClass(div, "nav_bg2");
            anchor.removeAttribute("href");
        },
        
        adjustMenus : function() {
            var oNodeList = GoVenture.Toolkit.getElementsByClassName("nav_bg1");
            for(var x = 0; x < oNodeList.length; x++) {
                GoVenture.Toolkit.selectIfActiveMenuButton(oNodeList[x]);
            }
        },
        
        arrayMatch : function(saList, sItemToFind) {
            for(var x = 0; x < saList.length; x++) {
                if(saList[x].match(sItemToFind)) {
                    return x;
                }
            }
            return -1;
        },
        
        getStyleSheetByHref : function(sHref) {
            for(var x = 0; x < document.styleSheets.length; x++) {
                if(document.styleSheets[x].href == undefined) {
                    continue;
                }
                if(document.styleSheets[x].href.match(new RegExp(sHref))) {
                    return x;
                }
            }
            return -1;
        },
        
        getCssRuleBySelector : function(sHref, sSelectorText) {
            var iStyleSheetIdx = GoVenture.Toolkit.getStyleSheetByHref(sHref);
            var aStyleSheet = document.styleSheets[iStyleSheetIdx];
            var aRules = (GoVenture.Toolkit.isIE ? aStyleSheet.rules : aStyleSheet.cssRules);
            for(var x = 0; x < aRules.length; x++) {
                /**
                 * We have to do case-insensitive regular-expression matching here, because
                 * Internet Explorer munges the case of selectors.
                 */
                if(aRules[x].selectorText.match(new RegExp(sSelectorText, "i"))) {
                    return aRules[x];
                }
            }
            return undefined;
        },
        
        getCssRuleStyleAttribute : function(sHref, sSelectorText, sStyleAttrName) {
            var oCssRule = GoVenture.Toolkit.getCssRuleBySelector(sHref, sSelectorText);
            return (oCssRule == undefined ? undefined : oCssRule.style[sStyleAttrName]);
        },
        
        urlEncode : function(sUrl) {
            var sSafeInput = "0123456789" + // Numeric
                "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + // Alphabetic
                "abcdefghijklmnopqrstuvwxyz" +
                "-_.!~*'()"; // RFC2396 Mark characters
            var HEX = "0123456789ABCDEF";

            var plaintext = sUrl;
            var encoded = "";
            for (var i = 0; i < plaintext.length; i++ ) {
                var ch = plaintext.charAt(i);
                if (ch == " ") {
                    encoded += "+"; // x-www-urlencoded, rather than %20
                } else if (SAFECHARS.indexOf(ch) != -1) {
                    encoded += ch;
                } else {
                    var charCode = ch.charCodeAt(0);
                    if (charCode > 255) {
                        alert( "GoVenture.Toolkit.urlEncode() error: Unicode Character '"
                        + ch
                        + "' cannot be encoded using standard URL encoding.\n" +
                        "(URL encoding only supports 8-bit characters.)\n" +
                        "A space (+) will be substituted." );
                        encoded += "+";
                    } else {
                        encoded += "%";
                        encoded += HEX.charAt((charCode >> 4) & 0xF);
                        encoded += HEX.charAt(charCode & 0xF);
                    }
                }
            }

            return encoded;
        },
        
        urlDecode : function(sUrl) {
            // Replace + with ' '
            // Replace %xx with equivalent character
            // Put [ERROR] in output if %xx is invalid.
            var HEXCHARS = "0123456789ABCDEFabcdef";
            var encoded = url;
            var plaintext = "";
            var i = 0;
            while (i < encoded.length) {
                var ch = encoded.charAt(i);
                if (ch == "+") {
                    plaintext += " ";
                    i++;
                } else if (ch == "%") {
                    if (i < (encoded.length-2)
                        && HEXCHARS.indexOf(encoded.charAt(i+1)) != -1
                        && HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 )
                    {
                        plaintext += unescape( encoded.substr(i,3) );
                        i += 3;
                    } else {
                        alert( 'GoVenture.Toolkit.urlDecode() error: Bad escape combination near ...' + encoded.substr(i) );
                        plaintext += "%[ERROR]";
                        i++;
                    }
                } else {
                    plaintext += ch;
                    i++;
                }
            } // end while

            return plaintext;
        },
        
        httpQueryObject : function(sGet) {
            var oHttpQuery = {}; // empty object
            if(typeof(sGet) == "string" && sGet.length > 0) {
                var saPairs = sGet.split("&");
                for(var x = 0; x < saPairs.length; x++) {
                    var saKeyVal = saPairs[x].split("=", 2);
                    oHttpQuery[saKeyVal[0]] = saKeyVal[1];
                }
            }
            return oHttpQuery;
        },
        
        httpQueryString : function(oHttpQuery) {
            var sGet = "";
            for(var prop in oHttpQuery) {
                if(typeof(oHttpQuery[prop]) == "string") { // filter out functions, etc.
                    sGet += (sGet.length > 0 ? "&" : "") + prop + "=" + oHttpQuery[prop];
                }
            }
            return sGet;
        },
                
        selfRedirectWithGetParams : function() {
            var oInput = arguments[0];
            var clobber = (arguments.length > 0 ? arguments[1] : false);
            if(typeof(oInput) != "string" && typeof(oInput) != "object") {
                try {
                    throw new Error("GoVenture.Toolkit.selfRedirectWithGetParams takes exactly one parameter, which can either be a URL-encoded query string or a JSON object representing a list of key-value pairs");
                } catch(e) {
                    alert("GoVenture.Toolkit.selfRedirectWithGetParams takes exactly one parameter, which can either be a URL-encoded query string or a JSON object representing a list of key-value pairs");
                } finally {
                    return {};
                }
            }
            var saBaseAndQuery = document.location.href.split("?", 2);
            var sQueryString = saBaseAndQuery[1];
            var oGetParams = {};
            var oHttpQuery = GoVenture.Toolkit.httpQueryObject(sQueryString);
            if(typeof(oInput) == "string") {
                oGetParams = GoVenture.Toolkit.httpQueryObject(oInput);
            } else {
                oGetParams = oInput;
            }
            var bLoaded = true;
            for(var prop in oGetParams) {
                if(typeof(oGetParams[prop]) == "string") { // filter out functions, etc.
                    if(oHttpQuery[prop] != oGetParams[prop])
                    {
                        bLoaded = false;
                        oHttpQuery[prop] = oGetParams[prop];
                    }
                }
            }
            if(clobber) { // We can't do this any earlier, or else the page would keep redirecting
                for(var prop in oHttpQuery) {
                    if(typeof(oHttpQuery[prop]) == "string" && typeof(oGetParams[prop]) == "undefined") {
                        bLoaded = false;
                        delete oHttpQuery[prop];
                    }
                }
            }
            if(bLoaded) {
                return;
            }
            var sHttpQuery = GoVenture.Toolkit.httpQueryString(oHttpQuery);
            document.location.href = saBaseAndQuery[0] + "?" + sHttpQuery;
        }, 
		
/**
 * namedWindow(theParam)
 * This function opens a new, empty window. Note that if you want Google, Yahoo! and MSN spiders to follow the link,
 * you should always use a link of the form <a href="myLink" onclick="!namedWindow(theParam)">Link text</a> -- this will
 * also allow JavaScript-disabled clients and ones with popup prevention to follow the link (although in the launching window).
 * (You don't want to have your onclick event simply return false because if a popup prevention plugin like Google's prevents
 * the window from opening, you want the link to be able to open regardless.)
 * By default, the new window created by namedWindow()is named (i.e., multiple calls will appear in the same window),
 * but this property can be overridden (see below). 
 * Legal syntaxes:
 * <a href="http://goventure.net/myFirst/" onclick = "return !namedWindow('http://goventure.net/myFirst/')">Link text</a>
 * (opens a full-sized window with default featureset -- see function definition, below)
 * <a href="http://goventure.net/myFirst/"
 *     onclick = "return !namedWindow({url:'http://goventure.net/myFirst/',name:'MyFirst',width:300,height:300})">Link text</a>
 * (Note that in this second syntax, any default variables not overridden in the object literal passed as a parameter
 * to this function will retain the values assigned when objProps is first created in the first line of the function body.)
 * **** IMPORTANT: **** The value for the 'name' parameter in this function must ONLY include alphanumeric characters or underscore,
 * or else the function will break!!! (Specified by the second parameter restrictions of JavaScript's window.open() method)
 * **********************************
 * If you want to create a new window without a variable name so that it opens a new window each time (i.e., window.open(myLink, '', featureList),
 * then include the pair name: '' (empty string) in the object literal, i.e.,
 * onclick="namedWindow({url: 'http://some.url', name: '', width: 750, height:400})"
 * By default the window featureset is the same as that for the old newWindow_full function
 * ('toolbar=yes,location=yes,directories=yes,menubar=yes,scrollbars=yes,width=800,height=600') with left and top (or screenX and screenY)
 * each set to 50.
 * For replacing legacy calls:
 * newWindow featureset = 'toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes'
 * newPdfWindow featureset =
 * 'toolbar=no,location=no,directories=no,status=yes,menubar=no,scrollbars=auto,resizable=no,width=780,height=590,left=50,top=50'
 * and a specified windowName.
 * newWindow_contact featureset = 'toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes' with left and top each set to 40,
 * default width 560, and default height 420.
 * newWindow_movie featureset =
 * 'toolbar=no,location=no,directories=no,menubar=no,scrollbars=no,resizable=yes,status=no' with default width 639 and default height 477,
 * and width and height explicitly called, in that order. (Left and top are both set to 100.)
 * newWindow_help featureset = 'toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes' with width and height explicitly specified
 * and no left/top settings.
 * newWindow_newsletter featureset = 'toolbar=yes,location=no,directories=no,menubar=no,scrollbars=yes,resizable=yes,width=620,height=500'
 * with no left/top settings. Make the URL into a GET request to http://www.goventure.net/site/products/live/fwd.cfm and append
 * "?d=" + the issue's URL + "&i=" + the page name you want the Activity Tracker to record for hit-count purposes.
 * newWindow_trial featureset = 'toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes,width=620,height=420'
 * with left and top set to 40.
 * newWindow_tools featureset = 'toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes' with left, top, width, and height
 * explicitly passed as args in that order.
 * For all VOwindow functions (see newWindow_VO) the featureset is
 * 'toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes,resizable=no,width=640,height=480'
 * (the original script had the resizable label misspelled as "resizeable" so it didn't work)
 */
		namedWindow : function() {
			if(GoVenture.Toolkit.namedWindow.arguments.length < 1) {
				return false;
			}
			var propertiesObjectOrUrl = GoVenture.Toolkit.namedWindow.arguments[0];
			var defaultObject = null;
			
			if(GoVenture.Toolkit.namedWindow.arguments.length > 1) {
				if(typeof(GoVenture.Toolkit.namedWindow.arguments[1]) == "object") {
					defaultObject = GoVenture.Toolkit.namedWindow.arguments[1];
				}
			}
			var objProps = {
				url         :   'about:blank',
				name        :   'fullWindow',
				toolbar     :   'yes',
				location    :   'yes',
				directories :   'yes',
				menubar     :   'yes',
				scrollbars  :   'yes',
				width       :   800,
				height      :   600
			};
			var arrWindowFeatures = new Array("toolbar", "location", "directories", "menubar", "scrollbars", "width", "height");
			
			if (navigator.appName.indexOf("Microsoft") > -1) {
				isMSIE = true;
				objProps.leftName = 'left';
				objProps.topName = 'top';
		//    	winStats=winStats+'left=50,top=50';
			} else {
				isMSIE = false;
				objProps.leftName = 'screenX';
				objProps.topName = 'screenY';
		//		winStats=winStats+'screenX=50,screenY=50';
			}
			arrWindowFeatures.splice(arrWindowFeatures.length, 0, objProps.leftName, objProps.topName);
			objProps.leftVal = '50';
			objProps.topVal = '50';
			if(defaultObject != null) {
				for(defProp in defaultObject) {
					if(defProp == "screenX") {
						continue; // skip remainder of the current loop: this case will be handled later
					}
					objProps[defProp] = defaultObject[defProp];
				}
			}
			
			var strWindowFeatures = "";

			if(typeof(propertiesObjectOrUrl) == "string") {
				// treat as URL
				objProps.url = propertiesObjectOrUrl;
				
			} else if(typeof(propertiesObjectOrUrl) == "object") {
				// treat as properties object
				objProps.url = propertiesObjectOrUrl.url;
				for(var x = 0; x < arrWindowFeatures.length; x++) {
					if(eval("propertiesObjectOrUrl." + arrWindowFeatures[x])) {
						eval("objProps." + arrWindowFeatures[x] + " = propertiesObjectOrUrl." + arrWindowFeatures[x]);
					}
				}
				if(propertiesObjectOrUrl.screenX && typeof(propertiesObjectOrUrl.screenX) != "undefined") {
					objProps.leftVal = propertiesObjectOrUrl.screenX;
				} else if (propertiesObjectOrUrl.left && typeof(propertiesObjectOrUrl.left) != "undefined") {
					objProps.leftVal = propertiesObjectOrUrl.left;
				} else if(defaultObject != null && defaultObject.screenX && typeof(defaultObject.screenX) != "undefined")
				{
					objProps.leftVal = defaultObject.screenX;
				} else if(defaultObject != null && defaultObject.left && typeof(defaultObject.left) != "undefined")
				{
					objProps.leftVal = defaultObject.left;
				}
				if(propertiesObjectOrUrl.screenY && typeof(propertiesObjectOrUrl.screenY) != "undefined") {
					objProps.topVal = propertiesObjectOrUrl.screenY;
				} else if (propertiesObjectOrUrl.top && typeof(propertiesObjectOrUrl.top) != "undefined") {
					objProps.topVal = propertiesObjectOrUrl.top;
				} else if(defaultObject != null && defaultObject.screenY && typeof(defaultObject.screenY) != "undefined")
				{
					objProps.topVal = defaultObject.screenY;
				} else if(defaultObject != null && defaultObject.top && typeof(defaultObject.top) != "undefined")
				{
					objProps.topVal = defaultObject.top;
				}
				objProps[objProps.leftName] = objProps.leftVal;
				objProps[objProps.topName] = objProps.topVal;
				if(propertiesObjectOrUrl.name) {
					objProps.name = propertiesObjectOrUrl.name;
				}
			}
			for(var x = 0; x < arrWindowFeatures.length; x++) {
				strWindowFeatures += (objProps[arrWindowFeatures[x]] === '' ? '' :
										(strWindowFeatures.length == 0 ? '' : ',') + arrWindowFeatures[x] + '=' + objProps[arrWindowFeatures[x]]);
			}
			if(objProps.hasOwnProperty('status')) {
				strWindowFeatures += (objProps['status'] === '' ? '' :
										(strWindowFeatures.length == 0 ? '' : ',') + 'status=' + objProps['status']);
			}
			var windowRef = window.open(objProps.url, objProps.name, strWindowFeatures);
			return windowRef;
		},
		
		toggleDivsByAnchor : function() {

			var oRegex = /\#(.+)/;
			var anchorName = (oRegex.exec(document.location.href))[1];
			if(anchorName == undefined) {
				return;
			}
			if(anchorName.length > 0) {
				var oRegExp = new RegExp("\\\<a name=\\\"" + anchorName + "\\\"\\\>");
				if(oRegExp.test(document.body.innerHTML) == false) {
					return;
				}
			}
			var anchors = document.getElementsByTagName("a");
			for(var x = 0; x < anchors.length; x++) {
				if(anchors[x].name == undefined) {
					continue; // skip remainder of current iteration and go to next one
				}
				var elem = document.getElementById(anchors[x].name);
				if(elem == undefined || elem.tagName.toLowerCase() !="div") {
					continue;
				}
				if(elem.id == anchorName) {
					elem.style.display = "block";
				} else {
					elem.style.display = "none";
				}
			}
		}
    }
}

