// JavaScript Utilities File

var xMousePos;
var yMousePos;
var xMousePosMax;
var yMousePosMax;

// Global object to hold drag information.
var dragObj = new Object();
dragObj.zIndex = 0;

var browser;

var objUtils = {

    showDiv: function(id) {
        // .NET Postback
        // .NET puts "_" in the ID of tags in the HTML stream, but refers to them using the $
        id = id.toString().replace(/_/g, "$");
        __doPostBack(id, '');
    }, // end of showDiv

    dotNetPostBack: function(eventTargetId) {
        // .NET Postback
        // .NET puts "_" in the ID of tags in the HTML stream, but refers to them using the $
        eventTargetId = eventTargetId.toString().replace(/_/g, "$");
        __doPostBack(eventTargetId, '');
    }, // end of dotNetPostBack

    dotNetClientValidate: function() {
        if (!Page_Validators) return;
        // remove all error styles first ...
        for (var i = 0; i < Page_Validators.length; i++) {
            var ctrlID = Page_Validators[i].controltovalidate;
            var ctrl = document.getElementById(ctrlID);
            ctrl.className = "";
        }
        Page_ClientValidate();
        for (var i = 0; i < Page_Validators.length; i++) {
            var ctrlID = Page_Validators[i].controltovalidate;
            var ctrl = document.getElementById(ctrlID);
            if (!Page_Validators[i].isvalid) {
                ctrl.className = "ErrorFieldStyle";
            } 
        }
    }, // end of dotNetClientValidate

    BuildDropDownOptionsFromXML: function(ElementID, DropDownOptionsXML) {

        /*
        This function takes an XML document in which the drop down options are 
        are listed within XML tags, and creates the drop down options.
        <DropDownOptions>
        <DropDownOption>
        <Text>Option1 Text</Text>
        <Value>Option1 Value</Value>
        </DropDownOption>
        <DropDownOption>
        <Text>Option2 Text</Text>
        <Value>Option2 Value</Value>
        </DropDownOption>
        </DropDownOptions>
        NOTE: Because of the way this function is written, the actual names of 
        tags are not important. The structure, where the individual options tags are listed 
        or nested under a top level container tag, is important.

    1. First step is to get the  <DropDownOption> nodes within the
        <DropDownOptions> tag.
        This is achieved simply by defining an "DropDownOptions" array and setting
        it as follows:
        var DropDownOptions = objXMLReq.responseXML.getElementsByTagName("DropDownOption");
        Note the "SecondList" argument - not "DropDownOptions" since we are interested
        in the "DropDownOption' nodes in the XML tree.

    Next, to access the tags, within a "DropDownOption" tag, use:
        var text = DropDownOptions[i].firstChild.nodeValue;
        Hence, we use the .firstChild.nodeValue to get the value.
        */

        var DropDownOptionsContainer = DropDownOptionsXML;
        // Now place all items in the drop down list:
        // Get the DropDownList element and assign to variable
        var ddl = document.getElementById(ElementID);

        // loop through <DropDownOption> elements, and add to ddl  element
        var opt;
        /* Essentials of adding an option element
        opt = document.createElement("option");
        opt.value = i;
        opt.text = i
        ddl.appendChild(opt);
        */

        // Remove existing option elements
        ddl.innerHTML = "";
        if (DropDownOptionsContainer) {

            /*
            DropDownOptionsContainer.childNodes[0] gives the container XML tag: <DropDownOptions>
            DropDownOptionsContainer.childNodes[0].childNodes[i] gives the i-th option
            tag
            */
            //alert("# of nodes = " + DropDownOptionsContainer.childNodes[0].childNodes.length);
            DropDownOptions = DropDownOptionsContainer.childNodes[0];
            // or getElementsByTagName("DropDownOption");

            for (var i = 0; i < DropDownOptions.childNodes.length; i++) {
                opt = document.createElement("option");

                // Note: to get access to the text within a tag, you 
                // need to access it as .firstChild
                // DropDownOptions.childNodes[i] = i-th <DropDownOption> tag
                opt.text = DropDownOptions.childNodes[i].childNodes[0].firstChild.nodeValue;
                opt.value = DropDownOptions.childNodes[i].childNodes[1].firstChild.nodeValue;

                //ddl.appendChild(opt);  // works in Firefox but not IE
                // hence, use the "add" method instead
                try {
                    //ddl.appendChild(opt)
                    ddl.add(opt, null); // standards compliant; doesn't work in IE
                } catch (ex) {
                    ddl.add(opt); // IE only
                }
            }
        }
    }, // end of BuildDropDownOptionsFromXML

    // Disables Submit Buttons Once Clicked and Shows Progress Bar
    // To use on any page, insert 
    // objUtils.addEvent(window, "load", objUtils.disableAllSubmitButtonsAfterClick);
    disableAllSubmitButtonsAfterClick: function() {

        // cache progress bar image
        var ProgressBarPath = "/Images/RotatingIndicator.gif";
        (new Image()).src = ProgressBarPath;

        // Get a list of all "input" elements on page
        var allInputButtons = document.getElementsByTagName('input');

        // Walk through the list identifying buttons of type "submit"
        // There are two walk throughs of the list of input elements:
        // the first one is to identify all "Submit" buttons and assign a function 
        // to their onclick event.
        // The second one is to disable all "Submit" buttons when any one has been clicked
        // … Here is the first walk through:
        for (var i = 0; i < allInputButtons.length; i++) {
            var inp = allInputButtons[i];
            //alert("type = " + inp.type);
            if (inp.type != "submit") continue;
            objUtils.addEvent(inp, "click", function(e) {

                if (!Page_ClientValidate()) return;

                var imgProgressBar = document.createElement("img");
                imgProgressBar.setAttribute("src", ProgressBarPath);
                // Center the Progress Bar
                imgProgressBar.style.position = "absolute";
                objUtils.captureMousePosition(e);

                // Get image position from cursor
                if (xMousePos && yMousePos) {
                    //alert("x, y = " + xMousePos + ":" + yMousePos);
                    imgProgressBar.style.left = xMousePos - 20 + "px";
                    imgProgressBar.style.top = yMousePos - 20 + "px";
                } else { // or if the user has hit enter, then center.
                    //imgProgressBar.style.left = objUtils.getHtmlElementPositionLeft(inp) + "px";
                    //imgProgressBar.style.top = objUtils.getHtmlElementPositionTop(inp) + "px";
                    imgProgressBar.style.top = "50%";
                    imgProgressBar.style.left = "50%";

                }
                //imgProgressBar.style.width = "32";
                //imgProgressBar.style.height = "32";                     
                inp.parentNode.appendChild(imgProgressBar);


                var allInputButtons2 = document.getElementsByTagName("input");
                for (var i = 0; i < allInputButtons2.length; i++) {
                    var inp2 = allInputButtons2[i];
                    if (inp2.type != "submit") continue;
                    // disable submit button
                    //inp2.disabled = true;
                    //inp2.value = "Submitting …"; 
                    objUtils.DisableControl_SetTimeout(inp2.id);
                } // end of second for loop over input elements on page



            } // end of function called in objUtils.addEvent
          ); // end of objUtils.addEvent
        }  // end of loop

    }, // end of disableAllSubmitButtonsAfterClick

    DisableControl_SetTimeout: function(ElemID) {
        var EvalString = "document.getElementById('" + ElemID + "').disabled = true";

        setTimeout("eval(" + EvalString + ")", 50);

    }, // end of DisableControl_SetTimeout




    getHtmlElementPositionLeft: function(HtmlElement) {
        // This function gets left position of the HTML element (using the offsetLeft property
        // and recursively going up the HtmlElementect tree using the offsetTop property
        //alert(HtmlElement);
        var curLeft = 0;
        if (HtmlElement.offsetParent) {
            do {
                curLeft += HtmlElement.offsetLeft;
            } while (HtmlElement = HtmlElement.offsetParent);
        }
        else if (HtmlElement.x) {
            curLeft += HtmlElement.x;
        }
        return curLeft;
    }, // end of getElementPositionLeft

    getHtmlElementPositionTop: function(HtmlElement) {
        // This function gets top position of the target element (using the offsetLeft property
        // and recursively going up the HtmlElementect tree using the offsetTop property
        var curTop = 0;
        if (HtmlElement.offsetParent) {
            do {
                curTop += HtmlElement.offsetTop;
            } while (HtmlElement = HtmlElement.offsetParent);
        }
        else if (HtmlElement.y) {
            curTop += HtmlElement.y;
        }
        return curTop;
    }, // end of getHtmlElementPositionTop

    captureMousePosition: function(e) {
        if (document.all) {
            //xMousePos = window.event.x+document.body.scrollLeft;
            //yMousePos = window.event.y+document.body.scrollTop;
            xMousePos = window.event.clientX + document.body.scrollLeft;
            yMousePos = window.event.clientY + document.body.scrollTop;
            xMousePosMax = document.body.clientWidth + document.body.scrollLeft;
            yMousePosMax = document.body.clientHeight + document.body.scrollTop;
        } else if (document.getElementById) {
            xMousePos = e.pageX;
            yMousePos = e.pageY;
            xMousePosMax = window.innerWidth + window.pageXOffset;
            yMousePosMax = window.innerHeight + window.pageYOffset;
        }
        //alert(yMousePos + " " + yMousePosMax);
    }, // end of captureMousePosition


    showDivWindow: function(DivID) {
        document.getElementById(DivID).style.visibility = "hidden";
        //document.getElementById(DivID).style.display = "none";
        //alert("showDivWindow: " + yMousePos+", "+yMousePosMax);
        // get DivID dims:
        var DivWidth = parseInt(document.getElementById(DivID).style.width);
        var DivHeight = parseInt(document.getElementById(DivID).style.height)

        var yDivPos = yMousePos;
        var xDivPos = xMousePos;
        if ((yMousePos + DivHeight) >= (yMousePosMax)) {
            yDivPos = yMousePos - DivHeight;
        }
        if ((xMousePos + DivWidth) >= (xMousePosMax)) {
            xDivPos = xMousePos - DivWidth;
        }

        //alert("xDivPos = " + xDivPos);
        document.getElementById(DivID).style.top = yDivPos + "px";
        document.getElementById(DivID).style.left = xDivPos + "px";
        document.getElementById(DivID).style.visibility = "visible";
        //document.getElementById(DivID).style.display = "block";
        //document.getElementById(DivID).innerHTML = xDivPos + " " + yDivPos;


    }, // end of showDivWindow


    BrowserDetect: function() {
        var ua = navigator.userAgent.toLowerCase();
        //alert(ua);
        // browser engine name
        this.isGecko = (ua.indexOf('gecko') != -1);
        this.isAppleWebKit = (ua.indexOf('applewebkit') != -1);
        // browser name
        this.isKonqueror = (ua.indexOf('konqueror') != -1);
        this.isSafari = (ua.indexOf('safari') != -1);
        this.isOmniweb = (ua.indexOf('omniweb') != -1);
        this.isOpera = (ua.indexOf('opera') != -1);
        this.isIcab = (ua.indexOf('icab') != -1);
        this.isAol = (ua.indexOf('aol') != -1);
        this.isIE = (ua.indexOf('msie') != -1 && !this.isOpera && (ua.indexOf('webtv') == -1));
        this.isMozilla = (this.isGecko && ua.indexOf('gecko/') + 14 == ua.length);
        this.isFirebird = (ua.indexOf('firebird/') != -1);
        this.isFirefox = (ua.indexOf('firefox') != -1);
        this.isNS = ((this.isGecko) ? (ua.indexOf('netscape') != -1) : ((ua.indexOf('mozilla') != -1) && !this.isOpera && !this.isSafari && (ua.indexOf('spoofer') == -1) && (ua.indexOf('compatible') == -1) && (ua.indexOf('webtv') == -1) && (ua.indexOf('hotjava') == -1)));
        // spoofing and compatible browsers
        this.isIECompatible = ((ua.indexOf('msie') != -1) && !this.isIE);
        this.isNSCompatible = ((ua.indexOf('mozilla') != -1) && !this.isNS && !this.isMozilla);
        // rendering engine versions
        this.geckoVersion = ((this.isGecko) ? ua.substring((ua.lastIndexOf('gecko/') + 6), (ua.lastIndexOf('gecko/') + 14)) : -1);
        this.equivalentMozilla = ((this.isGecko) ? parseFloat(ua.substring(ua.indexOf('rv:') + 3)) : -1);
        this.appleWebKitVersion = ((this.isAppleWebKit) ? parseFloat(ua.substring(ua.indexOf('applewebkit/') + 12)) : -1);
        //alert(ua + " |||| " + this.equivalentMozilla);
        // browser version
        this.versionMinor = parseFloat(navigator.appVersion);
        // correct version number
        if (this.isGecko && !this.isMozilla) {
            this.versionMinor = parseFloat(ua.substring(ua.indexOf('/', ua.indexOf('gecko/') + 6) + 1));
        }
        else if (this.isMozilla) {
            this.versionMinor = parseFloat(ua.substring(ua.indexOf('rv:') + 3));
            this.versionRevision = ua.substring(ua.indexOf('rv:') + 3, ua.indexOf(")", ua.indexOf('rv:')));
        }
        else if (this.isIE && this.versionMinor >= 4) {
            this.versionMinor = parseFloat(ua.substring(ua.indexOf('msie ') + 5));
        }
        else if (this.isKonqueror) {
            this.versionMinor = parseFloat(ua.substring(ua.indexOf('konqueror/') + 10));
        }
        else if (this.isSafari) {
            this.versionMinor = parseFloat(ua.substring(ua.lastIndexOf('safari/') + 7));
        }
        else if (this.isOmniweb) {
            this.versionMinor = parseFloat(ua.substring(ua.lastIndexOf('omniweb/') + 8));
        }
        else if (this.isOpera) {
            this.versionMinor = parseFloat(ua.substring(ua.indexOf('opera') + 6));
        }
        else if (this.isIcab) {
            this.versionMinor = parseFloat(ua.substring(ua.indexOf('icab') + 5));
        }
        this.versionMajor = parseInt(this.versionMinor);
        // dom support
        this.isDOM1 = (document.getElementById);
        this.isDOM2Event = (document.addEventListener && document.removeEventListener);
        // css compatibility mode
        this.mode = document.compatMode ? document.compatMode : 'BackCompat';
        // platform
        this.isWin = (ua.indexOf('win') != -1);
        this.isWin32 = (this.isWin && (ua.indexOf('95') != -1 || ua.indexOf('98') != -1 || ua.indexOf('nt') != -1 || ua.indexOf('win32') != -1 || ua.indexOf('32bit') != -1 || ua.indexOf('xp') != -1));
        this.isMac = (ua.indexOf('mac') != -1);
        this.isUnix = (ua.indexOf('unix') != -1 || ua.indexOf('sunos') != -1 || ua.indexOf('bsd') != -1 || ua.indexOf('x11') != -1)
        this.isLinux = (ua.indexOf('linux') != -1);
        //alert(this.versionMajor + " " + this.versionMinor + " " + this.versionRevision );
        // specific browser shortcuts
        this.isNS4x = (this.isNS && this.versionMajor == 4);
        this.isNS40x = (this.isNS4x && this.versionMinor < 4.5);
        this.isNS47x = (this.isNS4x && this.versionMinor >= 4.7);
        this.isNS4up = (this.isNS && this.versionMinor >= 4);
        this.isNS6x = (this.isNS && this.versionMajor == 6);
        this.isNS6up = (this.isNS && this.versionMajor >= 6);
        this.isNS7x = (this.isNS && this.versionMajor == 7);
        this.isNS7up = (this.isNS && this.versionMajor >= 7);
        this.isNS8x = (this.isNS && this.versionMajor == 8);
        this.isNS8up = (this.isNS && this.versionMajor >= 8);
        this.isIE4x = (this.isIE && this.versionMajor == 4);
        this.isIE4up = (this.isIE && this.versionMajor >= 4);
        this.isIE5x = (this.isIE && this.versionMajor == 5);
        this.isIE55 = (this.isIE && this.versionMinor == 5.5);
        this.isIE5up = (this.isIE && this.versionMajor >= 5);
        this.isIE6x = (this.isIE && this.versionMajor == 6);
        this.isIE6up = (this.isIE && this.versionMajor >= 6);
        this.isMoz17up = (this.isMozilla && this.versionMinor >= 1.7);
        this.isMoz175 = (this.isMozilla && this.versionRevision == "1.7.5");
        this.isGecko17up = (this.isGecko && this.versionMinor >= 1.7);
        this.isSaf13 = (this.isSafari && this.versionMinor >= 1.3);
        this.isOpera9up = (this.isOpera && this.versionMajor >= 9);
        this.isIE4xMac = (this.isIE4x && this.isMac);
        this.isIE5xMac = (this.isIE5x && this.isMac);

    }, // end of BrowserDetect

    setBrowser: function() {
        browser = new objUtils.BrowserDetect();
    }, // end of setBrowser

    // Drag functions

    dragStart: function(event, id) {
        document.body.style.cursor = "move";
        var el;
        var x, y;

        // If an element id was given, find it. Otherwise use the element being
        // clicked on.
        if (id)
            dragObj.elNode = document.getElementById(id);
        else {
            if (browser.isIE5up) {
                dragObj.elNode = window.event.srcElement;
            } else {
                dragObj.elNode = event.target;
            }
            // If this is a text node, use its parent element.
            while (dragObj.elNode.nodeName != "DIV") {
                dragObj.elNode = dragObj.elNode.parentNode;
            }
            if (dragObj.elNode.nodeType == 3)
                dragObj.elNode = dragObj.elNode.parentNode;
        }
        // Get cursor position with respect to the page.
        if (browser.isIE5up) {
            x = window.event.clientX + document.documentElement.scrollLeft
+ document.body.scrollLeft;
            y = window.event.clientY + document.documentElement.scrollTop
+ document.body.scrollTop;
        } else {
            x = event.clientX + window.scrollX;
            y = event.clientY + window.scrollY;
        }
        // Save starting positions of cursor and element.
        dragObj.cursorStartX = x;
        dragObj.cursorStartY = y;
        dragObj.elStartLeft = parseInt(dragObj.elNode.style.left, 10);
        dragObj.elStartTop = parseInt(dragObj.elNode.style.top, 10);
        if (isNaN(dragObj.elStartLeft)) dragObj.elStartLeft = 0;
        if (isNaN(dragObj.elStartTop)) dragObj.elStartTop = 0;
        // Update element's z-index.
        dragObj.elNode.style.zIndex = ++dragObj.zIndex;

        // Capture mousemove and mouseup events on the page.
        if (browser.isIE5up) {
            document.attachEvent("onmousemove", objUtils.dragGo);
            document.attachEvent("onmouseup", objUtils.dragStop);
            window.event.cancelBubble = true;
            window.event.returnValue = false;
        } else {
            document.addEventListener("mousemove", objUtils.dragGo, true);
            document.addEventListener("mouseup", objUtils.dragStop, true);
        }
    }, // end of dragStart


    dragGo: function(event) {
        drag = true;
        var x, y;
        // Get cursor position with respect to the page.
        if (browser.isIE5up) {
            x = window.event.clientX + document.documentElement.scrollLeft
+ document.body.scrollLeft;
            y = window.event.clientY + document.documentElement.scrollTop
+ document.body.scrollTop;
        } else {
            x = event.clientX + window.scrollX;
            y = event.clientY + window.scrollY;
        }
        // window.status = dragObj.elStartLeft + " " + x + " " + dragObj.cursorStartX;
        // Move drag element by the same amount the cursor has moved.
        dragObj.elNode.style.left =
(dragObj.elStartLeft + x - dragObj.cursorStartX) + "px";
        dragObj.elNode.style.top =
(dragObj.elStartTop + y - dragObj.cursorStartY) + "px";
        if (browser.isIE5up) {
            window.event.cancelBubble = true;
            window.event.returnValue = false;
        } else {
            event.preventDefault();
        }
    }, // end of dragGo

    dragStop: function(event) {
        // Stop capturing mousemove and mouseup events.
        document.body.style.cursor = "auto";
        if (browser.isIE5up) {
            document.detachEvent("onmousemove", objUtils.dragGo);
            document.detachEvent("onmouseup", objUtils.dragStop);
        } else {
            document.removeEventListener("mousemove", objUtils.dragGo, true);
            document.removeEventListener("mouseup", objUtils.dragStop, true);
        }
    }, // end of dragStop

    getEventElement: function(event) {
        if (window.event) { // IE
            return window.event.srcElement;
        } else {
            return event.target;
        }
    }, // end of getEventElement

    stopEvent: function(e) {
        if (!e) e = window.event;
        if (e.stopPropagation) {
            e.stopPropagation();
        } else {
            e.cancelBubble = true;
        }
    }, // end of stopEvent

    cancelEvent: function(e) {
        if (!e) e = window.event;
        if (e.preventDefault) {
            e.preventDefault();
        } else {
            e.returnValue = false;
        }
    }, // end of cancelEvent



    addEvent: function(elm, evType, fn, useCapture) {
        // elm: Element that triggers event, eg. window
        // evType: Event type such as click, etc.
        // fn: function that gets called when event is triggered

        // USAGE: 
        // objUtils.addEvent(element, "EventType", functionToInvoke)
        // example: objUtils.addEvent(window, "load", showMap)

        // addEvent and removeEvent
        // cross-browser event handling for IE5+,  NS6 and Mozilla
        if (elm.addEventListener) {
            elm.addEventListener(evType, fn, useCapture);
            return true;
        } else if (elm.attachEvent) {
            var r = elm.attachEvent("on" + evType, fn);
            return r;
        } else {
            alert("Handler could not be removed");
        }
    } // end of addEvent function 


} // end of objUtils


objUtils.addEvent(window, "load", objUtils.setBrowser);
objUtils.addEvent(window, "load", objUtils.disableAllSubmitButtonsAfterClick);


