﻿
CustomValidatorCallout = {
    _warningIconImageUrl: null,
    _closeImageUrl: null,
    _width: "200px",
    _popupTable: null,
    _errorMessageCell: null,
    _calloutArrowCell: null,
    _warningIconImage: null,
    _closeImage: null,
    _popupBehavior: null,
    _focusAttached: false,
    _isOpen: false,
    _isBuilt: false,
    _closeClickHandler: null, //Function.createDelegate(this, this._oncloseClick),
    _focusHandler: null, //Function.createDelegate(this, this._onfocus),
    _cache: {},
    _isValid: null,
    _errMsg: null,
    _valOpenId: "",

    _ensureCallout: function(ctrlId) {
        var elt = $get(ctrlId);
        var popupTableBody = document.createElement("tbody");
        var popupTableRow = document.createElement("tr");
        var calloutCell = document.createElement("td");
        var calloutTable = document.createElement("table");
        var calloutTableBody = document.createElement("tbody");
        var calloutTableRow = document.createElement("tr");
        var iconCell = document.createElement("td");
        var closeCell = document.createElement("td");
        var popupTable = this._popupTable = document.createElement("table");
        var calloutArrowCell = this._calloutArrowCell = document.createElement("td");
        var warningIconImage = this._warningIconImage = document.createElement("img");
        var closeImage = this._closeImage = document.createElement("img");
        var errorMessageCell = this._errorMessageCell = document.createElement("td");
        //
        // popupTable
        //
        popupTable.id = elt.id + "_popupTable";
        popupTable.cellPadding = 0;
        popupTable.cellSpacing = 0;
        popupTable.border = 0;
        popupTable.width = this._width;
        popupTable.style.zIndex = 20;
        popupTable.style.display = 'none';
        //
        // popupTableRow
        //
        popupTableRow.vAlign = 'top';
        popupTableRow.style.height = "100%";
        //
        // calloutCell
        //
        calloutCell.width = 20;
        if (this.screenSpaceAvailable(elt) == true) { calloutCell.align = "right"; }
        else { calloutCell.align = "left"; }
        calloutCell.style.height = "100%";
        calloutCell.style.verticalAlign = "top";
        //
        // calloutTable
        //
        calloutTable.cellPadding = 0;
        calloutTable.cellSpacing = 0;
        calloutTable.border = 0;
        calloutTable.style.height = "100%";
        //
        // _calloutArrowCell
        //
        if (this.screenSpaceAvailable(elt) == true) { calloutArrowCell.align = "right"; }
        else { calloutArrowCell.align = "left"; }
        calloutArrowCell.vAlign = "top";
        calloutArrowCell.style.fontSize = "1px";
        calloutArrowCell.style.paddingTop = "8px";
        //
        // iconCell
        //
        iconCell.width = 20;
        iconCell.style.borderTop = "1px solid black";
        if (this.screenSpaceAvailable(elt) == true) { iconCell.style.borderLeft = "1px solid black"; }
        else { iconCell.style.borderRight = "1px solid black"; }
        iconCell.style.borderBottom = "1px solid black";
        iconCell.style.padding = "5px";
        iconCell.style.backgroundColor = 'LemonChiffon';
        //
        // _warningIconImage
        //
        warningIconImage.border = 0;
        warningIconImage.src = custvalImgUrl.Alert;
        //
        // _errorMessageCell
        //
        errorMessageCell.style.backgroundColor = 'LemonChiffon';
        errorMessageCell.style.fontFamily = 'verdana';
        errorMessageCell.style.fontSize = '10px';
        errorMessageCell.style.padding = "5px";
        errorMessageCell.style.borderTop = "1px solid black";
        errorMessageCell.style.borderBottom = "1px solid black";
        errorMessageCell.width = '100%';
        errorMessageCell.innerHTML = "error";
        //
        // closeCell
        //
        closeCell.style.borderTop = "1px solid black";
        if (this.screenSpaceAvailable(elt) == true) { closeCell.style.borderRight = "1px solid black"; }
        else { closeCell.style.borderLeft = "1px solid black"; }
        closeCell.style.borderBottom = "1px solid black";
        closeCell.style.backgroundColor = 'lemonchiffon';
        closeCell.style.verticalAlign = 'top';
        closeCell.style.textAlign = 'right';
        closeCell.style.padding = '2px';
        //
        // closeImage
        //
        closeImage.src = custvalImgUrl.Close;
        closeImage.style.cursor = 'pointer';
        closeImage.id = elt.id + "_close";
        //
        // Create the DOM tree
        //

        if (elt.parentNode != null) { elt.parentNode.appendChild(popupTable); }
        else { elt.appendChild(popupTable); }
        if (this.screenSpaceAvailable(elt) == true) {
            popupTable.appendChild(popupTableBody);
            popupTableBody.appendChild(popupTableRow);
            popupTableRow.appendChild(calloutCell);
            calloutCell.appendChild(calloutTable);
            calloutTable.appendChild(calloutTableBody);
            calloutTableBody.appendChild(calloutTableRow);
            calloutTableRow.appendChild(calloutArrowCell);
            popupTableRow.appendChild(iconCell);
            iconCell.appendChild(warningIconImage);
            popupTableRow.appendChild(errorMessageCell);
            popupTableRow.appendChild(closeCell);
            closeCell.appendChild(closeImage);
        }
        else {
            popupTable.appendChild(popupTableBody);
            popupTableBody.appendChild(popupTableRow);
            popupTableRow.appendChild(closeCell);
            closeCell.appendChild(closeImage);
            popupTableRow.appendChild(errorMessageCell);
            popupTableRow.appendChild(iconCell);
            iconCell.appendChild(warningIconImage);
            calloutTable.appendChild(calloutTableBody);
            calloutTableBody.appendChild(calloutTableRow);
            calloutTableRow.appendChild(calloutArrowCell);
            popupTableRow.appendChild(calloutCell);
            calloutCell.appendChild(calloutTable);
        }
        //
        // initialize callout arrow
        //
        var div = document.createElement("div");
        div.style.fontSize = "1px";
        div.style.position = "relative";
        if (this.screenSpaceAvailable(elt) == true) { div.style.left = "1px"; }
        else { div.style.right = "1px"; }
        div.style.borderTop = "1px solid black";
        div.style.width = "15px";
        calloutArrowCell.appendChild(div);
        for (var i = 14; i > 0; i--) {
            var line = document.createElement("div");
            line.style.width = i.toString() + "px";
            line.style.height = "1px";
            line.style.overflow = "hidden";
            line.style.backgroundColor = "LemonChiffon";
            if (this.screenSpaceAvailable(elt) == true) { line.style.borderLeft = "1px solid black"; }
            else { line.style.borderRight = "1px solid black"; }
            div.appendChild(line);
        }
        //
        // initialize behaviors

        this._popupBehavior = new PopupBehavior(this._popupTable, elt, "");
        $addHandler(this._closeImage, "click", this._closeClickHandler);
        $addHandler(elt, "focus", this._focusHandler);
        this._cache[elt.id] = this._popupBehavior;
        this._isBuilt = true;
    },

    _oncloseClick: function(e) {
        this._popupBehavior.hide();
        this._isOpen = false;
    },

    _onfocus: function(e) {
        this.getElement(e.target.id);
    },

    getElement: function(ctrlid) {
        if (this._cache[ctrlid]) {
            for (var key in this._cache) {
                if (key != ctrlid && this._cache[key]._visible == true) {
                    if (this._isOpen) {
                        if (this._popupBehavior == this._cache[key]) {
                            this._popupBehavior.hide();
                            this._isOpen = false;
                        }
                    }
                }
            }

            if (this._cache[ctrlid]._visible == false) {
                var ele = document.getElementById(ctrlid);
                if (ele.custvalid) {
                    var val;
                    for (var i = 0; i <= ele.custvalid.length - 1; i++) {
                        var valctrl = $get(ele.custvalid[i]);
                        if (valctrl != null && valctrl.isvalid == false) {
                            val = valctrl;
                        }
                    }
                    if (val)
                        OnValidate(val);
                }
            }
        }
    },

    dispose: function() {

        if (this._isBuilt) {
            this._oncloseClick();

            if (this._popupBehavior) {
                this._popupBehavior = null;
                this._cache = {};
            }

            if (this._popupTable) {
                if (this._popupTable.parentNode)
                    this._popupTable.parentNode.removeChild(this._popupTable);

                this._popupTable = null;
                this._errorMessageCell = null;
                this._calloutArrowCell = null;
                this._warningIconImage = null;
                this._closeImage = null;
                this._closeCellInnerDiv = null;
            }
            this._isBuilt = false;
        }
    },

    validateCtrl: function(val) {
        var elt = $get(val.controltovalidate);
        if (this._closeClickHandler == null)
            this._closeClickHandler = Function.createDelegate(this, this._oncloseClick);

        if (this._focusHandler == null)
            this._focusHandler = Function.createDelegate(this, this._onfocus);

        if (val.isopen == null) {
            val.isopen = false;
        }

        if (elt.isopen == null) {
            elt.isopen = false;
        }

        if (!val.isvalid) {
            $addHandler(elt, "focus", this._focusHandler);
            if (!this._isOpen) {
                if (this._cache != null) {
                    if (this._cache[val.controltovalidate] == null) {
                    this._ensureCallout(val.controltovalidate); }
                    else if (this._cache[val.controltovalidate]._visible == false)
                    { this._ensureCallout(val.controltovalidate); }
                }
                else
                { this._ensureCallout(val.controltovalidate); }

                if (this._errorMessageCell != null)
                { this._errorMessageCell.innerHTML = val.errormessage; }

                this._popupBehavior = this._cache[val.controltovalidate];
                this._popupBehavior.set_x(this.calculatePosition(elt, this._popupBehavior._element));
                this._popupBehavior.show();
                val.isopen = true;
                elt.isopen = true;
                this._isOpen = true;
                this._valOpenId = val.id;
            }
            else {
                if (this._cache[val.controltovalidate] == null) {
                    this._cache[val.controltovalidate] = new PopupBehavior(null, val.controltovalidate, val.errormessage);
                }
                else {
                    if (this._popupBehavior == this._cache[val.controltovalidate]) {
                        if (this._errorMessageCell != null) {
                            this._errorMessageCell.innerHTML = val.errormessage;
                        }
                    }
                }
            }
        }
        else {
            if (this._isOpen) {
                if (this._popupBehavior == this._cache[val.controltovalidate]) {
                    if (val.isopen == true) {
                        this._popupBehavior.hide();
                        this._isOpen = false;
                        val.isopen = false;
                    }
                }

                //                if (this._cache[val.controltovalidate] != null) {
                //                    $removeHandler(elt, "focus", this._focusHandler);
                //                    delete this._cache[val.controltovalidate];
                //                }
            }
        }
    },

    screenSpaceAvailable: function(trgtctrl) {
        var xsDiv = null;
        var ysDiv = null;
        var oPos = trgtctrl;
        var xsDiv = this.calculateLeft(trgtctrl);
        var iPopW = parseInt(this._width, 10) + 15;

        if (xsDiv + iPopW + trgtctrl.offsetWidth > screen.width) {
            return false;
        }
        else {
            return true;
        }
    },

    calculatePosition: function(trgtctrl, frame) {
        var xsDiv = null;
        var ysDiv = null;
        var oPos = trgtctrl;
        var oDiv = frame;
        var xsDiv = this.calculateLeft(trgtctrl);
        var iPopW = parseInt(oDiv.width, 10) + 15;

        if (xsDiv + iPopW + trgtctrl.offsetWidth > screen.width) {
            xsDiv = 0 - parseInt(oDiv.width);
        }
        else {
            xsDiv = this._popupBehavior._getSize(trgtctrl).width;
        }
        return xsDiv;
    },

    calculateLeft: function(obj) {
        toreturn = 0;
        while (obj) {
            toreturn += obj.offsetLeft;
            obj = obj.offsetParent;
        }
        return toreturn;
    }


} // End of Callout JSON Object

    PopupBehavior = function(element, parentElement, errorMessage) {
        this._x = 0;
        this._y = 0;
        this._parentElement = parentElement;

        if (element != null) {
            this._element = element;
            this._setVisible(element, false);
            this._element.style.position = "absolute";
        }
        this._visible = false;
        this._isValid = false;
        this._errMsg = errorMessage;
    },

