﻿var cx = function() {
    return {

        //logging can be turned on or off here.
        EnableLogging: false,
        byID: function byID(elementID) {
            return YAHOO.util.Dom.get(elementID);
        },
        show: function show(el) { // el can be elementid or element
            if (cx.byID(el) && cx.byID(el).tagName && cx.byID(el).tagName.toLowerCase() == 'tr') { //if it's a table row, set to '' (table-row breaks in IE7)
                YAHOO.util.Dom.setStyle(el, 'display', '');
            }
            else {
                YAHOO.util.Dom.setStyle(el, 'display', 'block');
            }
        },
        hide: function hide(el) { // el can be elementid or element
            YAHOO.util.Dom.setStyle(el, 'display', 'none');
        },
        toggleShowHide: function toggleShowHide(el) {
            if (cx.byID(el).style.display == 'none') {
                this.show(el);
            }
            else {
                this.hide(el);
            }
        },
        form: function form() {
            var frm = this.byID('aspnetForm'); //xchange
            if (!frm || null === frm || typeof (frm) == 'undefined') {
                frm = this.byID('frmMain'); //xquote
            }
            return frm;
        },
        findParentBySuffix: function findParentBySuffix(aNode, parentSuffix) {
            var currentNode = aNode;
            while (null !== currentNode) {
                if (currentNode.id.lastIndexOf(parentSuffix) == currentNode.id.length - parentSuffix.length) {
                    return currentNode;
                }
                currentNode = currentNode.parentNode;
            }
        },
        findChildBySuffix: function findChildBySuffix(aNode, currentSuffix, childSuffix) {
            if (null === aNode) {
                return null;
            }
            var id = aNode.id.replace(currentSuffix, childSuffix);
            var node = this.byID(id);
            if (null === node) {
                node = this.drillForChildNodeBySuffix(aNode, childSuffix);
            }
            return node;
        },
        drillForChildNodeBySuffix: function drillForChildNodeBySuffix(el, childSuffix) {
            if (null === el || typeof el == "undefined") {
                return null;
            }
            if (el.id && el.id.lastIndexOf(childSuffix) >= 0) {
                return el;
            }
            if (el.childNodes.length > 0) {
                for (var n = 0; n < el.childNodes.length; n++) {
                    var e = drillForChildNodeBySuffix(el.childNodes[n], childSuffix);
                    if (null !== e) {
                        return e;
                    }
                }
            }
            return null;
        },
        refreshWindow: function refreshWindow() {
            try {
                if (cx.browser.hasParent) {
                    window.parent.location.href = cx.request.parentUrl;
                    return;
                }
            } catch (e) { /*could not refresh parent window*/ }
            try {
                cx.browser.redirect(cx.request.url);
            } catch (f) { /*could not refresh window*/ }
        },
        ///<summary>
        /// searches page for checkboxes and checks or unchecks depending on checkAll paremeter
        ///</summary>
        ///<param name="checkAll">true if you want boxes checked, false if you would like boxes unchecked</param>
        ///<param name="node">optional: if you would like to only check checkboxes in a certain element, pass in this parameter - it can be the id or the element node.</param>
        checkAll: function checkAll(/*bool* checkAll, *object* node*/) { // if element is passed in will search element children
            var Parent = this.form();
            var checked;
            if (this.checkAll.arguments && this.checkAll.arguments.length > 0) {
                checked = this.checkAll.arguments[0];
                if (this.checkAll.arguments.length > 1) {
                    if (typeof (this.checkAll.arguments[1]) == "string") {
                        Parent = this.byID(this.checkAll.arguments[1]);
                    }
                    else if (typeof (this.checkAll.arguments[1]) == "object") {
                        Parent = this.checkAll.arguments[1];
                    }
                }
            }
            else {
                return;
            }
            var elements = this.getChildNodes(Parent);
            for (var i = 0; i < elements.length; i++) {
                var e = elements[i];
                if (e.type == 'checkbox') {
                    e.checked = checked;
                }
            }

        },
        getChildNodes: function getChildNodes(Parent) {
            return Parent.getElementsByTagName('*');
        },
        setOpacity: function setOpacity(elementid, opacityvalue) {
            this.byID(elementid).style.opacity = opacityvalue / 10;
            this.byID(elementid).style.filter = 'alpha(opacity=' + opacityvalue * 10 + ')';
        },
        /* This method makes a call to a URL and replaces the contents of the target element with the results 
        of the asynchronous request
        targetElementID: the element on the page where the results should be displayed
        url: the URL to which we are making an asynchronous request
        querystringparams:  querystring values to append to the URL
        contenttoverify: content you expect to see in the response... this helps us avoid displaying a 
        login page or error page if there is a problem with the request
        errormessage:  message to display in the failure case
        method:  GET or POST
        postdata:  should be null for GET; for POST, this should include the form data you wish to post
        */
        simpleAsyncCallback: function simpleAsyncCallback(targetElementID, url, querystringparams, contenttoverify, errormessage, method, postdata) {
            var sUrl = url;
            var elem = this.byID(targetElementID);
            if (querystringparams) {
                sUrl += '?' + querystringparams + '&time=' + new Date().getTime();
            }

            var callback = {
                success: function(o) {
                    if (elem !== null) {
                        if (o.responseText.indexOf(contenttoverify) > -1) {
                            elem.innerHTML = o.responseText;
                        }
                        else {
                            elem.innerHTML = errormessage;
                        }
                    }
                },
                failure: function(o) {
                    //elem.innerHTML =  o.statusText;
                    if (elem !== null) {
                        elem.className = 'redhighlight';
                        elem.innerHTML = errormessage;
                    }
                }
            };

            //handle optional parameters
            if (method === undefined) {
                method = 'GET';
            }
            if (postdata === undefined) {
                postdata = null;
            }

            var transaction = YAHOO.util.Connect.asyncRequest(method, sUrl, callback, postdata);
        },
        slightlyMoreComplexAsyncCallback: function slightlyMoreComplexAsyncCallback(url, querystringparams, callbackfunction, method, postdata) {
            var sUrl = url;
            if (querystringparams) {
                sUrl += '?' + querystringparams + '&time=' + new Date().getTime();
            }
            else
                sUrl += '?time=' + new Date().getTime();

            var callback = {
                success: function success(o) {
                    if (null != callbackfunction) {
                        callbackfunction('success', o)
                    }
                },
                failure: function failure(o) {
                    if (null != callbackfunction) {
                        callbackfunction('failure', o)
                    }
                }
            }

            //handle optional parameters
            if (method === undefined) {
                method = 'GET';
            }
            if (postdata === undefined) {
                postdata = null;
            }

            var transaction = YAHOO.util.Connect.asyncRequest(method, sUrl, callback, postdata);

        },
        stripWhitespace: function stripWhitespace(str) {
            str = str.replace(/[\n\r\t]/g, '').toLowerCase();
            return str;
        },
        setFocus: function setFocus(elementid) {
            this.byID(elementid).focus();
        },
        popUp: function popUp(url, name, width, height, left, top) {
            win = window.open(url, name, 'resizable=yes,scrollbars=yes,status=no,width=' + width + ',height=' + height);
            if (left && top)
                win.moveTo(left, top);
        },
        browser:
        {
            version:
          {
              isIE: navigator.appName.toLowerCase() == "microsoft internet explorer",
              isFireFox: navigator.appName.toLowerCase() == "netscape",
              value: navigator.appVersion
          },
            userAgent: navigator.userAgent,
            codeName: navigator.appCodeName,
            name: navigator.appName,
            platform: navigator.platform,
            redirect: function(url) {
                location.href = url;
            },
            hasParent: (function() {
                if (window.parent)
                    return true;
                return false;
            })()
        },
        formatMoney: function formatMoney(amount, showCents, currencySymbol) {
            var delimiter = ','; // replace comma if desired

            var a = new String(parseFloat(amount).toFixed(2)).split('.', 2);
            var d = a[1];
            var i = parseInt(a[0]);
            if (isNaN(i)) { return ''; }
            var minus = '';
            if (i < 0) { minus = '-'; }
            i = Math.abs(i);
            var n = new String(i);
            var a = [];
            while (n.length > 3) {
                var nn = n.substr(n.length - 3);
                a.unshift(nn);
                n = n.substr(0, n.length - 3);
            }
            if (n.length > 0) { a.unshift(n); }
            n = a.join(delimiter);

            if (d.length == 0 || !showCents) { amount = n; }
            else { amount = n + '.' + d; }
            amount = minus + amount;

            return currencySymbol + amount;
        },
        formatHoursMins: function formatHoursMins(hoursDecimal) {
            var hr = Math.floor(hoursDecimal);
            var min = Math.round((hoursDecimal - hr) * 60);
            if (min < 10)
                min = '0' + min;
            if (min == 60) {
                hr++;
                min = '00';
            }
            return hr + ':' + min;
        },
        formatTime: function formatTime(timeString) {
            var hrs = 0;
            var mins = 0;
            if (timeString.indexOf(':') > 0) {
                hrs = timeString.split(':')[0];
                mins = timeString.split(':')[1];
            }
            else if (timeString.indexOf('.') > 0) {
                hrs = timeString.split('.')[0];
                mins = 60 * parseFloat(timeString.substring(timeString.indexOf('.')));
            }
            else {
                switch (timeString.length) {
                    case 4:
                        hrs = timeString.substring(0, 2);
                        mins = timeString.substring(2);
                        break;
                    case 3:
                        hrs = timeString.substring(0, 1);
                        mins = timeString.substring(1);
                        break;
                    default:
                        hrs = timeString;
                }
            }

            if (mins > 59) {
                hrs = parseInt(hrs) + Math.floor(mins / 60);
                mins = (mins % 60);
            }

            //return appropriate time string
            return hrs + ':' + mins;
        },
        parseHoursMins: function parseHoursMins(hoursMins) {
            if (hoursMins.indexOf(':') > 0) {
                var hrs = 0;
                var mins = 0;
                hrs = hoursMins.split(':')[0];
                mins = hoursMins.split(':')[1];
                return parseInt(hrs) + (parseInt(mins) / 60);
            }
            else
                return parseFloat(hoursMins);
        },
        //walk the tree to get the index of the row that contains the target element
        getRowIndex: function getRowIndex(target) {
            var tablerow = this.getRow(target);
            if (null !== tablerow) {
                return tablerow.rowIndex;
            }
            return -1;
        },
        //walk the tree to get the row containing the target element
        getRow: function getRow(target) {
            while (target !== null && target !== undefined) {
                if (target.nodeName == "TR")
                    return target;
                target = target.parentNode;
            }
            return null;
        },
        //find the IFrame containing the supplied element and change the height to match the 
        // element's height plus a specified amount of padding
        resizeContainingIFrame: function resizeContainingIFrame(el, padding) {
            var iframe = null;
            var target = window.parent.document.getElementsByTagName("iframe");
            for (counter = 0; counter < target.length; counter++) {
                if (null !== target[counter].contentWindow.document.getElementById(el.id)) {
                    iframe = target[counter];
                    break;
                }
            }

            if (iframe !== null && iframe !== undefined) {
                var height = parseInt(el.offsetHeight) + parseInt(padding);
                iframe.height = height + 'px';
                //                alert(iframe.height);
                //                alert(height);
            }
        },
        /**
        * Returns the namespace specified and creates it if it doesn't exist
        * e.g., 
        *   cx.makeNamespace('cx.ui.my.newly.created.namespaceofgoodness');
        *
        * Be careful when naming packages. Reserved words may work in some browsers
        * and not others. For instance, the following will fail in Safari:
        *   cx.makeNamespace("really.long.nested.namespace");
        
        * This fails because "long" is a future reserved word in ECMAScript
        */
        makeNamespace: function makeNamespace(args) {
            var a = args, o = null, j, d;
            d = a.split(".");
            o = cx;

            // cx is implied, so it is ignored if it is included
            for (j = (d[0] == "cx") ? 1 : 0; j < d.length; j = j + 1) {
                o[d[j]] = o[d[j]] || {};
                o = o[d[j]];
            }
            return o;
        },
        getScrollX: function getScrollX() {
            var scrollX = 0;
            if (document.documentElement && document.documentElement.scrollLeft) {
                scrollX = document.documentElement.scrollLeft;
            }
            else if (document.body && document.body.scrollLeft) {
                scrollX = document.body.scrollLeft;
            }
            else if (window.pageXOffset) {
                scrollX = window.pageXOffset;
            }
            else if (window.scrollX) {
                scrollX = window.scrollX;
            }
            return scrollX;
        },
        getScrollY: function getScrollY() {
            var scrollY = 0;
            if (document.documentElement && document.documentElement.scrollTop) {
                scrollY = document.documentElement.scrollTop;
            }
            else if (document.body && document.body.scrollTop) {
                scrollY = document.body.scrollTop;
            }
            else if (window.pageYOffset) {
                scrollY = window.pageYOffset;
            }
            else if (window.scrollY) {
                scrollY = window.scrollY;
            }
            return scrollY;
        },
        unhighlightRow: function unhighlightRow(row, count) {
            var startingindex = row.rowIndex;

            // This next part was designed for the pilots page.  If a negative number is passed in,
            // we want to find the first full row and reset startingindex accordingly.
            if (count < 0) {
                for (var i = 0; i < Math.abs(count); i++) {
                    if (row.parentNode.rows[row.rowIndex - i].cells.length > row.cells.length) {
                        startingindex = row.rowIndex - i;
                        break;
                    }
                }
            }

            // unhighlight rows
            for (var ii = 0; ii < Math.abs(count); ii++) {
                row.parentNode.rows[startingindex + ii].bgColor = '#ffffff';
            }
        },
        highlightRow: function highlightRow(row, count) {
            var startingindex = row.rowIndex;

            // This next part was designed for the pilots page.  If a negative number is passed in,
            // we want to find the first full row and reset startingindex accordingly.
            if (count < 0) {
                for (var i = 0; i < Math.abs(count); i++) {
                    if (row.parentNode.rows[row.rowIndex - i].cells.length > row.cells.length) {
                        startingindex = row.rowIndex - i;
                        break;
                    }
                }
            }

            // highlight rows
            for (var ii = 0; ii < Math.abs(count); ii++) {
                row.parentNode.rows[startingindex + ii].bgColor = '#eeeeee';
            }
        },
        handleRowClick: function handleRowClick(url) {
            //	     var l = document.links,
            //         i = l.length,
            //         t = e.target || e.srcElement;

            //     /* Search to see if the target element
            //      * was a link. If it was, quit. */
            //     while(i--) {if(l[i] == t) {return;}} 

            //location.href = url;
        },
        getRealLeft: function getRealLeft(imgElem) {
            return YAHOO.util.Dom.getX(imgElem);
        },
        getRealTop: function getRealTop(imgElem) {
            return YAHOO.util.Dom.getY(imgElem);
        }
    };
} ();
///<summary>
/// exposes 1 property : queryString
/// just use this static function like var myParam = cx.request.queryString["parameter"];
///</summary>
cx.request = function() {
    return {
        queryString: (function() {
            var result = {};
            var querystring = location.search;
            // document.location.search is empty if a query string is absent  
            if (!querystring)
                return result;
            var pairs = querystring.substring(1).split("&");
            var splitPair;
            // Load the key/values of the return collection  
            for (var i = 0; i < pairs.length; i++) {
                splitPair = pairs[i].split("=");
                result[splitPair[0]] = splitPair[1];
            }
            return result;
        })(),
        url: (function() {
            return location.protocol + "//" + location.host + "/" + location.pathname + location.search;
        })(),
        parentUrl: (function() {
            try {
                return parent.location.protocol + "//" + parent.location.host + "//" + parent.location.pathname + parent.location.search;
            }
            catch (e) { }
        })()
    };
} ();
cx.getEvent = function(evt) { return window.event; }
///<summary>
/// to use this static object, just call cx.mouse.init with the current event and
/// then access any public properties {x,y}
///</summary>
cx.mouse = function() {
    return {
        _x: function _x(evt) {
            var posx = 0;
            if (evt) {
                if (evt.clientX) {
                    posx = evt.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
                } else if (evt.pageX) {
                    posx = evt.pageX;
                }
            }
            return posx;
        },
        _y: function _y(evt) {
            var posy = 0;
            if (evt) {
                if (evt.clientY) {
                    posy = evt.clientY + document.body.scrollTop + document.documentElement.scrollTop;
                }
                else if (evt.pageY) {
                    posy = evt.pageY + document.body.scrollTop + document.documentElement.scrollTop;
                }
            }
            return posy;
        },
        x: null,
        y: null,
        init: function(evt) {
            if (!evt) { evt = cx.getEvent(); }
            this.y = this._y(evt);
            this.x = this._x(evt);
        }
    };
} ();
///<summary>
/// exposes 2 properties of an element : x position {posX}, y position {posY}
/// create an instance of this object like var o = new cx.element(cx.byID('myElement'));
///</summary>
cx.element = function(/**object* element*/) {
    return {
        cotr: function() {
            this.el = arguments[0][0];
            return this;
        },
        el: null,
        properties: {},
        Coords: null,
        posX: function posX() {
            if (!this.el) return -1;
            if (YAHOO && YAHOO.ext && YAHOO.ext.Element) {
                var e = YAHOO.ext.Element.get(this.el);
                return e.getX;
            }
            if (null == this.Coords)
                this.setCoords();
            return this.Coords[0];
        },
        posY: function posY() {
            if (!this.el) return -1;
            if (YAHOO && YAHOO.ext && YAHOO.ext.Element) {
                var e = YAHOO.ext.Element.get(this.el);
                return e.getY;
            }
            if (null == this.Coords)
                this.setCoords();
            return this.Coords[1];
        },
        setCoords: function setCoords() {
            var el = this.el;
            var posX = 0, posY = 0;
            if (typeof (el.offsetParent) != 'undefined') {
                do {
//                    // If the element is position: relative we have to add borderWidth
//                    if (this.getStyle(el, 'position') == 'relative') {
//                        var border = this.getStyle(el, 'border-left-width');
//                        posX += parseInt(border);

//                        border == this.getStyle(el, 'border-top-width');
//                        posY += parseInt(border);
//                    }
                    posX += el.offsetLeft;
                    posY += el.offsetTop;
                }
                while (el = el.offsetParent)
                this.Coords = [posX, posY];
            } else
                this.Coords = [el.x, el.y];
        },
        getStyle: function getStyle(obj, styleProp) {
            if (obj.currentStyle)
                return obj.currentStyle[styleProp];
            else if (window.getComputedStyle)
                return document.defaultView.getComputedStyle(obj, null).getPropertyValue(styleProp);
        },
        matchHeightToOtherElements: function matchHeightToOtherElements(elementIDs, doMatchParent) {
            if (elementIDs.length <= 0 || null == this.el)
                return;
            var sHeight;
            elementIDs.push(this.el.id);
            var obj = cx.byID(elementIDs[0]);
            if (null == obj)
                var assumedHeight = 0;
            if (null != obj)
                assumedHeight = obj.offsetHeight;
            sHeight = assumedHeight;
            var isMisMatchHeight = false;
            var n = 0;
            while (n < elementIDs.length) {
                var x = cx.byID(elementIDs[n]);
                if (null != x) {
                    if (x.offsetHeight != assumedHeight)
                        isMisMatchHeight = true;
                    if (x.offsetHeight > assumedHeight)
                        assumedHeight = x.offsetHeight;
                    if (doMatchParent && (x.parentNodeoffsetHeight > assumedHeight))
                        assumedHeight = x.parentNode.offsetHeight;
                }
                ++n;
            }
            if (sHeight != assumedHeight || true == isMisMatchHeight) {
                this.el.style.height = assumedHeight + "px";
                n = 0;
                while (n < elementIDs.length) {
                    var x = cx.byID(elementIDs[n]);
                    if (null != x)
                        x.style.height = assumedHeight + "px";
                    ++n;
                }
            }
        }

}.cotr(arguments);
    }
  ///<summary>
  /// beginning of a unit
  ///</summary>
  cx.unit = function(/**int* number*/)
  {
    return {
      cotr: function()
      {
        this.i = arguments[0][0];
        return this;
      },
      i: null,
      toString: function()
      {
        return this.i + "px";
      }

}.cotr(arguments);
    }
    cx.forms = {
    validateCompanySearch: function validateCompanySearch(searchBoxID)
      {
        if (null == cx.forms.validationTimer)
        {
          cx.forms.validationTimer = new cx.forms.validationTimerObj();
        }
        if (cx.byID(searchBoxID).value <= 0)
        {
          // the validation timer here is to compensate for .net submitting all buttons on the page 
          // (that is if there is more than one.) since the onclick method is triggered on one button,
          // all image buttons inside type companySearchBox.ascx will then call into this method. this
          // will ensure that the user wont hit the keydown(enter) and recieve a 'Please enter a company name'
          // triggered from another other empty textbox.
          if (!cx.forms.validationTimer.isStarted && !cx.forms.validationTimer.isExpired())
          {
            alert('Please enter a company name');
            cx.forms.validationTimer.stop();
            cx.forms.validationTimer.reset();
            cx.forms.validationTimer.start();
          }
          return false;
        }
        else
        {
          cx.forms.validationTimer.stop();
          cx.forms.validationTimer.reset();
          cx.forms.validationTimer.start();
          return true;
        }
      },
      validationTimer: null,
      validationTimerObj: function()
      {
        return {
          Cotr: function()
          {
            var callback = new cx.events.callback("onUpdate", this);
            this.timer = new cx.util.timer(2500, callback);
            this._isExpired = false;
            return this;
          },
          timer: null,
          _isExpired: false,
          isStarted: false,
          start: function start()
          {
            this.timer.start();
            this.isStarted = true;
          },
          stop: function stop()
          {
            this.timer.stop();
            this.isStarted = false
          },
          reset: function reset()
          {
            this._isExpired = false;
            this.timer.reset();
            this.isStarted = false;
          },
          onUpdate: function onUpdate(date)
          {
            if (date.getSeconds() > 0)
              this._isExpired = true;
          },
          isExpired: function isExpired()
          {
            return this._isExpired
          }
}.Cotr(arguments);
        }
      }
      ///<summary>
      /// a namespace to hold utility script functionality.
      ///</summary>
      cx.util = {
        ///<summary>
        /// loops through the images on a page to fix the transparency in ie 5.5 and 6.
        ///</summary>
      fixPng: function fixPng()
        {
          var arVersion = navigator.appVersion.split("MSIE")
          var version = parseFloat(arVersion[1])
          if ((version >= 5.5) && (document.body.filters) && version < 7.0)
          {
            for (var i = 0; i < document.images.length; i++)
            {
              var img = document.images[i]
              if (img.className.indexOf("noMod") >= 0)
                continue;
              var imgName = img.src.toUpperCase()
              if (imgName.substring(imgName.length - 3, imgName.length) == "PNG")
              {
                var imgID = (img.id) ? "id='" + img.id + "' " : ""
                var imgClass = (img.className) ? "class='" + img.className + "' " : ""
                var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
                var imgStyle = "display:inline-block;" + img.style.cssText
                if (img.align == "left") imgStyle = "float:left;" + imgStyle
                if (img.align == "right") imgStyle = "float:right;" + imgStyle
                if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
                var strNewHTML = "<span " + imgID + imgClass + imgTitle
                     + " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
                     + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
                     + "(src=\'" + img.src + "\');\"></span>"
                img.outerHTML = strNewHTML
                i = i - 1
              }
            }
          }
        },
        ///<summary>
        /// gets a keycode from a keydown event
        ///</summary>
        getKeyCode: function getKeyCode(e)
        {
          if (!e)
          {
            e = window.event;
          }
          if (e)
          {
            if (e.keyCode)
            {
              return e.keyCode
            }
            else if (e.which)
            {
              return e.which
            }
          }
        },
        timer: function(/*int duration*/ /*cx.events.callback callback*/)
        {
          return {
            Cotr: function()
            {
              this.duration = arguments[0][0];
              this.callback = arguments[0][1];
              this.ID = cx.util.timer.timerID;
              cx.util.timer.timers[this.ID] = this;
              ++cx.util.timer.timerID;
              return this;
            },
            ID: null,
            duration: 1000,
            callback: null,
            tStart: null,
            timerID: null,
            updateTimer: function updateTimer()
            {
              if (this.timerID)
              {
                clearTimeout(this.timerID);
              }
              if (!this.tStart)
                this.tStart = new Date();
              var tDate = new Date();
              var tDiff = tDate.getTime() - this.tStart.getTime();
              tDate.setTime(tDiff);
              if (null == this.callback.Obj)
              {
                setTimeout(this.callback.Name + '()', 1);
              }
              else
                this.callback.Obj[this.callback.Name](tDate);

              this.timerID = setTimeout("cx.util.timer.update(" + this.ID + ")", this.duration);
            },
            start: function start()
            {
              this.tStart = new Date();
              this.timerID = setTimeout("cx.util.timer.update(" + this.ID + ")", this.duration);
            },
            stop: function stop()
            {
              if (this.timerID)
              {
                clearTimeout(this.timerID);
                this.timerID = 0;
              }
              this.tStart = null;
            },
            reset: function()
            {
              this.tStart = null;
            }
}.Cotr(arguments);
          }

        };
        cx.util.timer.timerID = 0;
        cx.util.timer.timers = new Array();
        cx.util.timer.update = function(id)
        {
          var t = cx.util.timer.timers[id];
          t.updateTimer();
        }
        cx.events = {};
        cx.events.callback = function(/* name of the function to be called */ /* object that contains the function */)
        {
          return {
            Cotr: function()
            {
              switch (arguments[0].length)
              {
                case 1:
                  this.Name = arguments[0][0];
                  this.Obj = null;
                  break;
                case 2:
                  this.Name = arguments[0][0];
                  this.Obj = arguments[0][1];
                  break;
              }
              return this;
            },
            Name: null,
            Obj: null
}.Cotr(arguments);
          }



          ///<summary>
          /// a general namespace to register control functionality or just extra odds and ends.
          ///</summary>
          cx.Objects = {};
          ///<summary>
          /// //a general namespace to create instances of cx.Objects or other built in objects.
          ///</summary>
          cx.Instance = {};
          ///<summary>
          /// a namespace to register page-related functionality.
          ///</summary>
          cx.page = function()
          {

            return {

              beginStartError: function beginStartError()
              {
                cx.page.createError();
              },
              createError: function createError()
              {
                cx.page.onThrowInit();
              },
              onThrowInit: function onTrowInit()
              {
                cx.page.throwUp();
              },
              throwUp: function throwUp()
              {
                puke();
                try
                {
                } catch (e)
                { cx.page.handle_Error(e, ""); throw e.message; }
              },
              getStackTrace: function getStackTrace()
              {
                var mode;
                try { (0)() } catch (e)
                {
                  mode = e.stack ? 'Firefox' : window.opera ? 'Opera' : 'Other';
                }
                switch (mode)
                {
                  case 'Firefox': return function()
                  {
                    try { (0)() } catch (e)
                    {
                      return e.stack.replace(/^.*?\n/, '').
                      replace(/(?:\n@:0)?\s+$/m, '').
                      replace(/^\(/gm, '{anonymous}(').
                      replace('<p>', '').
                      split(/@http:/).
                      join("<br />@http:");
                      //replace(/@http:/, '<br />');
                      //split(cx.page.newline);
                    }
                  };
                  case 'Opera': return function()
                  {
                    try { (0)() } catch (e)
                    {
                      var lines = e.message.split("\n"),
                      ANON = '{anonymous}',
                      lineRE = /Line\s+(\d+).*?in\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i,
                      i, j, len;

                      for (i = 4, j = 0, len = lines.length; i < len; i += 2)
                      {

                        if (lineRE.test(lines[i]))
                        {
                          lines[j++] = (RegExp.$3 ?
                        RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 :
                        ANON + RegExp.$2 + ':' + RegExp.$1) +
                        ' -- ' + lines[i + 1].replace(/^\s+/, '');
                        }
                      }

                      lines.splice(j, lines.length - j);
                      return lines;
                    }
                  };
                  default: return function()
                  {
                    var curr = arguments.callee.caller,
                    FUNC = 'function', ANON = "{anonymous}",
                    fnRE = /function\s*([\w\-$]+)?\s*\(/i,
                    stack = [], j = 0,
                    fn, args, i;

                    while (curr)
                    {
                      fn = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON;
                      args = stack.slice.call(curr.arguments);
                      i = args.length;

                      while (i--)
                      {
                        switch (typeof args[i])
                        {
                          case 'string': args[i] = 'string arg[' + i + ']'; break; //"' + args[i].replace(/"/g, '\\"') + '"
                          case 'function': args[i] = FUNC; break;
                        }
                      }

                      stack[j++] = fn + '(' + args.join() + ')<br />';
                      curr = curr.caller;
                    }

                    return stack;
                  };
                }
              },
              p: "<p>",
              newline: "<rn>",
              process_Error: function process_Error(errorType, pageuri, lineNumber, message, stackTrace)
              {
                if (cx.page._hasSentErrorMessage || !cx.EnableLogging)
                  return;
                cx.page._hasSentErrorMessage = true;
                // create ajax call to send the error message to the server
                var page = "/shared/script/cx/ClientErrorHandler.ashx?errorType=" + errorType + "&page=" + pageuri + "&lineNumber=" + lineNumber + "&message=" + message + "&stackTrace=" + stackTrace;
                try
                {
                  var conn = YAHOO.util.Connect.asyncRequest('GET', page + '&time=' + new Date().getTime(), new cx.page.error_Callback());
                }
                catch (e) { }
              },
              error_Callback: function error_Callback()
              {
                return {
                  success: function(o)
                  {
                    //alert(o.responseText);
                  },
                  failure: function()
                  {
                    //alert('error on server while processing error');
                  }
                }
              },
              _hasSentErrorMessage: false,
              _on_ErrorCalled: false,
              on_Error: function on_Error(message, uri, line, errorType)
              {

                if (!errorType)
                {
                  errorType = 0
                }
                if (uri.indexOf('banman') > 0)
                  return;
                if (cx.page._on_ErrorCalled)
                  return;
                cx.page._on_ErrorCalled = true;
                var sb = new String();
                sb += "uncaught runtime error has occured:";
                if (null == message)
                  message = "no inner message attached to this error";
                if (null == uri)
                  uri = "the uri is not available";
                if (null == line)
                  line = "the line which the error occured is not available";
                var stacktrace = cx.page.getStackTrace()().toString().replace("&", "andamp");
                stacktrace = encodeURI(stacktrace.replace("Stack trace:", ''));

                //message += cx.page.newline + stacktrace;
                message += cx.page.p + "User browser details:";
                message += cx.page.newline + "appCodeName: " + cx.browser.codeName;
                message += cx.page.newline + "appName: " + cx.browser.name;
                message += cx.page.newline + "appVersion: " + cx.browser.version.value;
                message += cx.page.newline + "userAgent: " + cx.browser.userAgent;
                message += cx.page.newline + "platform: " + cx.browser.platform;


                cx.page.process_Error(errorType, uri, line, message, stacktrace);
              },
              on_Init: function on_Init()
              {
                window.onerror = this.on_Error;
              },
              on_Load: function on_Load()
              {
              },
              ///<summary>
              /// processes an error object to the server. this is the intended method for handling an error
              /// as it provides a chain from the stack trace to be visible in the error report.
              ///</summary>
              /// <param name="errorObject">a javascript Error Object that represents the current error</param>
              /// <param name="optionalMessage">addional information about this error</param>
              handle_Error: function handle_Error(errorObject, optionalMessage)
              {
                var page = cx.request.url;
                var sb = new String();
                if (null != errorObject)
                {
                  try
                  {
                    sb += errorObject.message;
                  }
                  catch (e) { }
                  if (cx.browser.version.isIE)
                  {
                    // if this is an IE browser we get description and number
                    //where description (usually object expected) is additional message information
                    // and number is the error number
                    try
                    {
                      sb += "Error Description: " + errorObject.description;
                      sb += " Error Code: " + errorObject.number;
                    }
                    catch (e) { }
                  }
                  else if (cx.browser.version.isFireFox)
                  {
                    try
                    {
                      sb += " File: " + errorObject.fileName;
                    }
                    catch (e) { }
                  }
                }
                if (null != optionalMessage && optionalMessage.length > 0)
                {
                  sb += this.p + "Developer Message: ";
                  sb += this.newline + optionalMessage;
                }
                this.on_Error(sb.toString(), page, 0, 1);

                throw errorObject.message;
              }
            }
          } ();
          //cx.page.on_Init();
          
          ///<summary>
          /// a namespace to register UI functionality.
          ///</summary>
          cx.ui = {};



//          /* Extending javascript framework */
          String.prototype.trimString = function() { return this.replace(/^\s+|\s+$/g, ""); };   //renamed to avoid conflict with JQuery
//          String.prototype.ltrim = function() { return this.replace(/^\s+/, ""); }
//          String.prototype.rtrim = function() { return this.replace(/\s+$/, ""); }

