﻿// global client library
// util.js
// version 2.4

/* Changes are mostly removing getAttribute/setAttribute for FF 3.04
   Modified setSelected to define whether the found item is based on text or value property by adding istext param.
*/

Util = {
    ws: /^\s+$/, // regex to check for 1 or more whitespaces
    email: /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i, // regex for email format validation
    url: /^https?:\/\/[a-z0-9-]+\.[a-z0-9-]+\.[a-zA-Z]{2,4}.*$/i, // regex for url format validation
    devurl: /^https?:\/\/(localhost?|omniprog1?)\/.*$/i, // regex for development url format validation
    date: /^\d{1,2}\/\d{1,2}\/\d{2,4}$/, // regex for date format validation
    time: /^\d{1,2}:\d{2}$/, // regex for time
    usnumber: /^1?([\s\.-])?\(?\d{3}\)?([\s\.-])?\d{3}([\s\.-])?\d{4}$/, // regex for us telephone/fax format validation
    isEmail: function(emailtxt) {
        return this.email.test(emailtxt);
    },
    isUrl: function(urltxt) {
        return this.url.test(urltxt) ||
            this.devurl.test(urltxt);
    },
    isDate: function(datetxt) {
        return this.date.test(datetxt);
    },
    isValidDate: function(datetxt) { // MM-DD-YYYY format
        try {
            var flag, darray, year, mo, day, orgyear;
            datetxt = datetxt.replace(this.ws, '');
            var repl = /(\/)/g; // normalize delimiter
            darray = datetxt.replace(repl, '-').split('-');
            darray[0] = darray[0].charAt(0) == 0 ? darray[0].charAt(1) : darray[0];
            darray[1] = darray[1].charAt(0) == 0 ? darray[1].charAt(1) : darray[1];
            mo = parseInt(darray[0]);
            day = parseInt(darray[1]);
            orgyear = parseInt(darray[2]);
            year = parseInt(new Date().getFullYear());
            var months = [{ month: '1', name: 'January', days: '31' }, { month: '2', name: 'February', days: '28' },
                { month: '3', name: 'March', days: '31' }, { month: '4', name: 'April', days: '30' },
                { month: '5', name: 'May', days: '31' }, { month: '6', name: 'June', days: '30' },
                { month: '7', name: 'July', days: '31' }, { month: '8', name: 'August', days: '31' },
                { month: '9', name: 'September', days: '30' }, { month: '10', name: 'October', days: '31' },
                { month: '11', name: 'November', days: '30' }, { month: '12', name: 'December', days: '31'}];
            for (var i = 0; i < months.length; i++) {
                if (months[i].month == mo) {
                    if (months[i].month != 2) { // all but feb.
                        if (day >= 1 && day <= parseInt(months[i].days)) { // check day range
                            if (orgyear >= year - 1 && orgyear <= year + 1) { // check for +/- current year
                                flag = true;
                            }
                            else {
                                flag = false;
                            }
                        }
                        else { // day no good escape
                            flag = false;
                        }
                    }
                    else { // feb only
                        // start by testing for a leap year
                        if ((year % 4) && ((year % 400) || (year % 100))) { // is leap year
                            if (darray[1] > 0 && darray[1] <= 29) { // check day range
                                if (orgyear >= year - 1 && orgyear <= year + 1) { // check for +/- current year
                                    flag = true;
                                }
                                else { flag = false; }
                            }
                            else { flag = false; } // day no good
                        }
                        else { // not a leap year
                            if (day > 0 && day <= months[i].days) { // check day range
                                if (orgyear >= year - 1 && orgyear <= year + 1) { // check for +/- current year
                                    flag = true;
                                }
                                else { flag = false; }
                            }
                            else { flag = false; } // day no good
                        }
                    }
                }
            }
            return flag;
        }
        catch (e) {
            return false;
        }
    },
    isValidTime: function(timetxt) {
        var tval, flag, tarray, hr, min;
        tval = timetxt.replace(this.ws, '');
        if (!this.time.test(tval)) {
            flag = false;
        }
        else {
            tarray = tval.split(':');
            hr = (tarray[0].charAt(0) == 0) ? tarray[0].charAt(1) : tarray[0];
            min = tarray[1];
            if ((hr > 0 && hr <= 12) & (min >= 00 && min < 60)) {
                flag = true;
            }
            else { flag = false; }
        }
        return flag;
    },
    isNullOrEmpty: function(str) { // mimics .net server-side behavior
        if (str == null || str.constructor == String) {
            return (str == null) ? true :
                (str == '') ? true :
                    (str == ' ') ? true : false;
        }
        else
            alert('Invalid Type Exception:\nMust be a string to check for null, empty or whitespace.');
    },
    isIE: function() {
        return (Sys.Browser.agent === Sys.Browser.InternetExplorer);
    },
    isFF: function() {
        return (Sys.Browser.agent === Sys.Browser.FireFox);
    },
    isOpera: function() {
        return (Sys.Browser.agent === Sys.Browser.Opera);
    },
    isSafari: function() {
        return (Sys.Browser.agent === Sys.Browser.Safari);
    },
    isChecked: function(id, toint) {
        if (arguments.length == 2) {
            return ($get(id).checked) ? 1 : 0;
        }
        else {
            return ($get(id).checked) ? true : false;
        }
    },
    formatUSNumber: function(line) {
        num = line.replace(/([\(\)\s\.-])*/g, "");
        num = num.replace(/\b1\s*/, "");
        if (this.usnumber.test(num)) {
            return '(' + num.slice(0, 3) + ') ' + num.slice(3, 6) + '-' + num.slice(6, 10);
        }
        return line;
    },
    formatUrl: function(urltxt) {
        if (this.url.test(urltxt) || this.devurl.test(urltxt)) {
            return urltxt;
        }
        else {
            // test for http://.example.com
            if (/\/\/.\b/i.test(urltxt)) {
                return urltxt.replace('//.', '//www.');
            }
            // test for http://example.com
            else if (/\/\/\b((www.){0}|(www){0})/i.test(urltxt)) {
                urltxt = urltxt.replace(/([www])*/i, '');
                return urltxt.replace('//', '//www.');
            }
            else
                return null;
        }
    },
    innerText: function(id, txt) {
        h = $get(id);
        if (h.textContent !== undefined) {
            h.textContent = txt;
        }
        else if (h.innerText) {
            h.innerText = txt;
        }
        else
            h.innerHTML = txt;
    },
    innerHTML: function(id, elm) {
        h = $get(id);
        h.innerHTML = elm;
    },
    getJSONFromQueryString: function(url) {// use eval to build the return text
        a = new Array();
        qs = new Array();
        sb = new Sys.StringBuilder();
        if (url.indexOf("?") > -1) {
            a = url.split('?');
            qs = a[1].split('&');
            sb.append('{'); // build JSON data format
            for (i = 0; i < qs.length; i++) {
                kvp = qs[i].split('=');
                if (i === 0) {
                    sb.append('"' + kvp[0].toLowerCase() + '" : "' + kvp[1] + '"');
                }
                else if (qs.length >= 2) {
                    sb.append(',"' + kvp[0].toLowerCase() + '" : "' + kvp[1] + '"');
                }
            }
            sb.append('}');
            //alert(sb.toString()); // to display the JSON object
            eval("var json=" + sb.toString());
            return json;
        }
        else
            alert("Invalid Operation, ? is not present.");
    },
    cancelClick: function(e) { // prevents default behavior
        if (window.event && window.event.cancelBubble && window.event.returnValue) {
            window.event.cancelBubble = true;
            window.event.returnValue = '';
            return;
        }
        if (e && e.stopPropagation && e.preventDefault) {
            e.stopPropagation;
            e.preventDefault
        }
    },
    stopDefault: function(e) {
        // W3C
        if (e && e.preventDefault)
            e.preventDefault();
        else {
            if (window.event)
                window.event.returnValue = '';
        }
    },
    addEvent: function(elm, evType, fn, useCapture) {
        if (elm.addEventListner) { // w3c
            elm.addEventListner(evType, fn, useCapture);
            return true;
        }
        else if (elm.attachEvent) { // ie
            var r = elm.attachEvent('on' + evType, fn);
            return r;
        }
        else // legacy
            elm['on' + evType] = fn;
    },
    removeEvent: function(elm, evType, fn, useCapture) {
        if (elm.removeEventListner) { // w3c
            elm.removeEventListner(evType, fn, useCapture);
            return true;
        }
        else if (elm.detachEvent) { // ie
            elm.detachEvent('on' + evType, fn);
            return true;
        }
        else // legacy
            elm['on' + evType] = null;
    },
    normalizeDate: function(date) {
        // this assumes regex allows / or -
        var repl = /(\/)/g; // to normalize date delimiter
        return date.replace(repl, '-');
    },
    normalizeEvent: function(e) {
        if (!e) var e = window.event;
        e = (e.target) ? e.target : e.srcElement;
        return e;
    },
    normalizeKey: function(e) {
        e = (e) ? e.which : window.event.keyCode;
        return e;
    },
    getTarget: function(e) { // obtains a reference to the element firing the event
        var target = window.event ? window.event.srcElement : e ? e.target : null;
        if (!target)
            return;
        if (target.nodeName.toLowerCase() != 'a') {
            target = target.parentNode;
        }
        return target;
    },
    getText: function(node) {
        if (!node.hasChildNodes())
            return;
        var tempObj = node.firstChild;

        // 3 is a text node
        while (tempObj.nodeType != 3 && tempObj.nextSibling != null || Util.ws.test(tempObj.nodeValue)) {
            tempObj = tempObj.nextSibling;
        }
        return (tempObj.nodeType == 3) ? tempObj.nodeValue : false;
    },
    setText: function(node, txt) {
        if (!node.hasChildNodes())
            return;
        var tempObj = node.firstChild;

        // 3 is a text node
        while (tempObj.nodeType != 3 && tempObj.nextSibling != null || Util.ws.test(tempObj.nodeValue)) {
            tempObj = tempObj.nextSibling;
        }

        if (tempObj.nodeType == 3)
            tempObj.nodeValue = txt;
        else
            return;
    },
    setSelected: function(slct, val, istext) {
        var slt = $get(slct);
        slt.options.selectedIndex = 0; // set default
        for (var i = 0, len = slt.options.length; i < len; i++) {
            switch (istext) {
                case true:
                    if (slt.options[i].text == val) {
                        slt.options.selectedIndex = i;
                    }
                    break;
                case false:
                    if (slt.options[i].value == val) {
                        slt.options.selectedIndex = i;
                    }
                    break;
                default:
                    throw new Error("Util.setSelected requires istext parameter");
                    break;
            }
        }
    },
    getStyle: function(elm, name) {
        if (elm.style[name]) // if exists
            return elm.style[name];
        else if (elm.currentStyle)    // try IE's method
            return elm.currentStyle[name];
        else if (document.defaultView && document.defaultView.getComputedStyle) {// try W3C                
            name = name.replace(/([A-Z])/g, "-$1"); // this uses 'text-align', not textAlign, so change it
            name = name.toLowerCase();

            var s = document.defaultView.getComputedStyle(elm, "");
            return s && s.getPropertyValue(name);
        }
        else
            return null;
    },
    pageX: function(elm) {
        return elm.offsetParent ?   // check for root element
            elm.offsetLeft + pageX(elm.offsetParent) : // if not root element, add current offset
            elm.offsetLeft;     // otherwise, use current offset
    },
    pageY: function(elm) {
        return elm.offsetParent ?   // check for root element
            elm.offsetTop + pageY(elm.offsetParent) : // if not root element, add current offset
            elm.offsetTop;     // otherwise, use current offset
    },
    pageHeight: function() {
        return document.body.scrollHeight; // changes with new content
    },
    pageWidth: function() {
        return document.body.scrollWidth;  // returns width 
    },
    parentX: function(elm) {
        return elm.parentNode == elm.offsetParent ? // check to see if offsetParent is this elements parent
            elm.offsetLeft :  // break early
            Util.pageX(elm) - Util.pageX(elm.parentNode); // difference of both relative to entire document
    },
    parentY: function(elm) {
        return elm.parentNode == elm.offsetParent ? // check to see if offsetParent is this elements parent
            elm.offsetTop :  // break early
            Util.pageY(elm) - Util.pageY(elm.parentNode); // difference of both relative to entire document        
    },
    posX: function(elm) {
        return parseInt(Util.getStyle(elm, "left")); // get computed style and number
    },
    posY: function(elm) {
        return parseInt(Util.getStyle(elm, "top")); // get computed style and number
    },
    setX: function(elm, pos) {
        elm.style.left = pos + "px";    // set left in pixels
    },
    setY: function(elm, pos) {
        elm.style.top = pos + "px";    // set top in pixels
    },
    getX: function(e) {
        e = e || window.event;
        return e.pageX || e.clientX + document.body.scrollLeft;
    },
    getY: function(e) {
        e = e || window.event;
        return e.pageY || e.clientY + document.body.scrollTop;
    },
    addX: function(elm, pos) {
        Util.setX(Util.posX(elm) + pos);  // get current position and add offset
    },
    addY: function(elm, pos) {
        Util.setY(Util.posY(elm) + pos);  // get current position and add offset
    },
    getElementX: function(e) {
        return (e && e.layerX) || window.event.offsetX;  // get correct element offset
    },
    getElementY: function(e) {
        return (e && e.layerY) || window.event.offsetY;  // get correct element offset
    },
    getHeight: function(elm) {
        return parseInt(Util.getStyle(elm, "height"));  // get css and parse to whole number
    },
    getWidth: function(elm) {
        return parseInt(Util.getStyle(elm, "width"));  // get css and parse to whole number
    },
    windowHeight: function() {
        var de = document.documentElement;  // for IE 6 in Strict Mode

        return self.innerHeight || // if available within the browser
            (de && de.clientHeight) || // try the height off of the root node
            document.body.clientHeight; // otherwise, get the height off of the body element
    },
    windowWidth: function() {
        var de = document.documentElement;  // for IE 6 in Strict Mode

        return self.innerWidth || // if available within the browser
            (de && de.clientWidth) || // try the height off of the root node
            document.body.clientWidth; // otherwise, get the height off of the body element    
    },
    scrollX: function() {
        var de = document.documentElement;  // for IE 6 in Strict Mode

        return self.pageXOffset ||  // if available within the browser
            (de && de.scrollLeft) || // try to get scroll left of the root
            document.body.scrollLeft;  // otherwise, get scroll left of the body
    },
    scrollY: function() {
        var de = document.documentElement;  // for IE 6 in Strict Mode

        return self.pageYOffset ||  // if available within the browser
            (de && de.scrollTop) || // try to get the scroll top off of the root node
            document.body.scrollTop;  // otherwise, get the scroll top off of the body element
    },
    hide: function(elm) {
        var curDisplay = Util.getStyle(elm, "display"); // get current state

        if (curDisplay != "none") // remember for later
            elm.$oldDisplay = curDisplay;

        elm.style.display = "none"; // hide it
    },
    show: function(elm) {
        elm.style.display = elm.$oldDisplay || "";  // if nothing saved then "block", otherwise use previous
    },
    clearValues: function(parent) {
        var cal = $get(parent).getElementsByTagName('*');
        for (var j = 0; j < cal.length; j++) {
            if (cal[j].nodeName.toLowerCase() == 'input') {
                if (cal[j].type.toLowerCase() == 'text' || cal[j].type.toLowerCase() == 'hidden') {
                    cal[j].value = '';
                }
                else if (cal[j].type.toLowerCase() == 'radio') {
                    cal[j].checked = '';
                }
                else if (cal[j].type.toLowerCase() == 'checkbox') {
                    cal[j].checked = '';
                }
            }
            else if (cal[j].nodeName.toLowerCase() == 'textarea') {
                cal[j].value = '';
            }
            else if (cal[j].nodeName.toLowerCase() == 'select') {
                cal[j].selectedIndex = 0;
            }
            else continue;
        }
    },
    // thanks to Jeremy Keith for this one, its straight out of his book "DOM Scripting"
    animate: function(elementID, final_x, final_y, interval) {
        if (!document.getElementById) return false;
        if (!document.getElementById(elementID)) return false;
        var elem = document.getElementById(elementID);
        if (elem.movement) {
            clearTimeout(elem.movement);
        }
        if (!elem.style.left) {
            elem.style.left = "0px";
        }
        if (!elem.style.top) {
            elem.style.top = "0px";
        }
        var xpos = parseInt(elem.style.left);
        var ypos = parseInt(elem.style.top);
        if (xpos == final_x && ypos == final_y) {
            return true;
        }
        if (xpos < final_x) {
            var dist = Math.ceil((final_x - xpos) / 10);
            xpos = xpos + dist;
        }
        if (xpos > final_x) {
            var dist = Math.ceil((xpos - final_x) / 10);
            xpos = xpos - dist;
        }
        if (ypos < final_y) {
            var dist = Math.ceil((final_y - ypos) / 10);
            ypos = ypos + dist;
        }
        if (ypos > final_y) {
            var dist = Math.ceil((ypos - final_y) / 10);
            ypos = ypos - dist;
        }
        elem.style.left = xpos + "px";
        elem.style.top = ypos + "px";
        var repeat = "Util.animate('" + elementID + "'," + final_x + "," + final_y + "," + interval + ")";
        elem.movement = setTimeout(repeat, interval);
    },
    blindDown: function(elmId, endY, fps, innerElm) {
        if (!document.getElementById) return false;
        var elm = $get(elmId);
        elm.style.display = 'block';
        if (elm.action)
            window.clearTimeout(elm.action);
        if (!elm.style.height)
            elm.style.height = "0px";
        var ypos = parseInt(elm.style.height);
        if (ypos == endY) {
            var detcnt = $get(innerElm);
            detcnt.className = 'showContainer';
            Util.showContents(elmId);
            return true;
        }
        if (ypos < endY) {
            var dist = Math.ceil((endY - ypos) / 10);
            ypos = ypos + dist;
        }
        if (ypos > endY) {
            var dist = Math.ceil((ypos - endY) / 10);
            ypos = ypos - dist;
        }
        elm.style.height = ypos + 'px';
        var doover = "Util.blindDown('" + elmId + "'," + endY + "," + fps + ",'" + innerElm + "')";
        elm.action = window.setTimeout(doover, fps);
    },
    hideContents: function(elmId) {
        var cnts = $get(elmId).getElementsByTagName('*');
        for (var i = 0; i < cnts.length; i++) {
            if (cnts[i].nodeName === 'LEGEND') continue;
            cnts[i].style.visibility = 'hidden';
        }
    },
    showContents: function(elmId) {
        var cnts = $get(elmId).getElementsByTagName('*');
        for (var i = 0; i < cnts.length; i++) {
            cnts[i].style.visibility = 'visible';
        }
    },
    disableAll: function(parent) {
        var disall = $get(parent).getElementsByTagName('*');
        for (var x = 0; x < disall.length; x++) {
            if (disall[x].nodeName.toLowerCase() == 'textarea') {
                disall[x].style.visibility = 'hidden';
            }
            disall[x].disabled = "disabled"; // disabled
        }
    },
    enableAll: function(parent, hideElm) {
        var enball = $get(parent).getElementsByTagName('*');
        if (arguments.length == 2) {
            for (var x = 0; x < enball.length; x++) {
                if (enball[x].nodeName.toLowerCase() == 'textarea') {
                    enball[x].style.visibility = 'visible';
                }
                enball[x].disabled = ""; // enabled
            }
            if (arguments.length == 2)
                $get(hideElm).style.display = 'none';
        }
        else if (arguments.length == 1) {
            for (var x = 0; x < enball.length; x++) {
                if (enball[x].nodeName.toLowerCase() == 'textarea') {
                    enball[x].style.visibility = 'visible';
                }
                enball[x].disabled = ""; // enabled
            }
        }
    },
    loading: function(elmname, top) {
        var wm = $get(elmname);
        var wmloc = Sys.UI.DomElement.getBounds(wm);
        var msg = document.createElement('div');
        msg.id = 'loadMsg';
        msg.className = 'waitBox';
        var p = document.createElement('p');
        p.appendChild(document.createTextNode('Loading...'));
        msg.appendChild(p);
        var div = document.createElement('div');
        div.innerHTML = '<img src="Images/ajax-loaderkhakiBert.gif" alt="Loading..." />';
        msg.appendChild(div);
        // be sure it doesn't already exist
        if (wm.lastChild.id != 'loadMsg')
            wm.appendChild(msg);
        else
            return;
        var remsg = $get('loadMsg');
        var msgloc = Sys.UI.DomElement.getBounds(remsg);
        remsg.style.zIndex = 50000;
        remsg.style.left = parseFloat(Math.round((wmloc.width / 2) - (msgloc.width / 2))) + 'px';
        remsg.style.top = parseFloat(top + this.scrollY()) + 'px';
    },
    hideLoading: function(parent) {
        var elm = $get(parent);
        elm.removeChild(elm.lastChild);
    },
    setLoadingState: function(parent, modallayerid, top, status) { // status == { state: 'on' or 'off'}
        var bg = $get(modallayerid);
        if (status.state == 'on') {
            if (bg)
                bg.style.display = 'block';
            Util.loading(parent, top);
        }
        else if (status.state == 'off') {
            if (bg)
                bg.style.display = 'none';
            Util.hideLoading(parent);
        }
        else
            throw new Error('state.status is undefined');
    },
    message: function(elmname, msgHdr, lblMkupCnt, top, hideIn) {
        var lblre = /<label>/i;
        var wm = $get(elmname);
        var wmloc = Sys.UI.DomElement.getBounds(wm);
        var msg = document.createElement('div');
        msg.id = 'popMsg';
        msg.className = 'waitBox';
        var p = document.createElement('p');
        p.appendChild(document.createTextNode(msgHdr));
        msg.appendChild(p);
        var div = document.createElement('div');
        div.innerHTML = lblre.test(lblMkupCnt) ? lblMkupCnt : '<label>' + lblMkupCnt + '</label><br /><br />';
        msg.appendChild(div);
        // be sure it doesn't already exist
        if (wm.lastChild.id != 'popMsg')
            wm.appendChild(msg);
        else
            return;
        var remsg = $get('popMsg');
        var msgloc = Sys.UI.DomElement.getBounds(remsg);
        remsg.style.zIndex = 50000;
        remsg.style.left = parseFloat(Math.round((wmloc.width / 2) - (msgloc.width / 2))) + 'px';
        remsg.style.top = parseFloat(top + this.scrollY()) + 'px';
        window.setTimeout(function() {
            Util.hideMessage(wm); // this doesn't work must be Util
        },
        hideIn);
    },
    hideMessage: function(m) {
        var msg = $get('popMsg');
        if (msg)
            m.removeChild(msg);
    },
    modalDialog: function(elmname, msgHdr, str, top, okFunc, cnlFunc) {
        var strre = /</;
        if (str.constructor != String || strre.test(str)) {
            alert('String() is the only type accepted for "Util.modalDialog" message.');
            return;
        }
        var wm = $get(elmname);
        var wmloc = Sys.UI.DomElement.getBounds(wm);
        var msg = document.createElement('div');
        msg.id = 'modalDlg';
        msg.className = 'waitBox';
        var p = document.createElement('p');
        p.appendChild(document.createTextNode(msgHdr));
        msg.appendChild(p);
        var lbl = document.createElement('label');
        lbl.width = '95%';
        lbl.height = '15';
        lbl.appendChild(document.createTextNode(str));
        var div = document.createElement('div');
        div.appendChild(lbl);
        div.appendChild(
            document.createElement('br'));
        div.appendChild(
            document.createElement('br'));
        var span = document.createElement('span');
        span.style.width = '100%';
        span.style.textAlign = 'center';
        var btnok = document.createElement('input');
        var btncnl = document.createElement('input');
        btnok.type = 'button';
        btncnl.type = 'button';
        btnok.value = 'Ok';
        btncnl.value = 'Cancel';
        btnok.className = 'wizBtn';
        btncnl.className = 'wizBtn';
        btnok.style.marginRight = '2em';
        btnok.style.styleFloat = 'none';
        btncnl.style.styleFloat = 'none';
        btnok.onclick = function() {
            okFunc();
            Util.hideModalDialog(elmname);
        }
        btncnl.onclick = function() {
            if (cnlFunc == null) {
                cnlFunc = false;
            }
            else {
                cnlFunc();
            }
            wm.removeChild(wm.lastChild);
        }
        span.appendChild(btnok);
        span.appendChild(btncnl);
        div.appendChild(span);
        msg.appendChild(div);
        // be sure it doesn't already exist
        if (wm.lastChild.id != 'modalDlg')
            wm.appendChild(msg);
        else return;
        var remsg = $get('modalDlg');
        var msgloc = Sys.UI.DomElement.getBounds(remsg);
        remsg.style.zIndex = 50000;
        remsg.style.left = parseFloat(Math.round((wmloc.width / 2) - (msgloc.width / 2))) + 'px';
        remsg.style.top = parseFloat(top + this.scrollY()) + 'px';
        btncnl.focus(); // test
    },
    hideModalDialog: function(wrapper) {
        var wrapper = $get(wrapper);
        var dlg = $get('modalDlg');
        wrapper.removeChild(dlg);
    },
    valSummary: function(wrapper, msgHdr, mkupCnt, top) {
        var wm = $get(wrapper);
        var wmloc = Sys.UI.DomElement.getBounds(wm);
        var msg = document.createElement('div');
        msg.id = 'valSmry';
        msg.className = 'waitBox';
        var p = document.createElement('p');
        p.appendChild(document.createTextNode(msgHdr));
        msg.appendChild(p);
        var div = document.createElement('div');
        div.innerHTML = mkupCnt;
        msg.appendChild(div);
        // be sure it doesn't already exist
        if (wm.lastChild.id != 'valSmry')
            wm.appendChild(msg);
        else
            return;
        var remsg = $get('valSmry');
        var msgloc = Sys.UI.DomElement.getBounds(remsg);
        remsg.style.zIndex = 50000;
        remsg.style.left = parseFloat(Math.round((wmloc.width / 2) - (msgloc.width / 2))) + 'px';
        remsg.style.top = parseFloat(top + this.scrollY())+'px';
        msg.ondblclick = function() {
            Util.hideValSummary(wrapper);
        }
    },
    hideValSummary: function(id) {
        var m = $get(id);
        m.removeChild(m.lastChild);
    }
}