PopupBehavior.prototype = {

    _borderStyleNames: ["borderTopStyle", "borderRightStyle", "borderBottomStyle", "borderLeftStyle"],
    _borderWidthNames: ["borderTopWidth", "borderRightWidth", "borderBottomWidth", "borderLeftWidth"],
    _paddingWidthNames: ["paddingTop", "paddingRight", "paddingBottom", "paddingLeft"],
    _marginWidthNames: ["marginTop", "marginRight", "marginBottom", "marginLeft"],

    show: function() {
        if (this._visible) {
            return;
        }
        this._visible = true;
        this._setVisible(this._element, true);
        var bounds = this.getBounds();
        this._setLocation(this._element, bounds);

        this.adjustPopupPosition(bounds);
        this._element.zIndex = 1000;
        this.addBackgroundIFrame();
    },

    hide: function() {
        if (!this._visible) {
            return;
        }
        this._visible = false;
        this._setVisible(this._element, false);
        if (Sys.Browser.agent === Sys.Browser.InternetExplorer) {
            var childFrame = this._element._hideWindowedElementsIFrame;
            if (childFrame) {
                childFrame.style.display = "none";
            }
        }
    },

    getBounds: function() {

        var element = this._element;
        var elm = element;
        if (elm.offsetParent == null) {
            elm = document.documentElement;
        }
        else {
            for (;
            elm && elm.offsetParent != document.body && elm.offsetParent != document.documentElement;
            elm = elm.offsetParent
            );
        }
        var offsetParent = elm;
        var diff;
        var parentBounds;
        if (this._parentElement) {
            parentBounds = this._getBounds(this._parentElement);

            if (this._element.id == offsetParent.id) {
                diff = { x: parentBounds.x, y: parentBounds.y };
            } else {
                var offsetParentLocation = this._getLocation(offsetParent);
                diff = { x: parentBounds.x - offsetParentLocation.x, y: parentBounds.y - offsetParentLocation.y };
            }
        } else {
            parentBounds = this._getBounds(offsetParent);
            diff = { x: 0, y: 0 };
        }

        var width = element.offsetWidth - (element.clientLeft ? element.clientLeft * 2 : 0);
        var height = element.offsetHeight - (element.clientTop ? element.clientTop * 2 : 0);

        // Setting the width causes the element to grow by border+passing every
        // time.  But not setting it causes strange behavior in safari. Just set it once.

        var position;
        position = { x: 0, y: 0 };
        position.x += this._x + diff.x;
        position.y += this._y + diff.y;

        return new Sys.UI.Bounds(position.x, position.y, width, height);
    },

    adjustPopupPosition: function(bounds) {

        var element = this._element;
        if (!bounds) {
            bounds = this.getBounds();
        }

        var newPosition = this._getBounds(element);
        var updateNeeded = false;

        if (newPosition.x < 0) {
            bounds.x -= newPosition.x;
            updateNeeded = true;
        }
        if (newPosition.y < 0) {
            bounds.y -= newPosition.y;
            updateNeeded = true;
        }

        if (updateNeeded) {
            this._setLocation(element, bounds);
        }
    },


    addBackgroundIFrame: function() {
        /// <summary>
        /// Add an empty IFRAME behind the popup (for IE6 only) so that SELECT, etc., won't
        /// show through the popup.
        /// </summary>

        // Get the child frame

        if ((Sys.Browser.agent === Sys.Browser.InternetExplorer) && (Sys.Browser.version < 7)) {
            var element = this._element;
            var childFrame = element._hideWindowedElementsIFrame;

            // Create the child frame if it wasn't found
            if (!childFrame) {
                childFrame = document.createElement("iframe");
                childFrame.src = "javascript:'<html></html>';";
                childFrame.style.position = "absolute";
                childFrame.style.display = "none";
                childFrame.scrolling = "no";
                childFrame.frameBorder = "0";
                childFrame.tabIndex = "-1";
                childFrame.style.filter = "progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)";
                element.parentNode.insertBefore(childFrame, element);
                element._hideWindowedElementsIFrame = childFrame;
            }

            // Position the frame exactly behind the element
            this.setBounds(childFrame, this.getBounds());
            childFrame.style.display = element.style.display;
            if (element.currentStyle && element.currentStyle.zIndex) {
                childFrame.style.zIndex = element.currentStyle.zIndex;
            } else if (element.style.zIndex) {
                childFrame.style.zIndex = element.style.zIndex;
            }
        }
    },

    setBounds: function(element, bounds) {
        /// <summary>
        /// Sets the "border-box" bounds of an element
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <param name="bounds" type="Object">
        /// Bounds of the element (of the form {x,y,width,height})
        /// </param>
        /// <remarks>
        /// The "border-box" is the size of the content area *outside* of the borders and
        /// padding of an element.  The "border-box" size does not include the margins around
        /// the element.
        /// </remarks>

        if (!element) {
            throw Error.argumentNull('element');
        }
        if (!bounds) {
            throw Error.argumentNull('bounds');
        }
        this.setSize(element, bounds);
        this._setLocation(element, bounds);
    },

    setContentSize: function(element, size) {
        /// <summary>
        /// Sets the "content-box" size of an element.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <param name="size" type="Object">
        /// Size of the element (in the form {width,height})
        /// </param>
        /// <remarks>
        /// The "content-box" is the size of the content area *inside* of the borders and
        /// padding of an element. The "content-box" size does not include the margins around
        /// the element.
        /// </remarks>

        if (!element) {
            throw Error.argumentNull('element');
        }
        if (!size) {
            throw Error.argumentNull('size');
        }
        // FF respects -moz-box-sizing css extension, so adjust the box size for the border-box
        if (this._getCurrentStyle(element, 'MozBoxSizing') == 'border-box' || this._getCurrentStyle(element, 'BoxSizing') == 'border-box') {
            var borderBox = this.getBorderBox(element);
            var paddingBox = this.getPaddingBox(element);
            size = {
                width: size.width + borderBox.horizontal + paddingBox.horizontal,
                height: size.height + borderBox.vertical + paddingBox.vertical
            };
        }
        element.style.width = size.width.toString() + 'px';
        element.style.height = size.height.toString() + 'px';
    },

    setSize: function(element, size) {
        /// <summary>
        /// Sets the "border-box" size of an element.
        /// </summary>
        /// <remarks>
        /// The "border-box" is the size of the content area *outside* of the borders and 
        /// padding of an element.  The "border-box" size does not include the margins around
        /// the element.
        /// </remarks>
        /// <param name="element" type="Sys.UI.DomElement">DOM element</param>
        /// <param name="size" type="Object">Size of the element (in the form {width,height})</param>
        /// <returns />

        if (!element) {
            throw Error.argumentNull('element');
        }
        if (!size) {
            throw Error.argumentNull('size');
        }
        var borderBox = this.getBorderBox(element);
        var paddingBox = this.getPaddingBox(element);
        var contentSize = {
            width: size.width - borderBox.horizontal - paddingBox.horizontal,
            height: size.height - borderBox.vertical - paddingBox.vertical
        };
        this.setContentSize(element, contentSize);
    },

    getBorderBox: function(element) {
        /// <summary>
        /// Gets the entire border box sizes.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <returns type="Object">
        /// Element's border box sizes (of the form {top,left,bottom,right,horizontal,vertical})
        /// </returns>

        if (!element) {
            throw Error.argumentNull('element');
        }
        var box = {
            top: this.getBorderWidth(element, 0),
            right: this.getBorderWidth(element, 1),
            bottom: this.getBorderWidth(element, 2),
            left: this.getBorderWidth(element, 3)
        };
        box.horizontal = box.left + box.right;
        box.vertical = box.top + box.bottom;
        return box;
    },

    getPaddingBox: function(element) {
        /// <summary>
        /// Gets the entire padding box sizes.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <returns type="Object">
        /// Element's padding box sizes (of the form {top,left,bottom,right,horizontal,vertical})
        /// </returns>

        if (!element) {
            throw Error.argumentNull('element');
        }
        var box = {
            top: this.getPadding(element, 0),
            right: this.getPadding(element, 1),
            bottom: this.getPadding(element, 2),
            left: this.getPadding(element, 3)
        };
        box.horizontal = box.left + box.right;
        box.vertical = box.top + box.bottom;
        return box;
    },

    isBorderVisible: function(element, boxSide) {
        /// <summary>
        /// Gets whether the current border style for an element on a specific boxSide is not 'none'.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <param name="boxSide" type="AjaxControlToolkit.BoxSide">
        /// Side of the element
        /// </param>
        /// <returns type="Boolean">
        /// Whether the current border style for an element on a specific boxSide is not 'none'.
        /// </returns>

        if (!element) {
            throw Error.argumentNull('element');
        }
        if (boxSide < 0 || boxSide > 3) {
            throw Error.argumentOutOfRange(String.format(Sys.Res.enumInvalidValue, boxSide, 'AjaxControlToolkit.BoxSide'));
        }

        var styleName = this._borderStyleNames[boxSide];
        var styleValue = this._getCurrentStyle(element, styleName);
        return styleValue != "none";
    },

    getBorderWidth: function(element, boxSide) {
        /// <summary>
        /// Gets the border thickness of an element on a specific boxSide.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <param name="boxSide" type="AjaxControlToolkit.BoxSide">
        /// Side of the element
        /// </param>
        /// <returns type="Number" integer="true">
        /// Border thickness on the element's specified side
        /// </returns>

        if (!element) {
            throw Error.argumentNull('element');
        }
        if (boxSide < 0 || boxSide > 3) {

            throw Error.argumentOutOfRange(String.format(Sys.Res.enumInvalidValue, boxSide, 'AjaxControlToolkit.BoxSide'));
        }

        if (!this.isBorderVisible(element, boxSide)) {
            return 0;
        }
        var styleName = this._borderWidthNames[boxSide];
        var styleValue = this._getCurrentStyle(element, styleName);

        return this.parseBorderWidth(styleValue);
    },

    getPadding: function(element, boxSide) {
        /// <summary>
        /// Gets the padding thickness of an element on a specific boxSide.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <param name="boxSide" type="AjaxControlToolkit.BoxSide">
        /// Side of the element
        /// </param>
        /// <returns type="Number" integer="true">
        /// Padding on the element's specified side
        /// </returns>

        if (!element) {
            throw Error.argumentNull('element');
        }
        if (boxSide < 0 || boxSide > 3) {
            throw Error.argumentOutOfRange(String.format(Sys.Res.enumInvalidValue, boxSide, 'AjaxControlToolkit.BoxSide'));
        }
        var styleName = this._paddingWidthNames[boxSide];
        var styleValue = this._getCurrentStyle(element, styleName);
        return this.parsePadding(styleValue);
    },

    parseBorderWidth: function(borderWidth) {

        /// <summary>
        /// Parses a border-width string into a pixel size
        /// </summary>
        /// <param name="borderWidth" type="String" mayBeNull="true">
        /// Type of border ('thin','medium','thick','inherit',px unit,null,'')
        /// </param>
        /// <returns type="Number" integer="true">
        /// Number of pixels in the border-width
        /// </returns>
        if (!this._borderThicknesses) {

            // Populate the borderThicknesses lookup table
            var borderThicknesses = {};
            var div0 = document.createElement('div');
            div0.style.visibility = 'hidden';
            div0.style.position = 'absolute';
            div0.style.fontSize = '1px';
            document.body.appendChild(div0)
            var div1 = document.createElement('div');
            div1.style.height = '0px';
            div1.style.overflow = 'hidden';
            div0.appendChild(div1);
            var base = div0.offsetHeight;
            div1.style.borderTop = 'solid black';
            div1.style.borderTopWidth = 'thin';
            borderThicknesses['thin'] = div0.offsetHeight - base;
            div1.style.borderTopWidth = 'medium';
            borderThicknesses['medium'] = div0.offsetHeight - base;
            div1.style.borderTopWidth = 'thick';
            borderThicknesses['thick'] = div0.offsetHeight - base;
            div0.removeChild(div1);
            document.body.removeChild(div0);
            this._borderThicknesses = borderThicknesses;
        }

        if (borderWidth) {
            switch (borderWidth) {
                case 'thin':
                case 'medium':
                case 'thick':
                    return this._borderThicknesses[borderWidth];
                case 'inherit':
                    return 0;
            }
            var unit = this.parseUnit(borderWidth);
            Sys.Debug.assert(unit.type == 'px', String.format(AjaxControlToolkit.Resources.Common_InvalidBorderWidthUnit, unit.type));
            return unit.size;
        }
        return 0;
    },

    parsePadding: function(padding) {
        /// <summary>
        /// Parses a padding string into a pixel size
        /// </summary>
        /// <param name="padding" type="String" mayBeNull="true">
        /// Padding to parse ('inherit',px unit,null,'')
        /// </param>
        /// <returns type="Number" integer="true">
        /// Number of pixels in the padding
        /// </returns>

        if (padding) {
            if (padding == 'inherit') {
                return 0;
            }
            var unit = this.parseUnit(padding);
            Sys.Debug.assert(unit.type == 'px', String.format(AjaxControlToolkit.Resources.Common_InvalidPaddingUnit, unit.type));
            return unit.size;
        }
        return 0;
    },

    parseUnit: function(value) {
        /// <summary>
        /// Parses a unit string into a unit object
        /// </summary>
        /// <param name="value" type="String" mayBeNull="true">
        /// Value to parse (of the form px unit,% unit,em unit,...)
        /// </param>
        /// <returns type="Object">
        /// Parsed unit (of the form {size,type})
        /// </returns>

        if (!value) {
            throw Error.argumentNull('value');
        }

        value = value.trim().toLowerCase();
        var l = value.length;
        var s = -1;
        for (var i = 0; i < l; i++) {
            var ch = value.substr(i, 1);
            if ((ch < '0' || ch > '9') && ch != '-' && ch != '.' && ch != ',') {
                break;
            }
            s = i;
        }
        if (s == -1) {
            throw Error.create(AjaxControlToolkit.Resources.Common_UnitHasNoDigits);
        }
        var type;
        var size;
        if (s < (l - 1)) {
            type = value.substring(s + 1).trim();
        } else {
            type = 'px';
        }
        size = parseFloat(value.substr(0, s + 1));
        if (type == 'px') {
            size = Math.floor(size);
        }
        return {
            size: size,
            type: type
        };
    },

    set_x: function(value) {
        if (value != this._x) {
            this._x = value;
            if (this._visible) {
                this.setupPopup();
            }
        }
    },

    _getLocation: function(element) {
        if (element === document.documentElement) {
            return new Sys.UI.Point(0, 0);
        }

        // Workaround for IE6 bug in getLocation (also required patching getBounds - remove that fix when this is removed)
        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);

            // Get the first bounding rectangle in screen coordinates
            var screenRects = element.getClientRects();
            if (!screenRects || !screenRects.length) {
                return new Sys.UI.Point(0, 0);
            }
            var first = screenRects[0];

            // Delta between client coords and screen coords
            var dLeft = 0;
            var dTop = 0;

            var inFrame = false;
            try {
                inFrame = element.ownerDocument.parentWindow.frameElement;
            } catch (ex) {
                // If accessing the frameElement fails, a frame is probably in a different
                // domain than its parent - and we still want to do the calculation below
                inFrame = true;
            }

            // If we're in a frame, get client coordinates too so we can compute the delta
            if (inFrame) {
                // Get the bounding rectangle in client coords
                var clientRect = element.getBoundingClientRect();
                if (!clientRect) {
                    return new Sys.UI.Point(0, 0);
                }

                // Find the minima in screen coords
                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;
                    }
                }

                // Compute the delta between screen and client coords
                dLeft = minLeft - clientRect.left;
                dTop = minTop - clientRect.top;
            }

            // Subtract 2px, the border of the viewport (It can be changed in IE6 by applying a border style to the HTML element,
            // but this is not supported by ASP.NET AJAX, and it cannot be changed in IE7.), and also subtract the delta between
            // screen coords and client coords
            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);
    },

    _setLocation: function(element, point) {
        Sys.UI.DomElement.setLocation(element, point.x, point.y);
    },

    _getSize: function(element) {

        if (!element) {
            throw Error.argumentNull('element');
        }
        return {
            width: element.offsetWidth,
            height: element.offsetHeight
        };
    },

    _getBounds: function(element) {

        var offset = this._getLocation(element);
        return new Sys.UI.Bounds(offset.x, offset.y, element.offsetWidth || 0, element.offsetHeight || 0);
    },

    _getVisible: function(element) {
        return (element &&
                ("none" != this._getCurrentStyle(element, "display")) &&
                ("hidden" != this._getCurrentStyle(element, "visibility")));
    },

    _setVisible: function(element, value) {

        if (element && value != this._getVisible(element)) {

            element.style.visibility = value ? 'visible' : 'hidden';
            element.style.display = value ? 'block' : 'none';
        }
    },

    _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;
    }
}// End of PopupBehavior JSON Object


    //    document.body.onload = funct;

    //    function funct() {

    //    }

