var popups = new Array();

function ShowPopup(popupControlID, closeControlID, backgroundCssClass) {
    var pop = findPopup(popupControlID, closeControlID, backgroundCssClass);
    pop.initilize();
    pop.show();
}

function ShowTimedPopup(popupControlID, closeControlID, backgroundCssClass, timeout) {
    var pop = findPopup(popupControlID, closeControlID, backgroundCssClass);
    pop.initilize();
    pop.show();
    window.setTimeout('HidePopup("' + popupControlID + '");', timeout);
}

function HidePopup(popupControlID) {
    var pop = findPopup(popupControlID, null, null, true);
    if (pop != null) {
        pop.hide();
    }
}

function findPopup(popupControlID, closeControlID, backgroundCssClass, mustExist) {
    for (i=0; i<popups.length; i++) {
        if (popups[i]._popupControlID == popupControlID) {
            return popups[i];
        }
    }

    if (mustExist) {
        return null;
    }

    var pop = new JSPopup(popupControlID, closeControlID, backgroundCssClass);
    popups[popups.length] = pop;
    return pop;
}

JSPopup = function(popupControlID, closeControlID, backgroundCssClass) {
    // Properties
    this._backgroundCssClass = backgroundCssClass;
    this._popupControlID = popupControlID;
    this._closeControlID = closeControlID;

    this._isInitilized = false;

    // Variables
    this._showDetailsHandler = null;
    this._hideDetailsHandler = null;
    this._backgroundElement = null;
    this._foregroundElement = null;
    this._closeElement = null;
    this._popupElement = null;
    this._imageElement = null;
    this._titleElement = null;
    this._textElement = null;
    this._scrollHandler = null;
    this._resizeHandler = null;
    this._windowHandlersAttached = false;

    // Variables for layout
    this._relativeOrAbsoluteParentElement = null;
    this._isIE6 = false;
    this._xCoordinate = -1;
    this._yCoordinate = -1;

    // Variables for "tabbing"
    this._saveTabIndexes = new Array();
    this._saveDesableSelect = new Array();
    this._tagWithTabIndex = new Array('A','AREA','BUTTON','INPUT','OBJECT','SELECT','TEXTAREA','IFRAME');
}