function OnValidate(val) {
        val.isvalid = val.oldevaluationfunction(val);
        if (val.isvalid == false) {
            if (val.innerHTML != null && val.innerHTML != "") {
                if (val.errormessage == null || val.errormessage == "") {
                    val.errormessage = val.innerHTML; 
                }
                val.innerHTML = "";
            }
        }
        CustomValidatorCallout.validateCtrl(val);
        return val.isvalid;
    }


    Sys.Application.add_load(BeginRequestHandler);

    function BeginRequestHandler() {
        if (!(typeof Page_Validators == "undefined" || Page_Validators == null)) {
            CustomValidatorCallout.dispose();
            for (var i = 0; i < Page_Validators.length; i++) {
//                if (Page_Validators[i].id.indexOf("rfvTxtEmail") > 0) {
//                    debugger;
//                                }
                if (Page_Validators[i].getAttribute("allowcustcallout") == null || (Page_Validators[i].getAttribute("allowcustcallout") != null && Page_Validators[i].getAttribute("allowcustcallout") != "0")) {

                    if (Page_Validators[i].controltovalidate != null && Page_Validators[i].controltovalidate != "") {
                        //if (Page_Validators[i].clientvalidationfunction) {
                        var ele = $get(Page_Validators[i].controltovalidate);
                        var test = false;
                        if (ele != null) {
                             if(ele.custvalid == null) {
                                ele.custvalid = [];
                            } 
                            if (Page_Validators[i].valoverride == null) {
                                Page_Validators[i].valoverride = true;
                                Page_Validators[i].oldevaluationfunction = Page_Validators[i].evaluationfunction;
                                Page_Validators[i].evaluationfunction = OnValidate;
                                ele.custvalid[ele.custvalid.length] = Page_Validators[i].id;
                            }
                        }
                                                 
                   
                    }


                }
            }
        }
    }

    

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();