JSPopup.prototype = {
    initilize : function() {
        if (!this._popupControlID) return;

        this._isInitilized = true;
        this._isIE6 = (Sys.Browser.agent == Sys.Browser.InternetExplorer && Sys.Browser.version < 7);

        this._popupElement = $get(this._popupControlID);

        if (!this._popupElement) return;

        this._foregroundElement = $get(this._popupControlID);
        if (this._closeControlID) {
            this._closeElement = $get(this._closeControlID);

            if (this._closeElement) {
                this._hideDetailsHandler = Function.createDelegate(this, this._hideDetails);
                $addHandler(this._closeElement, "click", this._hideDetailsHandler);
            }
        }

        this._backgroundElement = document.createElement('div');
        this._backgroundElement.style.display = 'none';
        this._backgroundElement.style.position = 'fixed';
        this._backgroundElement.style.left = '0px';
        this._backgroundElement.style.top = '0px';
        // Want zIndex to big enough that the background sits above everything else
        // CSS 2.1 defines no bounds for the <integer> type, so pick arbitrarily
        this._backgroundElement.style.zIndex = 10000;
        if (this._backgroundCssClass) {
            this._backgroundElement.className = this._backgroundCssClass;
        }
        this._foregroundElement.parentNode.appendChild(this._backgroundElement);

        this._foregroundElement.style.display = 'none';
        this._foregroundElement.style.position = 'fixed';
        this._foregroundElement.style.zIndex = this.getCurrentStyle(this._backgroundElement, 'zIndex', this._backgroundElement.style.zIndex) + 1;

        this._scrollHandler = Function.createDelegate(this, this._onLayout);
        this._resizeHandler = Function.createDelegate(this, this._onLayout);
    },

    show : function() {
        /// <summary>
        /// Display the popup control as a modal dialog
        /// </summary>


        if (!this._isInitilized)
            this.initilize();

        if (!this._popupElement) return;


        this._attachPopup();


        this._backgroundElement.style.display = '';
        this._foregroundElement.style.display = '';
        this._popupElement.style.display = 'block';
        if (this._isIE6) {
            this._foregroundElement.style.position = 'absolute';
            this._backgroundElement.style.position = 'absolute';
            // find the relative or absolute parent
            var tempRelativeOrAbsoluteParent = this._foregroundElement.parentNode;
            while (tempRelativeOrAbsoluteParent && (tempRelativeOrAbsoluteParent != document.documentElement)) {
                if((tempRelativeOrAbsoluteParent.style.position != 'relative') && (tempRelativeOrAbsoluteParent.style.position != 'absolute')) {
                    tempRelativeOrAbsoluteParent = tempRelativeOrAbsoluteParent.parentNode;
                } else {
                    this._relativeOrAbsoluteParentElement = tempRelativeOrAbsoluteParent;
                    break;
                }
            }
        }


        // Disable TAB
        this.disableTab();

        this._layout();
        // On pages that don't need scrollbars, Firefox and Safari act like
        // one or both are present the first time the layout code runs which
        // obviously leads to display issues - run the layout code a second
        // time to work around this problem
        this._layout();

        //this.raiseShown(Sys.EventArgs.Empty);
    },

    _onLayout : function() {
        /// <summary>
        /// Handler for scrolling and resizing events that would require a repositioning of the modal dialog
        /// </summary>
        this._layout();
    },

    _layout : function() {
        /// <summary>
        /// Position the modal dialog
        /// </summary>

        var scrollLeft = (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
        var scrollTop = (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);

        var clientBounds = this.getClientBounds();
        var clientWidth = clientBounds.width;
        var clientHeight = clientBounds.height;

        // Setup the location of the background element
        this._layoutBackgroundElement();

        var xCoord = 0;
        var yCoord = 0;
        if(this._xCoordinate < 0) {
            var foregroundelementwidth = this._foregroundElement.offsetWidth? this._foregroundElement.offsetWidth: this._foregroundElement.scrollWidth;
            xCoord = ((clientWidth-foregroundelementwidth)/2);
            // workaround for drag behavior which calls setlocation which in turn
            // changes the position of the panel to be absolute and requiring us
            // to add the scrollLeft so that it is positioned correctly.
            if (this._foregroundElement.style.position == 'absolute') {
                xCoord += scrollLeft;
            }
            this._foregroundElement.style.left = xCoord + 'px';

        } else {
            if(this._isIE6) {
                this._foregroundElement.style.left = (this._xCoordinate + scrollLeft) + 'px';
                xCoord = this._xCoordinate + scrollLeft;
            }
            else {
                this._foregroundElement.style.left = this._xCoordinate + 'px';
                xCoord = this._xCoordinate;
            }
        }
        if(this._yCoordinate < 0) {
            var foregroundelementheight = this._foregroundElement.offsetHeight? this._foregroundElement.offsetHeight: this._foregroundElement.scrollHeight;
            yCoord = ((clientHeight-foregroundelementheight)/2);
            // workaround for drag behavior which calls setlocation which in turn
            // changes the position of the panel to be absolute and requiring us
            // to add the scrollLeft so that it is positioned correctly.
            if (this._foregroundElement.style.position == 'absolute') {
                yCoord += scrollTop;
            }
            this._foregroundElement.style.top = yCoord + 'px';

        } else {
            if(this._isIE6) {
                this._foregroundElement.style.top = (this._yCoordinate + scrollTop) + 'px';
                yCoord = this._yCoordinate + scrollTop;
            }
            else {
                this._foregroundElement.style.top = this._yCoordinate + 'px';
                yCoord = this._yCoordinate;
            }
        }

        // make sure get location agrees with the location of the foreground element
        this._layoutForegroundElement(xCoord, yCoord);

        // layout background element again to make sure it covers the whole background
        // in case things moved around when laying out the foreground element
        this._layoutBackgroundElement();
    },

    _layoutForegroundElement : function(xCoord, yCoord) {
        /// <summary>
        /// Set the correct location of the foreground element to ensure that it is absolutely
        /// positioned with respect to the browser. This is just a workaround for IE 6 since
        /// elements nested in relative parents cause modal popup positioning issues and 'fixed'
        /// is not supported by IE 6. Hence we manually compute the right location of the popup.
        /// </summary>
        /// <param name="xCoord" type="Number" integer="true" maybenull="false">
        /// <param name="yCoord" type="Number" integer="true" maybenull="false">
        /// </params>

        if (this._isIE6 && this._relativeOrAbsoluteParentElement) {
            var foregroundLocation = this.getLocation(this._foregroundElement);
            var relativeParentLocation = this.getLocation(this._relativeOrAbsoluteParentElement);
            var getLocationXCoord = foregroundLocation.x;
            if (getLocationXCoord != xCoord) {
                // offset it by that amount
                this._foregroundElement.style.left = (xCoord - relativeParentLocation.x) + 'px';
            }

            var getLocationYCoord = foregroundLocation.y;
            if (getLocationYCoord != yCoord) {
                // offset it by that amount
                this._foregroundElement.style.top = (yCoord - relativeParentLocation.y) + 'px';
            }
        }
    },

    _layoutBackgroundElement : function() {
        /// <summary>
        /// Set the correct location of the background element to ensure that it is absolutely
        /// positioned with respect to the browser.
        /// </summary>

        // Background element needs to cover the visible client area completely hence its
        // top and left coordinates need to be 0, and if relatively positioned its getlocation
        // value needs to be 0.
        if(this._isIE6) {
            var backgroundLocation = this.getLocation(this._backgroundElement);
            var backgroundXCoord = backgroundLocation.x;
            if (backgroundXCoord != 0) {
                // offset it by that amount. This is assuming only one level of nesting. If
                // multiple parents with absolute/relative positioning are setup this may not
                // cover the whole background.
                this._backgroundElement.style.left = (-backgroundXCoord) + 'px';
            }

            var backgroundYCoord = backgroundLocation.y;
            if (backgroundYCoord != 0) {
                // offset it by that amount. This is assuming only one level of nesting. If
                // multiple parents with absolute/relative positioning are setup this may not
                // cover the whole background.
                this._backgroundElement.style.top = (-backgroundYCoord) + 'px';
            }
        }
        var clientBounds = this.getClientBounds();
        var clientWidth = clientBounds.width;
        var clientHeight = clientBounds.height;
        this._backgroundElement.style.width = Math.max(Math.max(document.documentElement.scrollWidth, document.body.scrollWidth), clientWidth)+'px';
        this._backgroundElement.style.height = Math.max(Math.max(document.documentElement.scrollHeight, document.body.scrollHeight), clientHeight)+'px';
    },

    _attachPopup : function() {
        /// <summary>
        /// Attach the event handlers for the popup
        /// </summary>

        $addHandler(window, 'resize', this._resizeHandler);
        $addHandler(window, 'scroll', this._scrollHandler);
        this._windowHandlersAttached = true;
    },

    _hideDetails : function(ev) {
        if (!this._closeElement.disabled) {
            this.hide();
            //e.preventDefault();
            return false;
        }
    },

    hide : function() {
        /// <summary>
        /// Hide the modal dialog
        /// </summary>
        /// <returns type="Boolean" mayBeNull="false">
        /// Whether or not the dialog was hidden
        /// </returns>

        /*var eventArgs = new Sys.CancelEventArgs();
        this.raiseHiding(eventArgs);
        if (eventArgs.get_cancel()) {
            return false;
        }*/

        this._backgroundElement.style.display = 'none';
        this._foregroundElement.style.display = 'none';

        this.restoreTab();

        this._detachPopup();

        //this.raiseHidden(Sys.EventArgs.Empty);
        return true;
    },

    _detachPopup : function() {
        /// <summary>
        /// Detach the event handlers for the popup
        /// </summary>

        if (this._windowHandlersAttached) {
            if (this._scrollHandler) {
                $removeHandler(window, 'scroll', this._scrollHandler);
            }

            if (this._resizeHandler) {
                $removeHandler(window, 'resize', this._resizeHandler);
            }
            this._windowHandlersAttached = false;
        }
    },

    disableTab : function() {
        /// <summary>
        /// Change the tab indices so we only tab through the modal popup
        /// (and hide SELECT tags in IE6)
        /// </summary>

        var i = 0;
        var tagElements;
        var tagElementsInPopUp = new Array();
        Array.clear(this._saveTabIndexes);

        //Save all popup's tag in tagElementsInPopUp
        for (var j = 0; j < this._tagWithTabIndex.length; j++) {
            tagElements = this._foregroundElement.getElementsByTagName(this._tagWithTabIndex[j]);
            for (var k = 0 ; k < tagElements.length; k++) {
                tagElementsInPopUp[i] = tagElements[k];
                i++;
            }
        }

        i = 0;
        for (var j = 0; j < this._tagWithTabIndex.length; j++) {
            tagElements = document.getElementsByTagName(this._tagWithTabIndex[j]);
            for (var k = 0 ; k < tagElements.length; k++) {
                if (Array.indexOf(tagElementsInPopUp, tagElements[k]) == -1)  {
                    this._saveTabIndexes[i] = {tag: tagElements[k], index: tagElements[k].tabIndex};
                    tagElements[k].tabIndex="-1";
                    i++;
                }
            }
        }

        //IE6 Bug with SELECT element always showing up on top
        i = 0;
        if ((Sys.Browser.agent === Sys.Browser.InternetExplorer) && (Sys.Browser.version < 7)) {
            //Save SELECT in PopUp
            var tagSelectInPopUp = new Array();
            for (var j = 0; j < this._tagWithTabIndex.length; j++) {
                tagElements = this._foregroundElement.getElementsByTagName('SELECT');
                for (var k = 0 ; k < tagElements.length; k++) {
                    tagSelectInPopUp[i] = tagElements[k];
                    i++;
                }
            }

            i = 0;
            Array.clear(this._saveDesableSelect);
            tagElements = document.getElementsByTagName('SELECT');
            for (var k = 0 ; k < tagElements.length; k++) {
                if (Array.indexOf(tagSelectInPopUp, tagElements[k]) == -1)  {
                    this._saveDesableSelect[i] = {tag: tagElements[k], visib: this.getCurrentStyle(tagElements[k], 'visibility')} ;
                    tagElements[k].style.visibility = 'hidden';
                    i++;
                }
            }
        }
    },

    restoreTab : function() {
        /// <summary>
        /// Restore the tab indices so we tab through the page like normal
        /// (and restore SELECT tags in IE6)
        /// </summary>

        for (var i = 0; i < this._saveTabIndexes.length; i++) {
            this._saveTabIndexes[i].tag.tabIndex = this._saveTabIndexes[i].index;
        }

        //IE6 Bug with SELECT element always showing up on top
        if ((Sys.Browser.agent === Sys.Browser.InternetExplorer) && (Sys.Browser.version < 7)) {
            for (var k = 0 ; k < this._saveDesableSelect.length; k++) {
                this._saveDesableSelect[k].tag.style.visibility = this._saveDesableSelect[k].visib;
            }
        }
    },

    getCurrentStyle : function(element, attribute, defaultValue) {
        var currentValue = null;
        if (element) {
            if (element.currentStyle) {
                currentValue = element.currentStyle[attribute];
            } else if (document.defaultView && document.defaultView.getComputedStyle) {
                var style = document.defaultView.getComputedStyle(element, null);
                if (style) {
                    currentValue = style[attribute];
                }
            }

            if (!currentValue && element.style.getPropertyValue) {
                currentValue = element.style.getPropertyValue(attribute);
            } else if (!currentValue && element.style.getAttribute) {
                currentValue = element.style.getAttribute(attribute);
            }
        }

        if ((!currentValue || currentValue == "" || typeof(currentValue) === 'undefined')) {
            if (typeof(defaultValue) != 'undefined') {
                currentValue = defaultValue;
            } else {
                currentValue = null;
            }
        }
        return currentValue;
    },

    getClientBounds : function() {
        var clientWidth;
        var clientHeight;

        switch(Sys.Browser.agent) {
            case Sys.Browser.InternetExplorer:
                clientWidth = document.documentElement.clientWidth;
                clientHeight = document.documentElement.clientHeight;
                break;
            case Sys.Browser.Safari:
                clientWidth = window.innerWidth;
                clientHeight = window.innerHeight;
                break;
            case Sys.Browser.Opera:
                clientWidth = Math.min(window.innerWidth, document.body.clientWidth);
                clientHeight = Math.min(window.innerHeight, document.body.clientHeight);
                break;
            default:
                clientWidth = Math.min(window.innerWidth, document.documentElement.clientWidth);
                clientHeight = Math.min(window.innerHeight, document.documentElement.clientHeight);
                break;
        }
        return new Sys.UI.Bounds(0, 0, clientWidth, clientHeight);
    },

    getLocation : function(element) {
        if (element === document.documentElement) {
            return new Sys.UI.Point(0,0);
        }
        if (Sys.Browser.agent == Sys.Browser.InternetExplorer && Sys.Browser.version < 7) {
            if (element.window === element || element.nodeType === 9 || !element.getClientRects || !element.getBoundingClientRect) {
                return new Sys.UI.Point(0,0);
            }
            var screenRects = element.getClientRects();
            if (!screenRects || !screenRects.length) {
                return new Sys.UI.Point(0,0);
            }

            var first = screenRects[0];
            var dLeft = 0;
            var dTop = 0;
            var inFrame = false;

            try {
                inFrame = element.ownerDocument.parentWindow.frameElement;
            } catch(ex) {
                inFrame = true;
            }

            if (inFrame) {
                var clientRect = element.getBoundingClientRect();
                if (!clientRect) {
                    return new Sys.UI.Point(0,0);
                }
                var minLeft = first.left;
                var minTop = first.top;

                for (var i = 1;i < screenRects.length;i++) {
                    var r = screenRects[i];
                    if (r.left < minLeft) {
                        minLeft = r.left;
                    }
                    if (r.top < minTop) {
                        minTop = r.top;
                    }
                }

                dLeft = minLeft - clientRect.left;
                dTop = minTop - clientRect.top;
            }
            var ownerDocument = element.document.documentElement;
            return new Sys.UI.Point(first.left - 2 - dLeft + ownerDocument.scrollLeft, first.top - 2 - dTop + ownerDocument.scrollTop);
        }
        return Sys.UI.DomElement.getLocation(element);
    },

    _last : function() {
    }
}