

/***********************************************************************************
 * GLOBAL FUNCTIONS
 ***********************************************************************************/

/**
 * Get element x and y coordinates
 */
function getElementLocation(aElement) {
    function getNextAncestor(aElement) {
        var actualStyle;
        if (window.getComputedStyle) {
            actualStyle = getComputedStyle(aElement,null).position;
        }
        else if( aElement.currentStyle) {
            actualStyle = aElement.currentStyle.position;
        }
        else {
            //fallback for browsers with low support - only reliable for inline styles
            actualStyle = aElement.style.position;
        }
        if (actualStyle == 'absolute' || actualStyle == 'fixed') {
            //the offsetParent of a fixed position element is null so it will stop
            return aElement.offsetParent;
        }
        return aElement.parentNode;
    }

    if (typeof(aElement) == "string") aElement = elem(aElement);
    if (!aElement) return null;

    if (typeof(aElement.offsetParent) != 'undefined') {
        var originalElement = aElement;
        for (var posX = 0, posY = 0; aElement; aElement = aElement.offsetParent) {
            posX += aElement.offsetLeft;
            posY += aElement.offsetTop;
        }
        if (!originalElement.parentNode || !originalElement.style || typeof(originalElement.scrollTop) == 'undefined') {
            //older browsers cannot check element scrolling
            return {"x":posX, "y":posY};
        }
        aElement = getNextAncestor(originalElement);
        while (aElement && aElement != document.body && aElement != document.documentElement) {
            posX -= aElement.scrollLeft;
            posY -= aElement.scrollTop;
            aElement = getNextAncestor(aElement);
        }
        return {"x":posX, "y":posY};
    }
    else {
        return {"x":aElement.x, "y":aElement.y};
    }
}


/**
 * Set element x and y coordinates
 */
function setElementLocation(element, x, y) {
    if (typeof(element) == "string") element = elem(element);
    if (!element) return;

    element.style.position = "absolute";
    element.style.left = x + "px";
    element.style.top = y + "px";
}


/**
 * Get mouse x and y coordinates
 */
function getMouseLocation(event) {
    var result = new Object();
    if (event) {
        result.x = event.clientX + document.body.scrollLeft;
        result.y = event.clientY + document.body.scrollTop;
    }
    else {
        result.x = window.event.clientX + document.body.scrollLeft;
        result.y = window.event.clientY + document.body.scrollTop;
    }
    return result;
}


/**
 * Get element dimension
 */
function getElementDimension(element) {
    if (typeof(element) == "string") element = elem(element);
    if (!element) return null;

    var result = new Object();
    if (document.defaultView && document.defaultView.getComputedStyle) {
        result.w = parseInt(document.defaultView.getComputedStyle(element, "").getPropertyValue("width"));
        result.h = parseInt(document.defaultView.getComputedStyle(element, "").getPropertyValue("height"));
    } else {
        result.w = element.clientWidth;
        result.h = element.clientHeight;
    }

    return result;
}


/**
 * Set element width and height
 */
function setElementDimension(element, w, h) {
    if (typeof(element) == "string") element = elem(element);
    if (!element) return;

    element.style.width = w + "px";
    element.style.height = h + "px";
}


/**
 * Set opacity
 */
function setOpacity(element, value) {
    if (typeof(element) == "string") element = elem(element);
    if (!element) return;

    if (page.agent.isIE()) {
        element.style.filter = 'alpha(opacity=' + value + ')';
    }
    else if (page.agent.isFirefox() || page.agent.isMozilla()) {
        element.style.opacity = value/100;
    }
    else {
        element.style.opacity = value/100;
    }
}


/**
 * Get element by id
 */
function elem(id) {
    return document.getElementById(id);
}


/**
 * Get element by id
 */
function e(eId) {
    return document.getElementById(eId);
}


/**
 * setHtml
 */
function setHtml(element, html) {
    if (typeof(element) == "string") {
        element = document.getElementById(element);
    }

    try {
        element.innerHTML = html;
    }
    catch(ex) {
        if (document.contentType == "application/xhtml+xml") {
            setHtmlThroughDOM(element, "<span xmlns=\"http://www.w3.org/1999/xhtml\">" + html + "</span>");
        }
    }
}


/**
 * setHtmlThroughDOM
 */
function setHtmlThroughDOM(element, html) {
    if (typeof(element) == "string") {
        element = document.getElementById(element);
    }

    try {
        var children = element.childNodes;
  
        for (var i = 0; i < children.length; i++) {
            element.removeChild(children[i]);
        }
  
        var nodes = new DOMParser().parseFromString( html, 'text/xml' ).documentElement;
        var range = document.createRange();
        range.selectNodeContents( element );
        range.deleteContents();
  
        for (var i = 0; i < nodes.childNodes.length; i++) {
            element.appendChild(document.importNode(nodes.childNodes[i], true));
        }
    }
    catch(ex) {
    }
}


/**
 * Get object functions
 */
function getFunctions(obj)
{
    var str = "";
    for (i in obj) {
         if (i != "selectionStart" && i != "selectionEnd" && i != "domConfig") {
             if (typeof(obj[i]) == "function") {
                 str = str + i + " => " + obj[i] + "\n";
             }
         }
    }

    return str;
}


/**
 * print_r
 */
function print_r(mixed)
{
    var innerHtml = "";
    if (typeof(mixed) == "object") {
        for (i in mixed) {
             if (i != "selectionStart" && i != "selectionEnd" && i != "domConfig" && mixed[i]!=null && typeof(mixed[i]) != "function" && typeof(mixed[i]) != "unknown") {
                 innerHtml = innerHtml + i + " => " + mixed[i] + "\n";
             }
        }
    }
    else if (typeof(mixed) == "number") {
        innerHtml = "" + mixed;
    }
    else {
        innerHtml = mixed;
    }

    var elementTA = document.getElementById('print_r_TextArea');
    if (elementTA) {
        elementTA.value = elementTA.value + "\n\n============================ new entry ============================\n\n" + innerHtml;
        return;
    }

    var e = document.createElement("div");
    e.style.position = "absolute";
    e.id = page.createUID();
    document.body.appendChild(e);

    var btnCloseID = page.createUID();

    var html = "";
    html += "<table border='0' cellspacing='1' cellpadding='0' style='text-align:center;background-color:#286692;width:" + (page.windowWidth()-180) + "px;'>";
    html += "<tr><td style='background-color:#1D7CC0;padding:5 0 5 0;color:#FFFFFF;font-weight:bold;'>Debug Window</td></tr>";
    html += "<tr><td style='background-color:#D8EFFF'><textarea id='print_r_TextArea' style='width:100%;height:550px' readonly='readonly'>" + innerHtml + "</textarea></td></tr>";
    html += "<tr><td style='background-color:#D8EFFF;'><input id='" + btnCloseID + "' type='button' value='CLOSE' style='width:100%;height:28px;' /></td></tr>";
    html += "</table>";

    setHtml(e, html);
    page.centerElement(e);

    document.getElementById(btnCloseID).onclick = function() {
        document.body.removeChild(e);
    }
}


/**
 * httpBuildQuery
 */
function httpBuildQuery(obj, args) {
    var str = "";
	  for (k in obj) {
	      var v = obj[k];
	      if (v) {
	          if (isArray(v)) {
	              var arrstr = "";
	              for (var ind=0; ind<v.length; ind++) {
	              	   if (args && args['target'] && args['target']=='ajax') {
	              	       arrstr += escape(k) + "[]=" + encodeURIComponent(v[ind]) + "&";
	              	   }
	              	   else {
	              	       arrstr += escape(k) + "[]=" + escape(v[ind]) + "&";
	              	   }
	              }

	              str += arrstr;
	          }
	          else {
            	  if (args && args['target'] && args['target']=='ajax') {
            	      str += escape(k) + "=" + encodeURIComponent(v) + "&";
            	  }
            	  else {
            	      str += escape(k) + "=" + escape(v) + "&";
            	  }
	          }
	      }
	      else {
	          str += k + "=" + "&";
	      }
    }

    if (str.length > 0) {
        str = str.substr(0, str.length-1);
    }

    return str;
}


/**
 * Parse query string
 */
function httpParseQuery(str) {
    var obj = {};
    var arr = str.split("&");
    for (var i=0; i<arr.length; i++) {
         var pairStr = arr[i];
         pairArr = pairStr.split("=");
         if (pairArr.length == 2) {
             var k = unescape(pairArr[0]);
             var v = pairArr[1];
             v = v.split("+").join(" ");
             v = unescape(v);
             obj[k] = v;
         }
    }

    return obj;
}


/**
 * Gets quotes safe string.
 */
function safequot(str) {
    str = "" + str;
    str = str.replace(/'/g, "&#039;");
    str = str.replace(/"/g, "&quot;");
    return str;
}


/**
 * Get select element value
 */
function getSelectElementValue(element) {
    if (typeof(element) == "string") {
        element = document.getElementById(element);
    }

    if (!element || !element.tagName) {
        return null;
    }

    var tagName = element.tagName.toLowerCase();

    if (tagName == "select") {
        var arr = new Array();
        for (var j=0; j<element.options.length; j++) {
            if (element.options[j].selected) {
                arr.push(element.options[j].value);
            }
        }

        if (element.multiple) {
            return arr;
        }
        else if (arr.length == 1) {
            return arr[0];
        }
    }

    return null;
}


/**
 * Get element value
 */
function getElementValue(element) {
    if (typeof(element) == "string") {
        if (page && page[element]) {
            return page[element].getValue();
        }
        element = document.getElementById(element);
    }

    if (!element || !element.tagName) {
        return null;
    }

    var tagName = element.tagName.toLowerCase();

    if (tagName == "span" || tagName == "div") {
        return element.innerHTML;
    }
    else if (tagName == "textarea") {
        return element.value;
    }
    else if (tagName == "input") {
        var type = element.type.toLowerCase();

        if (type == "text" || type == "password" || type == "hidden" || type == "radio") {
            return element.value;
        }
        else if (type == "checkbox") {
            return element.checked ? true : false;
        }
    }
    else if (tagName == "select") {
        return getSelectElementValue(element);
    }

    return null;
}


/**
 * Set select element value
 */
function setSelectElementValue(element, value) {
    if (typeof(element) == "string") {
        element = document.getElementById(element);
    }

    if (element) {
        var tagName = element.tagName.toLowerCase();
        if (tagName == "select" && value != null) {
            var selectedValueList = {};
            for (var i=0; i<element.options.length; i++) {
                if (element.options[i].selected) {
                    selectedValueList[element.options[i].value] = true;
                }
            }

            if (typeof value == "string" || typeof value == "number") {
                selectedValueList = {};
                selectedValueList[value] = true;
            }
            else if (isArray(value)) {
                selectedValueList = {};
                for (i=0; i<value.length; i++) {
                    selectedValueList[value[i]] = true;
                }
            }
            else if (value.constructor === Object) {
                var tmp = value["selected"];
                if (tmp != null && (typeof tmp == "string" || typeof tmp == "number")) {
                    selectedValueList = {};
                    selectedValueList[tmp] = true;
                    delete value["selected"];
                }
                else if (tmp != null && isArray(tmp)) {
                    selectedValueList = {};
                    for (i=0; i<tmp.length; i++) {
                        selectedValueList[tmp[i]] = true;
                    }
                    delete value["selected"];
                }

                element.options.length = 0;
                for (var k in value) {
                    element.options[element.options.length] = new Option(value[k], k);
                }
            }

            for (i=0; i<element.options.length; i++) {
                element.options[i].selected = selectedValueList[element.options[i].value] ? true : false;
            }
        }
    }
}


/**
 * Set element value
 */
function setElementValue(element, value) {
    if (typeof(element) == "string") {
        element = document.getElementById(element);
    }

    if (element) {
        var tagName = element.tagName.toLowerCase();

        if (tagName == "select" && value != null) {
            this.setSelectElementValue(element, value);
        }
        else if (tagName == "span" || tagName == "div" || tagName == "td") {
            setHtml(element, value);
        }
        else if (tagName == "img") {
            element.src = value;
        }
        else if ((tagName == "input" && (element.type == "text" || element.type == "password")) || tagName == "textarea") {
            element.value = value;
        }
        else if (tagName == "input" && element.type == "checkbox") {
            if (value == true || value == "true" || value == "on" || value == "t") {
                element.checked = true;
            } else {
                element.checked = false;
            }
        }
        else if (tagName == "input" && element.type == "hidden") {
            var element2 = document.getElementById(element.id + "Iframe");
            if (element2 && element2.tagName.toLowerCase() == "iframe") {
                element.value = value;
                eval(element.id + ".onHiddenFieldChanged()");
            }
        }
    }
}


/**
 * Apply element style properties
 */
function applyElementStyleProperties(element, obj) {
    if (typeof(element) == "string") {
        element = document.getElementById(element);
    }

    if (element && element.style && obj) {
        if (typeof(obj) == "object") {
            for (var k in obj) element.style[k] = obj[k];
        }
    }
}


/**
 * Fetch form
 */
function fetchForm(formName) {
    var result = new Object();
    var frm = document.forms[formName];

    if (frm) {
        for (var i in frm.elements) {
            var element = frm.elements[i];
            if (element.name) {
                var value = getElementValue(element);
                if (value != null) {
                    result[element.name] = value;
                }
            }
        }
    }
    return result;
}


/**
 * Submit data to dialog opener
 */
function submitDataToDialogOpener(data) {
    var dialogID = page.model.getProperty("____dialogID");
    if (dialogID && window.parent && window.parent.page) {
        var dialog = window.parent.page.widget(dialogID);
        if (dialog) {
            dialog.fireChildDataEvent(json_encode(data));
            return;
        }
    }

    alert("System can't find dialog opener");
}


/**
 * Catch event
 */
function catchEvent(element, type, handler) {
    if (typeof(element) == "string") {
        element = document.getElementById(element);
    }

    if (element.attachEvent) {
        element.attachEvent('on'+type, function() {handler.call(this, window.event.srcElement, window.event)});
    }
    else {
        element.addEventListener(type, function(evt) {handler.call(this, evt.target, evt)}, false);
    }
}


/**
 * Converts file size to human readable text
 */
function filesizeToString(size) {
    if (!size || size == 0) {
        return "";
    }

    if (size < 1024) {
        return size + "b";
    }

    if (size < 1048576) {
        return Math.floor(size/1024) + "kb " + filesizeToString(size-Math.floor(size/1024)*1024);
    }

    if (size < 1073741824) {
        return Math.floor(size/(1048576)) + "mb " + filesizeToString(size-Math.floor(size/(1048576))*1048576);
    }

    if (size < 1099511627776) {
        return Math.floor(size/(1073741824)) + "gb " + filesizeToString(size-Math.floor(size/(1073741824))*1073741824);
    }

    return size + "";
}


/**
 * Join properties
 */
function joinProperties(assoc1, assoc2, assoc3) {
    if (!assoc1) assoc1 = new Object();
    if (!assoc2) assoc2 = new Object();
    if (!assoc3) assoc3 = new Object();
    var tmp = new Object();
    for (var k1 in assoc1) tmp[k1] = assoc1[k1];
    for (var k2 in assoc2) tmp[k2] = assoc2[k2];
    for (var k3 in assoc3) tmp[k3] = assoc3[k3];
    return tmp;
}


/**
 * Check for array
 */
function isArray(aObject) {
    return typeof(aObject) == "object" && aObject.constructor === Array;
}


/**
 * JSON encode
 */
function json_encode(data) {
    return JSON.stringify(data);
}


/**
 * JSON decode
 */
function json_decode(str) {
    return JSON.parse(str);
}


/***********************************************************************************
 * TClass definition
 ***********************************************************************************/
 
var TClass = {
    create: function() {
        return function() {
            this.initialize.apply(this, arguments);
        }
    }
}


Object.extend = function(destination, source) {
    for (property in source) {
         destination[property] = source[property];
    }
    return destination;
}


Object.extend( TClass, {
    extend: function(source, additions) {
        var newclass = TClass.create();
        if ($C(source)) {
            Object.extend( $C(newclass),$C(source) );
        }
        Object.extend( $C(newclass), additions );
        return newclass;
    }
});


function $C(object) {
    return object.prototype;
}




/***********************************************************************************
 * TWebControl definition
 ***********************************************************************************/

var TWebControl = TClass.extend({}, {

    /**
     * Constructor
     */
    initialize: function(name) {
       this.fName = name;
       this.fClassName = '';
       this.fStyle = '';
       this.fProperties = new Object();
       this.fVisible = true;
       this.fEnabled = true;
       this.fDisplay = true;
       this.fParent = null;
       this.fWidgetPath = '';
       this.fI18N = {};
       this.fActionType = "post";
       this.submitValue = true;
    },


    /**
     * Get name
     */
    getName: function() {
        return this.fName;
    },


    /**
     * Set parent
     */
    setParent: function(aParent) {
        this.fParent = aParent;
    },


    /**
     * Get parent
     */
    getParent: function() {
        return this.fParent;
    },


    /**
     * Set property
     */
    setProperty: function(key, value) {
        this.fProperties[key.toLowerCase()] = value;
    },


    /**
     * Get property
     */
    getProperty: function(key) {
        return this.fProperties[key.toLowerCase()];
    },


    /**
     * Get property
     */
    prop: function(key) {
        return this.getProperty(key);
    },


    /**
     * Has property
     */
    hasProperty: function(key) {
        return this.fProperties[key.toLowerCase()] != null;
    },


    /**
     * Get properties
     */
    getProperties: function() {
        return this.fProperties;
    },


    /**
     * Remove property
     */
    removeProperty: function(key) {
        if (this.hasProperty(key)) {
            delete this.fProperties[key.toLowerCase()];
        }
    },


    /**
     * Set class name
     */
    setClassName: function(aClassName) {
        this.fClassName = aClassName;
    },


    /**
     * Get class name
     */
    getClassName: function() {
        return this.fClassName;
    },


    /**
     * Apply class
     */
    applyClass: function(aClassName) {
        if (elem(this.getName())) elem(this.getName()).className = aClassName;
    },


    /**
     * Set style
     */
    setStyle: function(aStyle) {
        this.fStyle = aStyle;
    },


    /**
     * Get style
     */
    getStyle: function() {
        return this.fStyle;
    },


    /**
     * Apply style properties
     */
    applyStyleProperties: function(aStyleList) {
        applyElementStyleProperties(this.getName(), aStyleList);
    },


    /**
     * Get location
     */
    getLocation: function() {
        if (elem(this.getName() + "Widget")) {
            return getElementLocation(elem(this.getName() + "Widget"));
        }
        else if (elem(this.getName())) {
            return getElementLocation(elem(this.getName()));
        }

        return null;
    },


    /**
     * Set location
     */
    setLocation: function(x, y) {
        if (elem(this.getName() + "Widget")) {
            setElementLocation(elem(this.getName() + "Widget"), x, y);
        }
        else if (elem(this.getName())) {
            setElementLocation(elem(this.getName()), x, y);
        }
    },


    /**
     * Get dimension
     */
    getDimension: function() {
        if (elem(this.getName() + "Widget")) {
            return getElementDimension(elem(this.getName() + "Widget"));
        }
        else if (elem(this.getName())) {
            return getElementDimension(elem(this.getName()));
        }

        return null;
    },


    /**
     * Set dimension
     */
    setDimension: function(width, height) {
        if (elem(this.getName() + "Widget")) {
            setElementDimension(elem(this.getName() + "Widget"), width, height);
        }
        else if (elem(this.getName())) {
            setElementDimension(elem(this.getName()), width, height);
        }
    },


    /**
     * Set bounds
     */
    setBounds: function(x1, y1, x2, y2) {
        this.setLocation(x1, y1);
        this.setDimension(x2-x1, y2-y1);
    },


    /**
     * Set widget path
     */
    setWidgetPath: function(widgetPath) {
        this.fWidgetPath = widgetPath;
    },


    /**
     * Get widget path
     */
    getWidgetPath: function() {
        return this.fWidgetPath;
    },


    /**
     * Add locale strings
     */
    addLocaleStrings: function(localeStrings) {
        for (var key in localeStrings) {
             this.fI18N[key] = localeStrings[key];
        }
    },


    /**
     * Get locale string
     */
    i18n: function(localeString) {
        return (this.fI18N[localeString]!=null ? this.fI18N[localeString] : localeString);
    },


    /**
     * Set action type
     */
    setActionType: function(aType) {
        this.fActionType = aType;
    },


    /**
     * Set value
     */
    setValue: function(aValue) {
        if (elem(this.getName())) {
            elem(this.getName()).value = aValue;
        }
    },


    /**
     * Get value
     */
    getValue: function() {
        if (elem(this.getName())) {
            return elem(this.getName()).value;
        }

        return null;
    },


    /**
     * Set enabled
     */
    setEnabled: function(aValue) {
        this.fEnabled = aValue;
        if (elem(this.getName())) {
            elem(this.getName()).disabled = aValue ? false : true;
        }
    },


    /**
     * Is enabled
     */
    isEnabled: function() {
        return this.fEnabled;
    },


    /**
     * Set visible
     */
    setVisible: function(aValue) {
        this.fVisible = aValue;
        if (elem(this.getName())) {
            elem(this.getName()).style.visibility = aValue ? "visible" : "hidden";
        }
    },


    /**
     * Is visible
     */
    isVisible: function() {
        return this.fVisible;
    },


    /**
     * Set display
     */
    setDisplay: function(aValue) {
        this.fDisplay = aValue;
        var tgt = null;
        if (elem(this.getName() + "Widget")) {
            tgt = elem(this.getName() + "Widget");
        }
        else if (elem(this.getName())) {
            tgt = elem(this.getName());
        }

        if (tgt) {
            if (aValue == true) {
                tgt.style.display = "";
            }
            else if (aValue == false) {
                tgt.style.display = "none";
            }
            else if (aValue) {
                tgt.style.display = aValue;
            }
        }
    },


    /**
     * Set error message
     */
    setErrorMessage: function(aMessage) {
        var target = elem(this.getName() + "_error");
        if (target) {
            target.innerHTML = aMessage;
        }
    },


    /**
     * Fire action event
     */
    fireActionEvent: function(aActionSource, aActionName, aActionParams) {
        if (!this.fEnabled) return;
        page.submitAction(this.fActionType, aActionSource, aActionName, aActionParams);
    },


    /**
     * Destroy
     */
    destroy: function() {
        var el = elem(this.getName());
        if (el && el.parentNode) el.parentNode.removeChild(el);

        var w = elem(this.getName() + "Widget");
        if (w && w.parentNode) w.parentNode.removeChild(w);
    }
});


/**
 * TLabel
 */
var TLabel = TClass.extend(TWebControl, {

    /**
     * Constructor
     */
    initialize: function(name) {
        $C(TWebControl).initialize.call(this, name);
        this.submitValue = false;
        this.fDisplayWhenEmpty = true;
    },


    /**
     * Set value
     */
    setValue: function(aValue) {
        elem(this.getName()).innerHTML = aValue;
        if (!this.fDisplayWhenEmpty) {
            this.setDisplay(aValue ? true : false);
        }
    },


    /**
     * Get value
     */
    getValue: function() {
        return elem(this.getName()).innerHTML;
    },


    /**
     * Set enabled
     */
    setEnabled: function(aValue) {
    },


    /**
     * Set display when empty
     */
    setDisplayWhenEmpty: function(aValue) {
        this.fDisplayWhenEmpty = aValue;
    }
});


/**
 * TImage
 */
var TImage = TClass.extend(TWebControl, {

    /**
     * Constructor
     */
    initialize: function(name) {
        $C(TWebControl).initialize.call(this, name);
        this.submitValue = false;
    },


    /**
     * Set image source
     */
    setImageSource: function(aSource) {
        if (elem(this.getName())) elem(this.getName()).src = aSource;
    },


    /**
     * Set value
     */
    setValue: function(aValue) {
    },


    /**
     * Get value
     */
    getValue: function() {
        return null;
    }
});



/**
 * THiddenField
 */
var THiddenField = TClass.extend(TWebControl, {

    /**
     * Constructor
     */
    initialize: function(name) {
        $C(TWebControl).initialize.call(this, name);
    }

});



/**
 * TTextBox
 */
var TTextBox = TClass.extend(TWebControl, {

    /**
     * Constructor
     */
    initialize: function(name) {
        $C(TWebControl).initialize.call(this, name);
    },


    /**
     * Handle enter key
     */
    handleEnterKey: function(aButtonName) {
        catchEvent(this.getName(), "keypress", function(src, e) {
            var key = (e.keyCode || e.which);
            if (key==13) {
                page[aButtonName].fireClickEvent();
            }
        });
    }

});



/**
 * TCheckBox
 */
var TCheckBox = TClass.extend(TWebControl, {

    /**
     * Constructor
     */
    initialize: function(name, args) {
        $C(TWebControl).initialize.call(this, name);
        if (args["mode"]) {
            this.setActionType(args["mode"]);
        }
    },


    /**
     * Set value
     */
    setValue: function(aValue) {
        this.setChecked(aValue == true || aValue == "on" ? true : false);
    },


    /**
     * Get value
     */
    getValue: function() {
        return this.isChecked() ? "on" : null;
    },


    /**
     * Set checked
     */
    setChecked: function(aValue) {
        elem(this.getName()).checked = aValue ? true : false;
    },


    /**
     * Query checked state
     */
    isChecked: function() {
        return elem(this.getName()).checked;
    },


    /**
     * Fire click event
     */
    fireClickEvent: function() {
        this.fireActionEvent(this.getName(), this.getName() + "_OnClick");
    }

});



/**
 * TSelectBox
 */
var TSelectBox = TClass.extend(TWebControl, {

    /**
     * Constructor
     */
    initialize: function(name, args) {
        $C(TWebControl).initialize.call(this, name);
        if (args["mode"]) {
            this.setActionType(args["mode"]);
        }

        var widgetName = this.getName();
        catchEvent(widgetName, 'change', function() {
            if (page.widget(widgetName)) {
                page.widget(widgetName).fireChangeEvent();
            }
        });
    },


    /**
     * Set options
     */
    setOptions: function(aOptions) {
        var target = elem(this.getName());
        target.options.length = 0;

        for (var i in aOptions) {
            var opt = aOptions[i];
            target.options[target.options.length] = new Option(opt["text"], opt["value"]);
        }
    },


    /**
     * Set value
     */
    setValue: function(aValue) {
        setSelectElementValue(this.getName(), aValue);
    },


    /**
     * Get value
     */
    getValue: function() {
        return getSelectElementValue(this.getName());
    },


    /**
     * Fire click event
     */
    fireChangeEvent: function() {
        this.fireActionEvent(this.getName(), this.getName() + "_OnChange");
    }

});



/**
 * TAbstractButton
 */
var TAbstractButton = TClass.extend(TWebControl, {

    /**
     * Constructor
     */
    initialize: function(name, args) {
        $C(TWebControl).initialize.call(this, name);
        this.submitValue = false;
        this.args = args;

        if (args["mode"]) {
            this.setActionType(args["mode"]);
        }

        var widgetName = this.getName();
        catchEvent(widgetName, 'click', function() {
            if (page.widget(widgetName)) {
                page.widget(widgetName).fireClickEvent();
            }
        });
    },


    /**
     * Fire click event
     */
    fireClickEvent: function() {
        if (this.args["cm"]) {
            var _self = this;
            page.showConfirm(this.args["cm"], function() {_self.fireActionEvent(_self.getName(), _self.getName() + "_OnClick");});
        } else {
            this.fireActionEvent(this.getName(), this.getName() + "_OnClick");
        }
    },


    /**
     * Fire click event
     */
    click: function() {
        this.fireClickEvent();
    }

});


/**
 * TButton
 */
var TButton = TClass.extend(TAbstractButton, {

    /**
     * Constructor
     */
    initialize: function(name, args) {
        $C(TAbstractButton).initialize.call(this, name, args);
    }

});



/**
 * TLinkButton
 */
var TLinkButton = TClass.extend(TAbstractButton, {

    /**
     * Constructor
     */
    initialize: function(name, args) {
        $C(TAbstractButton).initialize.call(this, name, args);
    },


    /**
     * Set value
     */
    setValue: function(aValue) {
        elem(this.getName()).innerHTML = aValue;
    },


    /**
     * Set enabled
     */
    setEnabled: function(aValue) {
        this.fEnabled = aValue;
        setOpacity(this.getName(), aValue?100:30);
    }

});



/**
 * TImageButton
 */
var TImageButton = TClass.extend(TAbstractButton, {

    /**
     * Constructor
     */
    initialize: function(name, args) {
        $C(TAbstractButton).initialize.call(this, name, args);
    },


    /**
     * Set enabled
     */
    setEnabled: function(aValue) {
        this.fEnabled = aValue;
        setOpacity(this.getName() + "Image", aValue?100:30);
    }

});
/***********************************************************************************
 * TDataModel definition
 ***********************************************************************************/

var TDataModel = TClass.extend({}, {

    /**
     * Constructor
     */
    initialize: function() {
        this.fPropertyList = {};
    },


    /**
     * Set property
     */
    setProperty: function(key, value, stateful) {
        var obj = {};
        obj["val"] = value;
        obj["sf"] = (stateful?true:false);
        this.fPropertyList[key] = obj;
    },


    /**
     * Get property
     */
    getProperty: function(key) {
        return (this.fPropertyList[key] ? this.fPropertyList[key]["val"] : null);
    },


    /**
     * Get property list
     */
    getPropertyList: function() {
        var list = {};
        for (var k in this.fPropertyList) {
            list[k] = this.fPropertyList[k]["val"];
        }
        return list;
    },


    /**
     * Get stateful property list
     */
    getStatefulPropertyList: function() {
        var list = {};
        for (var k in this.fPropertyList) {
            if (this.fPropertyList[k]["sf"]) {
                list[k] = this.fPropertyList[k]["val"];
            }
        }
        return list;
    },


    /**
     * Remove property
     */
    removeProperty: function(key) {
        if (this.fPropertyList[key]) {
            delete this.fPropertyList[key];
        }
    }
});

/***********************************************************************************
 * TPage definition
 ***********************************************************************************/

var TPage = TClass.extend(TWebControl, {

    /**
     * Constructor
     */
    initialize: function() {
        $C(TWebControl).initialize.call(this, "");
        this.devMode = false;
        this.ajax = null;
        this.model = new TDataModel();
        this.widgetList = new Array();
        this.agent = new THttpAgent();

        this.lockId = "TPage_LockId";
        this.availableDialogs = 0;
        this.topZIndex = 50;

        var blankImg = new Image();
        blankImg.src = "/system/assets/images/blank.gif";

        this.UID = 7235;
        this.scriptLoadingNumber = 0;

        this.fWaitDialogs = new Object();
        this.fWidgetsInProgress = 0;
        this.submitInterrupted = false;

        this.addLocaleStrings({
           "BTN_OK": "OK",
           "BTN_CLOSE": "CLOSE",
           "BTN_CANCEL": "CANCEL",
           "BTN_YES": "YEP",
           "BTN_NO": "NOPE",
           "SYS_UI_PAGE_INFO_TITLE": "INFO",
           "SYS_UI_PAGE_CONFIRM_TITLE": "CONFIRM",
           "SYS_UI_PAGE_ERRORS_TITLE": "ERRORS",
           "SYS_MSG_ARE_YOU_SURE": "Are you sure ?",
           "SYSMSG_ERROR_ACTION_TERMINATED": "Action has been terminated"
        });
    },


    /**
     * Creates new unique identifier
     */
    createUID: function() {
        return "id" + this.UID++;
    },


    /**
     * Register widget
     */
    registerWidget: function(name, widget) {
        this[name] = widget;
        this.widgetList.push(name);
    },


    /**
     * Get widget
     */
    widget: function(name) {
        return this[name];
    },


    /**
     * Destroy widget
     */
    destroyWidget: function(name) {
        var w = this[name];
        if (w && w.destroy) {
            w.destroy();
            delete this[name];
        }
    },


    /**
     * Destroy widgets
     */
    destroyWidgets: function(list) {
        if (list) {
            for (var index in list) {
                this.destroyWidget(list[index]);
            }
        }
    },


    /**
     * Add widget in progress
     */
    addWidgetInProgress: function() {
        this.fWidgetsInProgress++;
    },


    /**
     * Remove widget in progress
     */
    removeWidgetInProgress: function() {
        this.fWidgetsInProgress--;
    },


    /**
     * Has widgets in progress
     */
    hasWidgetsInProgress: function() {
        return this.fWidgetsInProgress > 0;
    },


    /**
     * Cover this document with opacity layer
     */
    cover: function(aLayerId, opacityValue) {
        var layer = document.createElement("div");
        layer.id = aLayerId;
        layer.style.position = "absolute";

        if (opacityValue==null || (typeof opacityValue != "number") || opacityValue < 0 || opacityValue > 1) {
            opacityValue = 0.6;
        }

        var opacityStr = "";
        var imageFile = "blank.gif";
        if (opacityValue != 0) {
            imageFile = "disablepage.gif";
            if (page.agent.isIE()) {
                opacityStr = "filter:alpha(opacity=100)";
            }
            else {
                opacityStr = "opacity:" + opacityValue;
            }
        }

        var html = "<img id='"+aLayerId+"Child' src=\"/system/assets/images/" + imageFile + "\" style=\"width:{width};height:{height};"+opacityStr+";\" />";
        html = html.replace("{width}", this.docWidth());
        html = html.replace("{height}", (this.docHeight()));

        layer.style.top = "0px";
        layer.style.left = "0px";
        setHtml(layer, html);

        document.body.appendChild(layer);

        if (this.agent.isIE() && elem(aLayerId+"Child")) {
            elem(aLayerId+"Child").filters.alpha.opacity = Math.floor(opacityValue*100);
        }
    },


    /**
     * Uncover this document from opacity layer
     */
    uncover: function(aLayerId) {
        if (elem(aLayerId)) {
            document.body.removeChild(elem(aLayerId));
        }
    },


    /**
     * Toggle enable/disable mode, flag = true means to disable
     */
    toggleEnableDisableMode: function(flag) {
        if (flag) {
            if (document.getElementById(this.lockId)) {
                return;
            }

            this.cover(this.lockId);
        }
        else {
            this.uncover(this.lockId);
        }
    },


    /**
     * Sets disabled
     */
    setDisabled: function() {
        this.toggleEnableDisableMode(true);
    },


    /**
     * Sets enabled
     */
    setEnabled: function() {
        this.toggleEnableDisableMode(false);
    },


    /**
     * Checks to see if page is disabled
     */
    isDisabled: function() {
        if (document.getElementById(this.lockId)) {
            return true;
        }

        return false;
    },


    /**
     * Array of messages/errors to ordered list
     */
    objectToOrderedList: function(arr) {
        var str = "<ol style='margin-top:0px;margin-bottom:0px'>";

        var count = 0;
        var lastItem = null;
        for (var i in arr) {
             str += "<li>" + arr[i] + "</li>";
             lastItem = arr[i];
             count++;
        }

        str += "</ol>";

        return (count == 1 ? "<center>"+lastItem+"</center>" : str);
    },


    /**
     * Shows messages
     */
    showMessages: function(obj, onCloseHandler) {
        var content = "";
        if (typeof(obj) == "string") {
            content = "<center>"+obj+"</center>";
        }
        else if (typeof(obj) == "array" || typeof(obj) == "object") {
            content = this.objectToOrderedList(obj);
        }

        var dialog = new TDialog();
        dialog.setClassName("cssDialogInfo");
        dialog.setDraggable(true);
        dialog.setTitle(this.i18n("SYS_UI_PAGE_INFO_TITLE"));
        dialog.setContent(content);
        dialog.addButton(this.i18n("BTN_CLOSE"), function () {
               dialog.close();
               if (onCloseHandler)
                   onCloseHandler.call();
        });

        dialog.openModal();
        dialog.bringToFront();
        return dialog;
    },


    /**
     * Shows message
     */
    showMessage: function(obj, onCloseHandler) {
        return this.showMessages(obj, onCloseHandler);
    },


    /**
     * Shows errors
     */
    showErrors: function(obj, onCloseHandler) {
        var content = "";
        if (typeof(obj) == "string") {
            content = "<center>"+obj+"</center>";
        }
        else if (typeof(obj) == "array" || typeof(obj) == "object") {
            content = this.objectToOrderedList(obj);
        }

        var dialog = new TDialog();
        dialog.setClassName("cssDialogError");
        dialog.setDraggable(true);
        dialog.setTitle(this.i18n("SYS_UI_PAGE_ERRORS_TITLE"));
        dialog.setContent(content);
        dialog.addButton(this.i18n("BTN_CLOSE"), function () {
               dialog.close();
               if (onCloseHandler)
                   onCloseHandler.call();
        });

        dialog.openModal();
        dialog.bringToFront();
        return dialog;
    },


    /**
     * Shows error message
     */
    showError: function(obj, onCloseHandler) {
        return this.showErrors(obj, onCloseHandler);
    },


    /**
     * Shows confirm message
     */
    showConfirm: function(message, onYesHandler, onNoHandler) {
        var dialog = new TDialog();
        dialog.setClassName("cssDialogInfo");
        dialog.setDraggable(true);
        dialog.setTitle(this.i18n("SYS_UI_PAGE_CONFIRM_TITLE"));
        dialog.setContent("<center>"+message+"</center>");
        dialog.addButton(this.i18n("BTN_YES"), function() {
               dialog.close();
               if (onYesHandler)
                   onYesHandler.call();
        });

        dialog.addButton(this.i18n("BTN_NO"), function() {
               dialog.close();
               if (onNoHandler)
                   onNoHandler.call();
        });

        dialog.openModal();
        dialog.bringToFront();
        return dialog;
    },


    /**
     * Shows prompt message
     */
    showPrompt: function(title, message, onOkHandler, onCancelHandler) {
        var tboxID = this.createUID();
        var dialog = new TDialog();
        dialog.setClassName("cssDialogInfo");
        dialog.setDraggable(true);
        dialog.setTitle(title);
        dialog.setContent("<center>" + message + "&nbsp;<input type='text' id='" + tboxID + "' class='textbox' />" + "</center>");
        dialog.addButton(this.i18n("BTN_OK"), function() {
               var val = elem(tboxID).value;
               dialog.close();
               if (onOkHandler)
                   onOkHandler.call(this, val);
        });

        dialog.addButton(this.i18n("BTN_CANCEL"), function() {
               var val = elem(tboxID).value;
               dialog.close();
               if (onCancelHandler)
                   onCancelHandler.call(this, val);
        });

        dialog.openModal();
        dialog.bringToFront();
        return dialog;
    },


    /**
     * Wait
     */
    wait: function(message) {

        var waitDlg = new TDialog();
        waitDlg.showTitle(false);

        if (message) {
            waitDlg.setClassName("cssDialogWait");
            waitDlg.setContent("<br/>" + message + "<br/><br/>");
            waitDlg.openModal();
        }
        else {
            waitDlg.setClassName("cssNoExistingClass");
            waitDlg.setContent("<img src='/system/assets/images/page_loading.gif' border='0' />");
            waitDlg.openModal();
            waitDlg.getContentElement().style.textAlign = "center";
        }

        var id = this.createUID();
        this.fWaitDialogs[id] = waitDlg;

        return id;
    },


    /**
     * Unwait
     */
    unwait: function(id) {
        var dlg = this.fWaitDialogs[id];
        if (dlg && dlg.isOpen()) {
            dlg.close();
        }
    },


    /**
     * Reload
     */
    reload: function(milsec) {
        var uri = document.location.href;
        if (uri.indexOf("#") >= 0)
            uri = uri.substr(0, uri.indexOf("#"));

        if (milsec)
            setTimeout( function() { document.location.href = uri; }, milsec );
        else {
           document.location.href = uri;
        }
    },


    /**
     * Gets window height
     */
    windowHeight: function() {
        if (this.agent.isIE()) {
            return (document.body.offsetHeight ? document.body.offsetHeight : document.body.clientHeight);
        }
        else {
            return window.innerHeight;
        }
    },


    /**
     * Gets window width
     */
    windowWidth: function() {
        if (this.agent.isIE()) {
            return (document.body.offsetWidth ? document.body.offsetWidth : document.body.clientWidth);
        }
        else {
            return window.innerWidth;
        }
    },


    /**
     * Gets document height
     */
    docHeight: function() {
        return Math.max(document.body.scrollHeight, document.body.clientHeight);
    },


    /**
     * Gets document width
     */
    docWidth: function() {
        return document.body.scrollWidth;
    },


    /**
     * Bring to front
     */
    bringElementToFront: function(element) {
        if (!element.style.zIndex || element.style.zIndex < page.topZIndex)
            element.style.zIndex = ++page.topZIndex;
    },


    /**
     * Centers element
     */
    centerElement: function(element) {
        if (element.clientHeight < this.windowHeight()) {
            element.style.top = document.body.scrollTop + (this.windowHeight() - element.clientHeight)/2 + "px";
        }
        else {
            element.style.top = (this.docHeight() - element.clientHeight)/2 + "px";
        }

        if (element.clientWidth < this.windowWidth()) {
            element.style.left = document.body.scrollLeft + (this.windowWidth() - element.clientWidth)/2 + "px";
        }
        else {
            element.style.left = (this.docWidth() - element.clientWidth)/2 + "px";
        }
    },


    /**
     * Sets look and feel
     */
    setLookAndFeel: function(uri) {
        if (elem("idLafCssLink")) {
            elem("idLafCssLink").href = uri;
        }
    },


    /**
     * Sets cookie
     */
    setCookie: function(name,value,expires) {
        var today = new Date();
        today.setTime( today.getTime() );

        if (expires != 0) {
            expires = expires * 1000;
            var expiresDate = new Date(today.getTime()+expires);
            document.cookie = name + "=" + escape(value) + ";expires=" + expiresDate.toGMTString();
        }
        else {
            document.cookie = name + "=" + escape(value);
        }
    },


    /**
     * Gets cookie
     */
    getCookie: function(name) {
        if (document.cookie.length>0) {
            var startIndex = document.cookie.indexOf(name + "=");
            if (startIndex != -1) {
                startIndex = startIndex+name.length+1; 
                var endIndex = document.cookie.indexOf(";",startIndex);
                if (endIndex == -1)
                    endIndex = document.cookie.length;

                return unescape(document.cookie.substring(startIndex,endIndex));
            }
        }

        return null;
    },


    /**
     * Removes cookie
     */
    removeCookie: function(name) {
        if (this.getCookie(name))
            document.cookie = name + "=;expires=Thu, 01-Jan-1970 00:00:01 GMT";

    },


    /**
     * Adds script file
     */
    addScriptFile: function(uri, id) {
        var scriptElement;
        if (id && document.getElementById(id)) {
            scriptElement = document.getElementById(id);
        }
        else {
            scriptElement = document.createElement('script');
            scriptElement.type = 'text/javascript';
            document.getElementsByTagName('head')[0].appendChild(scriptElement);
            if (id)
                linkElement.id = id;
        }

        if (scriptElement) {
            page.scriptLoadingNumber++;
            if (this.agent.isIE()) {
                scriptElement.onreadystatechange = function () {
                           if (this.readyState == 'loaded') {
                               page.scriptLoadingNumber--;
                           }
                       }
            }
            else {
                scriptElement.onload = function() {page.scriptLoadingNumber--;};
            }
            scriptElement.src = uri;
        }
    },


    /**
     * Adds script content
     */
    addScriptContent: function(content) {
        try {
           var scriptElement = document.createElement('script');
           scriptElement.type = 'text/javascript';
           scriptElement.text = content;
           document.getElementsByTagName('head')[0].appendChild(scriptElement);
        } catch(e) {
           alert(e);
        }
    },


    /**
     * Adds css file
     */
    addCssFile: function(uri, id) {
        var linkElement;
        if (id && document.getElementById(id)) {
            linkElement = document.getElementById(id);
        }
        else {
            linkElement = document.createElement('link');
            linkElement.type = 'text/css';
            linkElement.rel = 'stylesheet';
            document.getElementsByTagName('head')[0].appendChild(linkElement);
            if (id) {
                linkElement.id = id;
            }
        }

        if (linkElement) {
            linkElement.href = uri;
        }
    },


    /**
     * Safe execution of a script
     */
    safeExec: function(content) {
        if (page.scriptLoadingNumber == 0) {
            eval(content);
        }
        else {
            setTimeout(function() {page.safeExec(content); }, 200);
        }
    },


    /**
     * Redirect
     */
    redirect: function(url, params, args) {
        if (!params && !args) {
            document.location.href = url;
            return;
        }

        var frm = document.createElement("FORM");
        frm.action = url;
        
        if (args) {
            if (args['method']) {
                frm.method = args['method'];
            }
            if (args['target']) {
                frm.target = args['target'];
            }
        }

        if (params) {
            for (var k in params) {
                var v = params[k];
    	          if (typeof(v) == "object" && v.constructor === Array) {
    	              for (var ind=0; ind<v.length; ind++) {
                        var hiddenElement = document.createElement("INPUT");
                        hiddenElement.type = "hidden";
                        hiddenElement.name = k + "[]";
                        hiddenElement.value = v[ind];
                        frm.appendChild(hiddenElement);
    	              }
        	      }
        	      else {
                    var hiddenElement = document.createElement("INPUT");
                    hiddenElement.type = "hidden";
                    hiddenElement.name = k;
                    hiddenElement.value = v;
                    frm.appendChild(hiddenElement);
                }
            }
        }

        document.body.appendChild(frm);
        frm.submit();
        document.body.removeChild(frm);
    },


    /**
     * Post redirect
     */
    redirectPost: function(url, params) {
        this.redirect(url, params, {"method" : "post"});
    },


    /**
     * Append model data
     */
    appendModelData: function(data) {
        if (!data) {
            data = new Object();
        }

        var statefulProps = this.model.getStatefulPropertyList();
        for (var propertyKey in statefulProps) {
            var propertyValue = statefulProps[propertyKey];
            if (propertyValue && (typeof propertyValue == "string" || typeof propertyValue == "number")) {
                data["___model_" + propertyKey] = propertyValue;
            }
        }

        for (var i in this.widgetList) {
            var widget = this.widgetList[i];
            var widgetValue = this[widget] && this[widget].submitValue ? this[widget].getValue() : null;
            if (widgetValue) {
                data[widget] = widgetValue;
            }
        }

        return data;
    },


    /**
     * Post back
     */
    postback: function(actionName, actionParams) {
        this.submitAction("post", "hsdgfhsfgE2Sdfd1", actionName, actionParams);
    },


    /**
     * Submit action
     */
    submitAction: function(actionType, actionSource, actionName, actionParams) {
        this.submitInterrupted = false;

        if (actionType) {
            actionType = actionType.toLowerCase();
        }

        if (actionType == "none") {
            return;
        }
        else if (actionType == "js" || actionType == "javascript") {
            eval(actionName + "()");
        }
        else {
            if ((actionType == "ajax" || actionType == "post") && window[actionName] && typeof window[actionName] == "function") {
                var functionResult = window[actionName].call();
                if (functionResult != "undefined" && functionResult == false) {
                    return;
                }
            }

            var disableID = this.createUID();
            this.cover(disableID, 0.3);

            var data = this.appendModelData();

            if (actionParams) {
                for (var n in actionParams) {
                    data[n] = actionParams[n];
                }
            }

            if (this.hasWidgetsInProgress()) {
                var intervalID = setInterval(function() {
                    if (!page.hasWidgetsInProgress()) {
                        clearInterval(intervalID);
                        data = page.appendModelData();
                        page.submitActionImpl(data, actionType, actionSource, actionName, disableID);
                    }
                }, 1000);
            }
            else {
                this.submitActionImpl(data, actionType, actionSource, actionName, disableID);
            }
        }
    },


    /**
     * Submit action impl
     */
    submitActionImpl: function(data, actionType, actionSource, actionName, disableID) {
        if (this.submitInterrupted == true) {
            this.uncover(disableID);
            this.showError(this.i18n("SYSMSG_ERROR_ACTION_TERMINATED"));
            return;
        }

        data["_submit_handler"] = actionName;
        if (actionSource) {
            data["_submit_source"] = actionSource;
        }

        if (actionType == "get" || actionType == "post") {
            data["_submit_type"] = actionType;
            this.redirect(page.submitUri, data, {"method":actionType});
        }
        else if (actionType == "ajax") {
            var _self = this;
            this.ajax.request(data, function(dataEvent) {
                _self.uncover(disableID);
            });
        }
    }

});





/***********************************************************************************
 * THttpAgent definition
 ***********************************************************************************/

var THttpAgent = TClass.extend({}, {

    /**
     * Constructor
     */
    initialize: function() {
    },


    /**
     * isIE
     */
    isIE: function() {
        return (
                 navigator.userAgent.indexOf("MSIE") >= 0 
                 && navigator.userAgent.indexOf("Opera") == -1
                 && navigator.userAgent.indexOf("Konqueror") == -1
               );
    },


    /**
     * isMozilla
     */
    isMozilla: function() {
        return (
                 navigator.userAgent.indexOf( "Mozilla" ) >= 0 
                 && navigator.userAgent.indexOf( "Gecko" ) >= 0
                 && navigator.userAgent.indexOf( "MSIE" ) == -1
                 && navigator.userAgent.indexOf( "Firefox" ) == -1
                 && navigator.userAgent.indexOf( "Opera" ) == -1
                 && navigator.userAgent.indexOf( "Konqueror" ) == -1
                 && navigator.userAgent.indexOf( "Safari" ) == -1
                 && navigator.userAgent.indexOf( "Chrome" ) == -1
               );
    },


    /**
     * isFirefox
     */
    isFirefox: function() {
        return ( navigator.userAgent.indexOf( "Firefox" ) >= 0 );
    },


    /**
     * isOpera
     */
    isOpera: function() {
        return ( navigator.userAgent.indexOf( "Opera" ) >= 0 );
    },


    /**
     * isKonqueror
     */
    isKonqueror: function() {
        return ( navigator.userAgent.indexOf( "Konqueror" ) >= 0 );
    },


    /**
     * isSafari
     */
    isSafari: function() {
        return (navigator.userAgent.indexOf("Safari") >= 0 && navigator.userAgent.indexOf("Chrome") == -1);
    },


    /**
     * isChrome
     */
    isChrome: function() {
        return (navigator.userAgent.indexOf("Chrome") >= 0);
    },


    /**
     * isUnknown
     */
    isUnknown: function() {
        return ( !this.isIE()
                 && !this.isMozilla()
                 && !this.isFirefox()
                 && !this.isOpera()
                 && !this.isKonqueror()
                 && !this.isSafari()
                 && !this.isChrome()
               );
    }

});

if(!this.JSON){this.JSON={};}
(function(){function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
if(typeof rep==='function'){value=rep.call(holder,key,value);}
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
v=partial.length===0?'[]':gap?'[\n'+gap+
partial.join(',\n'+gap)+'\n'+
mind+']':'['+partial.join(',')+']';gap=mind;return v;}
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+
mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
return str('',{'':value});};}
if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
return reviver.call(holder,key,value);}
cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
throw new SyntaxError('JSON.parse');};}}());

/***********************************************************************************
 * TDialog definition
 ***********************************************************************************/

var TDialog = TClass.extend(TWebControl, {

    /**
     * Constructor
     */
    initialize: function() {
        $C(TWebControl).initialize.call(this, page.createUID());
        this.fTitle = "";
        this.fContent = "";
        this.fTitleElementID = page.createUID();
        this.fContentElementID = page.createUID();
        this.fButtons = new Array();
        this.fButtonClickHandlers = new Object();

        this.fShowTitle = true;

        this.fShowMinButton = false;
        this.fShowMaxButton = false;
        this.fShowCloseButton = false;
        this.fShowConfirmOnClose = false;

        this.fSystemButton1 = page.createUID();
        this.fSystemButton2 = page.createUID();
        this.fSystemButton3 = page.createUID();
        this.fCloseHandler = null;

        this.fModalDialog = false;
        this.fModalCoverId = page.createUID();

        this.fContentBoxConstraints = null;
        this.fDraggableMode = false;
        this.fDragObject = null;
        this.fResizableMode = false;
        this.inResizeBox = false;
        this.fResizeObject = null;
        
        this.fIFrameContent = false;
        this.fChildEventListener = null;

        this.tmp = {'State':'normal'};
    },


    /**
     * Get dialog element
     */
    getDialogElement: function() {
        return elem(this.getName());
    },


    /**
     * Set title
     */
    setTitle: function(aTitle) {
        this.fTitle = aTitle;

        var titleElement = elem(this.fTitleElementID);
        if (titleElement)
            setHtml(titleElement, aTitle);
    },


    /**
     * Set content
     */
    setContent: function(aContent) {
        this.fContent = aContent;

        var contentElement = this.getContentElement();
        if (contentElement) {
            setHtml(contentElement, aContent);
            page.centerElement(contentElement);
        }
    },


    /**
     * Set url
     */
    setUrl: function(aUrl) {
        aUrl += (aUrl.indexOf("?") > 0 ? "&" : "?") + "____dialogID=" + this.getName();
        this.setContent("<iframe src='" + aUrl + "' frameborder='0' style='width:100%;height:100%'></iframe>");
        this.fIFrameContent = true;
    },


    /**
     * Set child event listener
     */
    setChildEventListener: function(aListener) {
        this.fChildEventListener = aListener;
    },


    /**
     * Fire child data event
     */
    fireChildDataEvent: function(data) {
        if (this.fChildEventListener) {
            this.fChildEventListener.call(this, data ? json_decode(data) : {});
        }
    },


    /**
     * Get content box id
     */
    getContentBoxId: function() {
        return this.fContentElementID;
    },


    /**
     * Get content element
     */
    getContentElement: function() {
        return elem(this.fContentElementID);
    },


    /**
     * Set content box dimension
     */
    setContentBoxDimension: function(aWidth, aHeight, aOverflow) {
        this.fContentBoxConstraints = {};
        this.fContentBoxConstraints['w'] = aWidth;
        this.fContentBoxConstraints['h'] = aHeight;

        if (aOverflow) {
            this.fContentBoxConstraints['overflow'] = aOverflow;
        }
        else {
            this.fContentBoxConstraints['overflow'] = "auto";
        }
    },


    /**
     * Set draggable mode
     */
    setDraggable: function(aDraggableMode) {
        this.fDraggableMode = aDraggableMode;
    },


    /**
     * Set resizable mode
     */
    setResizable: function(aResizableMode) {
        this.fResizableMode = aResizableMode;
    },


    /**
     * Show min button
     */
    showMinButton: function(flag) {
        this.fShowMinButton = flag;
    },


    /**
     * Show max buttons
     */
    showMaxButton: function(flag) {
        this.fShowMaxButton = flag;
    },


    /**
     * Show close button
     */
    showCloseButton: function(flag, aHandler) {
        this.fShowCloseButton = flag;
        if (flag == true && aHandler) {
            this.fCloseHandler = aHandler;
        }
    },


    /**
     * Show confirm on close
     */
    showConfirmOnClose: function(flag) {
        this.fShowConfirmOnClose = flag;
    },

    /**
     * Show title
     */
    showTitle: function(flag) {
        this.fShowTitle = flag;
    },


    /**
     * Go to
     */
    goTo: function(x, y) {
        setElementLocation(elem(this.getName()), x, y);
    },


    /**
     * Add button
     */
    addButton: function(aLabel, aHandler) {
        var id = page.createUID();
        this.fButtons.push({"id":id, "label":aLabel});
        this.fButtonClickHandlers[id] = aHandler;
        return id;
    },


    /**
     * Opens dialog
     */
    open: function() {
        if (elem(this.getName())) {
            return;
        }

        var dialogElement = document.createElement("div");
        dialogElement.style.visibility = "hidden";
        
        // set id
        dialogElement.id = this.getName();

        // set position
        dialogElement.style.position = "absolute";

        // set class name
        dialogElement.className = this.getClassName() ? this.getClassName() : "cssDialogInfo";

        // add element to document childs
        document.body.appendChild(dialogElement);

        setHtml(dialogElement, this.toHtml());

        if (this.fContentBoxConstraints) {
            dialogElement.style.width = this.fContentBoxConstraints['w'] + "px";
        }

        page.centerElement(dialogElement);
        var coordinates = getElementLocation(dialogElement);
        setElementLocation(dialogElement, coordinates.x + 8*page.availableDialogs, coordinates.y + 8*page.availableDialogs);

        dialogElement.style.visibility = "visible";
        page.bringElementToFront(dialogElement);

        var _self = this;

        if (this.fShowTitle && this.fShowMinButton && elem(this.fSystemButton1)) {
            elem(this.fSystemButton1).onclick = function() {_self.minimize()}
        }

        if (this.fShowTitle && this.fShowMaxButton && elem(this.fSystemButton2)) {
            elem(this.fSystemButton2).onclick = function() {_self.maximize()}
        }

        if (this.fShowTitle && this.fShowCloseButton && elem(this.fSystemButton3)) {
            elem(this.fSystemButton3).onclick = function() {
                if (_self.fCloseHandler) {
                    _self.fCloseHandler.call();
                }
                else {
                    _self.close();
                }
                return false;
            }
        }


        // assign onclick event handler(s) to button(s)
        for (var index in this.fButtons) {
             var btnAttr = this.fButtons[index];

             var btnElement = elem(btnAttr["id"]);
             if (btnElement) {
                 btnElement.onclick = function() {
                                            var clickHandler = _self.fButtonClickHandlers[this.id];
                                            if (clickHandler)
                                                clickHandler.call();
                                      }
             }
        }


        // bring to top
        if (page.agent.isIE()) {
            dialogElement.attachEvent("onmousedown", function() {
                _self.bringToFront();
            });
        }
        else {
            dialogElement.addEventListener("mousedown", function(event) {
                _self.bringToFront();
            }, false);
        }


        if (this.fDraggableMode && this.fShowTitle) {
            var targetElement = elem(this.fTitleElementID);

            if (page.agent.isIE()) {
                targetElement.attachEvent("onmousedown", function() {
                    var eXY = getElementLocation(dialogElement); var mXY = getMouseLocation();
                    _self.fDragObject = {'off_x':mXY.x-eXY.x,'off_y':mXY.y-eXY.y};
                    document.body.style.cursor = "move";
                });
                document.attachEvent("onmousemove", function() {
                    if (!_self.fDragObject) return; var mXY = getMouseLocation();
                    setElementLocation(dialogElement, mXY.x-_self.fDragObject.off_x, mXY.y-_self.fDragObject.off_y);
                });
                document.attachEvent("onmouseup", function() {
                    _self.fDragObject = null;
                    document.body.style.cursor = "default";
                });
            }
            else {
                targetElement.addEventListener("mousedown", function(event) {
                    var eXY = getElementLocation(dialogElement); var mXY = getMouseLocation(event);
                    _self.fDragObject = {'off_x':mXY.x-eXY.x,'off_y':mXY.y-eXY.y};
                    document.body.style.cursor = "move";
                }, false);
                document.addEventListener("mousemove", function(event) {
                    if (!_self.fDragObject) return; var mXY = getMouseLocation(event);
                    setElementLocation(dialogElement, mXY.x-_self.fDragObject.off_x, mXY.y-_self.fDragObject.off_y);
                }, false);
                document.addEventListener("mouseup", function() {
                    _self.fDragObject = null;
                    document.body.style.cursor = "default";
                }, false);
            }
        }

        if (this.fResizableMode) {
            var contentElement = elem(this.fContentElementID);

            if (page.agent.isIE()) {
                dialogElement.attachEvent("onmousedown", function() {
                    if (_self.inResizeBox) {
                        var eWH = getElementDimension(dialogElement);
                        var cWH = getElementDimension(contentElement);
                        var mXY = getMouseLocation(event);
                        _self.fResizeObject = {'dw':eWH.w,'ch':cWH.h,'mx':mXY.x,'my':mXY.y};
                    }
                });

                dialogElement.attachEvent("onmousemove", function() {
                    var mXY = getMouseLocation(event);
                    var eXY = getElementLocation(dialogElement);
                    var eWH = getElementDimension(dialogElement);
                    if (eXY.x + eWH.w - 10 < mXY.x && eXY.y + eWH.h - 10 < mXY.y) {
                        document.body.style.cursor = "nw-resize";
                        _self.inResizeBox = true;
                    }
                    else {
                        document.body.style.cursor = "default";
                        _self.inResizeBox = false;
                    }
                });

                document.attachEvent("onmousemove", function() {
                    if (!_self.fResizeObject) return; var mXY = getMouseLocation(event);
                    var dialogWidth = _self.fResizeObject.dw + mXY.x-_self.fResizeObject.mx;
                    var contentHeight = _self.fResizeObject.ch + mXY.y-_self.fResizeObject.my;

                    if (dialogWidth < 200 || contentHeight < 5) return;

                    dialogElement.style.width = dialogWidth + "px";
                    contentElement.style.height = contentHeight +"px";

                    if (_self.tmp['State'] == 'min' || _self.tmp['State'] == 'max') {
                        if (elem(this.fSystemButton1)) elem(_self.fSystemButton1).style.visibility = 'visible';
                        if (elem(this.fSystemButton2)) elem(_self.fSystemButton2).src = '/system/assets/images/dialog/max.gif';
                        _self.tmp['State'] = 'normal';
                    }
                });

                document.attachEvent("onmouseup", function() {
                    _self.fResizeObject = null;
                    document.body.style.cursor = "default";
                });
            }
            else {
                dialogElement.addEventListener("mousedown", function(event) {
                    if (_self.inResizeBox) {
                        var eWH = getElementDimension(dialogElement);
                        var cWH = getElementDimension(contentElement);
                        var paddTop_px = document.defaultView.getComputedStyle(contentElement, "").getPropertyValue("padding-top");
                        var paddBottom_px = document.defaultView.getComputedStyle(contentElement, "").getPropertyValue("padding-bottom");
                        var paddTop = (paddTop_px?parseInt(paddTop_px.replace(/px/g, '')):0);
                        var paddBottom = (paddBottom_px?parseInt(paddBottom_px.replace(/px/g, '')):0);
                        var offsetHeight = paddTop+paddBottom;

                        var mXY = getMouseLocation(event);
                        _self.fResizeObject = {'dw':eWH.w,'ch':cWH.h,'mx':mXY.x,'my':mXY.y,'offsetHeight':offsetHeight};
                    }
                }, false);

                dialogElement.addEventListener("mousemove", function(event) {
                    var mXY = getMouseLocation(event);
                    var eXY = getElementLocation(dialogElement);
                    var eWH = getElementDimension(dialogElement);
                    if (eXY.x + eWH.w - 10 < mXY.x && eXY.y + eWH.h - 10 < mXY.y) {
                        document.body.style.cursor = "nw-resize";
                        _self.inResizeBox = true;
                    }
                    else {
                        document.body.style.cursor = "default";
                        _self.inResizeBox = false;
                    }
                }, false);

                document.addEventListener("mousemove", function(event) {
                    if (!_self.fResizeObject) return; var mXY = getMouseLocation(event);
                    var dialogWidth = _self.fResizeObject.dw + mXY.x-_self.fResizeObject.mx;
                    var contentHeight = _self.fResizeObject.ch + mXY.y-_self.fResizeObject.my;

                    if (dialogWidth < 200 || contentHeight < 5) return;

                    dialogElement.style.width = dialogWidth + "px";
                    contentElement.style.height = contentHeight - _self.fResizeObject.offsetHeight + "px";

                    if (_self.tmp['State'] == 'min' || _self.tmp['State'] == 'max') {
                        if (elem(this.fSystemButton1)) elem(_self.fSystemButton1).style.visibility = 'visible';
                        if (elem(this.fSystemButton2)) elem(_self.fSystemButton2).src = '/system/assets/images/dialog/max.gif';
                        _self.tmp['State'] = 'normal';
                    }
                }, false);

                document.addEventListener("mouseup", function() {
                    _self.fResizeObject = null;
                    document.body.style.cursor = "default";
                }, false);
            }
        }

        if (this.fIFrameContent) {
            this.getContentElement().style.padding = "0 0 0 0";
            page.registerWidget(this.getName(), this);
        }

        this.fModalDialog = false;
        page.availableDialogs = page.availableDialogs+1;
    },


    /**
     * Opens modal dialog
     */
    openModal: function() {
        if (elem(this.getName())) {
            return;
        }

        page.cover(this.fModalCoverId);
        page.bringElementToFront(elem(this.fModalCoverId));

        this.open();
        this.fModalDialog = true;        
    },


    /**
     * Opens url dialog
     */
    openURL: function(width, height, title, url, childListener) {
        this.setContentBoxDimension(width, height, 'hidden');
        this.setTitle(title);
        this.showTitle(title ? true : false);
        this.showMinButton(false);
        this.showMaxButton(false);
        var _self = this;
        this.showCloseButton(true, function() {
            if (_self.fShowConfirmOnClose) {
                page.showConfirm(page.i18n("SYS_MSG_ARE_YOU_SURE"), function() {_self.close();}, function() {});
            }
            else {
                _self.close();
            }
        });
        this.setUrl(url);
        this.setDraggable(true);
        this.setResizable(false);
        this.openModal();

        if (childListener) {
            this.setChildEventListener(childListener);
        }
    },


    /**
     * Checks to see if it is opened
     */
    isOpen: function() {
        if (elem(this.getName())) {
            return true;
        }

        return false;
    },


    /**
     * Closes this dialog
     */
    close: function() {
        if (this.fIFrameContent) {
            page.destroyWidget(this.getName());
        }

        if (elem(this.getName())) {
            document.body.removeChild(e(this.getName()));
            if (this.fModalDialog) {
                page.uncover(this.fModalCoverId);
            }
        }

        page.availableDialogs = page.availableDialogs-1;
    },


    /**
     * Hides this dialog
     */
    show: function() {
        if (e(this.getName())) {
            e(this.getName()).style.visibility = 'visible';

            if (this.fModalDialog && e(this.fModalCoverId)) {
                e(this.fModalCoverId).style.visibility = 'visible';
                page.bringElementToFront(e(this.fModalCoverId));
            }

            page.bringElementToFront(e(this.getName()));
        }
    },


    /**
     * Hides this dialog
     */
    hide: function() {
        if (this.fModalDialog && e(this.fModalCoverId)) {
            e(this.fModalCoverId).style.visibility = 'hidden';
        }

        if (e(this.getName())) {
            e(this.getName()).style.visibility = 'hidden';
        }
    },


    /**
     * Bring to front
     */
    bringToFront: function() {
        var dialogElement = elem(this.getName());
        page.bringElementToFront(dialogElement);
    },


    /**
     * Minimize
     */
    minimize: function() {
        var dialogElement = this.getDialogElement();
        var contentElement = this.getContentElement();

        if (this.tmp['State'] == 'min') {
            return;
        }
        else {
            if (this.tmp['State'] == 'max') {
            }
            if (this.tmp['State'] == 'normal') {
                var dXY = getElementLocation(dialogElement);
                var dWH = getElementDimension(dialogElement);
                var cWH = getElementDimension(contentElement);
                this.tmp['x'] = dXY.x; this.tmp['y'] = dXY.y; this.tmp['w'] = dWH.w; this.tmp['h'] = cWH.h;
            }
            this.tmp['State'] = 'min';
            if (elem(this.fSystemButton1)) elem(this.fSystemButton1).style.visibility = 'hidden';
            if (elem(this.fSystemButton2)) elem(this.fSystemButton2).src = '/system/assets/images/dialog/restore.gif';
            //contentElement.style.height = "1px";
            contentElement.style.display = "none";
        }
    },


    /**
     * Maximize
     */
    maximize: function() {
        var dialogElement = this.getDialogElement();
        var contentElement = this.getContentElement();

        if (this.tmp['State'] == 'normal') {
            var dXY = getElementLocation(dialogElement);
            var dWH = getElementDimension(dialogElement);
            var cWH = getElementDimension(contentElement);
            this.tmp['x'] = dXY.x; this.tmp['y'] = dXY.y; this.tmp['w'] = dWH.w; this.tmp['h'] = cWH.h;
            this.tmp['State'] = 'max';
            if (elem(this.fSystemButton2)) elem(this.fSystemButton2).src = '/system/assets/images/dialog/restore.gif';
            dialogElement.style.width = page.windowWidth()-16 + "px";
            contentElement.style.height = page.windowHeight()-50 + "px";
            dialogElement.style.left = "8px";
            dialogElement.style.top = "5px";
        }
        else if (this.tmp['State'] == 'min' || this.tmp['State'] == 'max') {
            this.restore();
        }
    },


    /**
     * Restore
     */
    restore: function() {
        var dialogElement = this.getDialogElement();
        var contentElement = this.getContentElement();
        if (this.tmp['State'] == 'min' || this.tmp['State'] == 'max') {
            this.tmp['State'] = 'normal';
            contentElement.style.display = "block";
            dialogElement.style.width = this.tmp['w'] + "px";
            contentElement.style.height = this.tmp['h'] + "px";
            if (elem(this.fSystemButton1)) elem(this.fSystemButton1).style.visibility = 'visible';
            if (elem(this.fSystemButton2)) elem(this.fSystemButton2).src = '/system/assets/images/dialog/max.gif';
            setElementLocation(dialogElement, this.tmp['x'], this.tmp['y']);
        }
    },


    /**
     * To html
     */
    toHtml: function() {
        var html = "";
        html += "<table border='0' cellspacing='1' style='width:100%;'>";

        var systemButtons = "";
        var tdWidth = "1px;";
        if (this.fShowMinButton) {
            systemButtons += "<a id='" + this.fSystemButton1 + "Click' href='#' style='outline-style:none;'><img id='" + this.fSystemButton1 + "' src='/system/assets/images/dialog/min.gif' border='0' hspace='3' /></a>";
        }

        if (this.fShowMaxButton) {
            systemButtons += "<a id='" + this.fSystemButton2 + "Click' href='#' style='outline-style:none;'><img id='" + this.fSystemButton2 + "' src='/system/assets/images/dialog/max.gif' border='0' hspace='3' /></a>";
        }

        if (this.fShowCloseButton) {
            systemButtons += "<a id='" + this.fSystemButton3 + "Click' href='#' style='outline-style:none;'><img id='" + this.fSystemButton3 + "'src='/system/assets/images/dialog/close.gif' border='0' hspace='3' /></a>";
        }

        if (systemButtons != "") {
            tdWidth = "70px;";
        }

        if (this.fShowTitle) {
            var insideTable = "<table border='0' cellspacing='0' style='width:100%;height:100%;'><tr><td style='width:" + tdWidth + ";text-align:left;'></td><td id='" + this.fTitleElementID + "' class='header_inside'>" + this.fTitle + "</td><td style='width:" + tdWidth + ";text-align:right;vertical-align:middle;white-space:nowrap;'>" + systemButtons + "</td></tr></table>";
            html += "<tr><td class='header_outside'>" + insideTable + "</td></tr>";
        }

        var contentStyle = "";
        if (this.fContentBoxConstraints) {
            contentStyle = "height:" + this.fContentBoxConstraints['h'] + "px;overflow:" + this.fContentBoxConstraints['overflow'];
        }
        html += "<tr><td><div id='" + this.fContentElementID + "' class='content' style='" + contentStyle + "'>" + this.fContent + "</div></td></tr>";

        if (this.fButtons.length > 0) {
            html += "<tr><td style='text-align:center'>";
            for (var index in this.fButtons) {
                 var btnAttr = this.fButtons[index];
                 html += "<input id='" + btnAttr['id'] + "' type='button' value=\"" + btnAttr['label'] + "\" class='button' />&nbsp;";
            }
            html = html.substr(0, html.length-6);
            html += "</td></tr>";
        }

        html += "</table>";

        return html;
    },


    /**
     * Destroy
     */
    destroy: function() {
    },


    /**
     * Get value
     */
    getValue: function() {
        return null;
    }
});





/************************************************************************************
 * THttpAjaxData definition
 ************************************************************************************/

var THttpAjaxData = TClass.extend({}, {

    /**
     * Constructor
     */
    initialize: function() {
        this.clear();
    },


    /**
     * Add parameter
     */
    addParameter: function(key, value) {
        this.parameters[key] = value;
    },


    /**
     * Add parameter
     */
    addParam: function(key, value) {
        this.parameters[key] = value;
    },


    /**
     * Get parameter
     */
    getParameter: function(key, defaultValue) {
        var temp = this.parameters[key];

        if (!temp && defaultValue)
            temp = defaultValue;

        return temp;
    },


    /**
     * Get parameter
     */
    getParam: function(key, defaultValue) {
        return this.getParameter(key, defaultValue);
    },


    /**
     * Get parameter
     */
    get: function(key, defaultValue) {
        return this.getParameter(key, defaultValue);
    },


    /**
     * Remove parameter
     */
    removeParameter: function(key) {
        if (this.parameters[key] != null) {
            delete this.parameters[key];
        }
    },


    /**
     * Get parameters
     */
    getParameters: function() {
        var temp = {};

        for (i in this.parameters) {
            temp[i] = this.parameters[i];
        }

        return temp;
    },


    /**
     * Add script file
     */
    addScriptFile: function(scriptFile, id) {
        this.scriptFiles.push(scriptFile);
        if (id) this.tmp[scriptFile] = id;
    },


    /**
     * Add script content
     */
    addScriptContent: function(scriptContent) {
        this.scriptContents.push(scriptContent);
    },


    /**
     * Add css file
     */
    addCssFile: function(cssFile, id) {
        this.cssFiles.push(cssFile);
        if (id) this.tmp[cssFile] = id;
    },


    /**
     * Add script code for execution
     */
    addExecutionScriptCode: function(scriptCode) {
        this.executionScriptCodes.push(scriptCode);
    },


    /**
     * Execute
     */
    execute: function() {
        for (i in this.cssFiles) page.addCssFile(this.cssFiles[i], this.tmp[this.cssFiles[i]]);
        for (i in this.scriptFiles) page.addScriptFile(this.scriptFiles[i], this.tmp[this.scriptFiles[i]]);
        for (i in this.scriptContents) page.addScriptContent(this.scriptContents[i]);
        for (i in this.executionScriptCodes) page.safeExec(this.executionScriptCodes[i]);
        this.clearExecutableData();
    },


    /**
     * Clear
     */
    clearExecutableData: function() {
        this.scriptFiles = Array();
        this.scriptContents = Array();
        this.executionScriptCodes = Array();
        this.cssFiles = Array();
        this.tmp = {};
    },


    /**
     * Clear
     */
    clear: function() {
        this.parameters = {};
        this.clearExecutableData();
    },


    /**
     * Debug
     */
    debug: function() {
        var str = "Object (\n";

        for (i in this.parameters) str += "\t" + i + "=" + this.parameters[i] + "\n";

        str += ")";

        if (this.Text) str = this.Text + "\n\n" + str;

        print_r(str);
    }

});





/************************************************************************************
 * THttpAjax definition
 ************************************************************************************/

var THttpAjax = TClass.extend({}, {

    /**
     * Constructor
     */
    initialize: function() {
        this.fHttpRequest = false;
        this.fInitialized = false;
        this.fCallbacks = new Object();
        this.fRequestInProgress = false;
        this.fRequestQueue = new Array();
        this.TargetUri = page.submitUri;
        this.TargetMethod = 'post';
        this.fRequestedAjaxControls = new Array();
        this.debugMode = false;
        this.fUidNumber = 73641;

        if (typeof XMLHttpRequest == "undefined") {
            try {
                this.fHttpRequest = new ActiveXObject("Msxml2.XMLHTTP.6.0");
            } catch(e) {
                try {
                    this.fHttpRequest = new ActiveXObject("Msxml2.XMLHTTP.3.0");
                } catch(e) {
                    try {
                        this.fHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
                    } catch(e) {
                        try {
                            this.fHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
                        } catch(e) {
                        }
                    }
                }
            }
        }
        else {
            this.fHttpRequest = new XMLHttpRequest();
        }


        if (this.fHttpRequest) {
            this.fInitialized = true;
        }
        else {
            alert("Ajax can't be instantiated");
        }
    },


    /**
     * Do http get
     */
    doHttpGet: function(text) {
        this.fRequestInProgress = true;

        this.fHttpRequest.open("GET", this.TargetUri + "?" + text, true);

        var self = this;
        this.fHttpRequest.onreadystatechange = function() {
            if (self.fHttpRequest.readyState == 4 && self.fHttpRequest.status == 200) {
                self.processResponse(self.fHttpRequest.responseText);
                self.fRequestInProgress = false;
                self.processPendingRequests();
            }
        }

        this.fHttpRequest.send(null);
    },


    /**
     * Do http post
     */
    doHttpPost: function(text) {
        this.fRequestInProgress = true;

        var url = this.TargetUri + "?" + (this.fUidNumber++);

        this.fHttpRequest.open("POST", url, true);
        this.fHttpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        this.fHttpRequest.setRequestHeader("Content-length", text.length);
        this.fHttpRequest.setRequestHeader("Connection", "close");
        
        var self = this;
        this.fHttpRequest.onreadystatechange = function() {
            if (self.fHttpRequest.readyState == 4 && self.fHttpRequest.status == 200) {
                self.processResponse(self.fHttpRequest.responseText);
                self.fRequestInProgress = false;
                self.processPendingRequests();
            }
        }

        this.fHttpRequest.send(text);
    },


    /**
     * Free
     */
    free: function() {
        this.fHttpRequest = null;
    },


    /**
     * Make request
     */
    request: function(data, aHandler, method) {
        if (!data) {
            data = new Object();
        }

        data["_submit_type"] = "ajax";
        if (data["_submit_handler"] == null) {
            data["_submit_handler"] = "OnAjaxRequest";
        }

        var statefulProps = page.model.getStatefulPropertyList();
        for (var propertyKey in statefulProps) {
            var propertyValue = statefulProps[propertyKey];
            if (propertyValue && (typeof propertyValue == "string" || typeof propertyValue == "number")) {
                data["___model_" + propertyKey] = propertyValue;
            }
        }

        if (aHandler) {
            var trackID = page.createUID();
            data["_data_trackID"] = trackID;
            this.fCallbacks[trackID] = aHandler;
        }

        if (method && method.toLowerCase() == 'get') {
            this.TargetMethod = 'get';
        }

        this.fRequestQueue.push(httpBuildQuery(data, {'target':'ajax'}));
        this.processPendingRequests();

        this.TargetMethod = 'post';
    },


    /**
     * Make url request
     */
    makeURLRequest: function(url, data, aHandler, method) {
        var tmp = this.TargetUri;
        this.TargetUri = url;
        this.request(data, aHandler, method);
        this.TargetUri = tmp;
    },


    /**
     * Call server method
     */
    call: function(actionName, data, aHandler, method) {
        if (!data) data = new Object();
        data["_submit_handler"] = actionName;
        this.request(data, aHandler, method);
    },


    /**
     * Post back
     */
    postback: function(actionName, actionParams) {
        page.submitAction("ajax", "hsdgfhsfgE2Sdfd1", actionName, actionParams);
    },


    /**
     * Process pending requests
     */
    processPendingRequests: function() {
        if (!this.fRequestInProgress) {
            if (this.fRequestQueue.length > 0) {
                if (this.TargetMethod == 'post') {
                    this.doHttpPost(this.fRequestQueue.shift());
                }
                else {
                    this.doHttpGet(this.fRequestQueue.shift());
                }
            }
        }
    },


    /**
     * Process response
     */
    processResponse: function(text) {
        if (page.devMode) {
            if (text != null && text.length > 0 && text.charAt(0) != "{") {
                print_r(text);
            }
        }

        if (this.debugMode) {
            print_r(text);
        }

        var result = new THttpAjaxData();
        var temp = json_decode(text);

        var trackID;

        for (var key in temp) {
             if (key.indexOf("setcookie:;:") == 0) {
                 var rawstr = key; rawstr = rawstr.replace("setcookie:;:", "");
                 var name = rawstr.substr(0,rawstr.indexOf(":;:"));
                 var expires = rawstr.substr(rawstr.indexOf(":;:")+3);
                 if (expires == -1 && temp[key] == "removeme") {
                     page.removeCookie(name);
                 }
                 else {
                     page.setCookie(name,temp[key],expires);
                 }
             }
             else if (key.indexOf("___model_property:;:") == 0) {
                 var tmp = key.replace("___model_property:;:", "");
                 if (tmp.indexOf("true:") == 0) {
                     var propertyName = tmp.replace("true:", "");
                     page.model.setProperty(propertyName, temp[key], true);
                 }
                 else if (tmp.indexOf("false:") == 0) {
                     var propertyName = tmp.replace("false:", "");
                     page.model.setProperty(propertyName, temp[key], false);
                 }
             }
             else if (key.indexOf("___set_element_value:;:") == 0) {
                 var id = key.replace("___set_element_value:;:", "");
                 setElementValue(id, temp[key]);
             }
             else if (key.indexOf("___addscript:;:") == 0) {
                 var rawstr = key; rawstr = rawstr.replace("___addscript:;:", "");
                 var tmp = rawstr.split(':;:'); var id = (tmp.length == 2 && tmp[1] ? tmp[1] : null);
                 result.addScriptFile(temp[key], id);
             }
             else if (key.indexOf("___addscript_c") == 0) {
                 result.addScriptContent(temp[key]);
             }
             else if (key.indexOf("___addcss:;:") == 0) {
                 var rawstr = key; rawstr = rawstr.replace("___addcss:;:", "");
                 var tmp = rawstr.split(':;:'); var id = (tmp.length == 2 && tmp[1] ? tmp[1] : null);
                 result.addCssFile(temp[key], id);
             }
             else if (key.indexOf("___safe_exec") == 0) {
                 result.addExecutionScriptCode(temp[key]);
             }
             else if (key.indexOf("_data_trackID") == 0) {
                 trackID = temp[key];
             }
             else {
                 result.addParameter(key, temp[key]);
             }
        }

        result.execute();

        if (trackID && this.fCallbacks[trackID]) {
            this.fCallbacks[trackID].call(this, result);
            delete this.fCallbacks[trackID];
        }
    },


    /**
     * Request ajax control
     */
    requestControl: function(target, instName, widget, phpClass, args) {
        var req = {};
        req["rc_target"] = target;
        req["rc_name"] = instName;
        req["rc_widget"] = widget;
        req["rc_phpclass"] = phpClass;
        req["rc_args"] = args ? args : {};
        this.fRequestedAjaxControls.push(req);
    },


    /**
     * Bind requested ajax controls
     */
    bindRequestedControls: function() {
        if (this.fRequestedAjaxControls.length == 0) {
            return;
        }

        var tmpList = new Array();
        for (var i=0; i<this.fRequestedAjaxControls.length; i++) {
            tmpList.push(this.fRequestedAjaxControls[i]);
        }
        this.fRequestedAjaxControls = new Array();

        var command = {};
        command["___data_editor_cmd"] = "____create_widgets";
        command["controls"] = json_encode(tmpList);
        page.ajax.request(command);
    }

});

/**
 * TDataEditor
 */
var TDataEditor = TClass.extend(TDialog, {

    /**
     * Constructor
     */
    initialize: function() {
        $C(TDialog).initialize.call(this);

        this.setDraggable(true);
        this.setResizable(true);

        this.fControls = new Array();
        this.fControlNames = new Array();
        this.fServerControlNames = new Array();

        this.formName = "frm" + Math.floor(Math.random()*10000);

        this.setClassName("cssDataEditor");
        this.fDimension = null;
        this.fEditable = true;
    },


    /**
     * Set editable
     */
    setEditable: function(aValue) {
        this.fEditable = aValue;
    },


    /**
     * Add label control
     */
    addLabel: function(text, controlName, controlValue) {
        this.fControls.push({"type":"Label", "text":text, "name":controlName, "value":controlValue});
    },


    /**
     * Add hidden field control
     */
    addHiddenField: function(controlName, controlValue) {
        this.fControlNames.push(controlName);
        this.fControls.push({"type":"HiddenField", "name":controlName, "value":controlValue});
    },


    /**
     * Add text field control
     */
    addTextField: function(text, controlName, controlValue) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlValue);
        }
        this.fControlNames.push(controlName);
        this.fControls.push({"type":"TextField", "text":text, "name":controlName, "value":controlValue});
    },


    /**
     * Add password field control
     */
    addPasswordField: function(text, controlName, controlValue) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlValue);
        }
        this.fControlNames.push(controlName);
        this.fControls.push({"type":"Password", "text":text, "name":controlName, "value":controlValue});
    },


    /**
     * Add text area control
     */
    addTextArea: function(text, controlName, controlValue) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlValue);
        }
        this.fControlNames.push(controlName);
        this.fControls.push({"type":"TextArea", "text":text, "name":controlName, "value":controlValue});
    },


    /**
     * Add check box control
     */
    addCheckBox: function(text, controlName, controlValue) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlValue);
        }
        this.fControlNames.push(controlName);
        this.fControls.push({"type":"CheckBox", "text":text, "name":controlName, "value":controlValue});
    },


    /**
     * Add drop down control
     */
    addDropDown: function(text, controlName, controlOptions, controlValue) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlOptions[controlValue]);
        }
        this.fControlNames.push(controlName);
        this.fControls.push({"type":"DropDown", "text":text, "name":controlName, "options":controlOptions, "value":controlValue});
    },


    /**
     * Add list box control
     */
    addListBox: function(text, controlName, controlOptions, controlValue) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlOptions[controlValue]);
        }
        this.fControlNames.push(controlName);
        this.fControls.push({"type":"ListBox", "text":text, "name":controlName, "options":controlOptions, "value":controlValue});
    },


    /**
     * Add date drop down control
     */
    addDateDropDown: function(text, controlName, controlValue, args) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlValue);
        }

        this.addHTML(text, controlName, "<div id='" + controlName + "WidgetEditorBox'><img src='/system/assets/images/loading.gif'/></div>\n");
        if (controlValue) {
            if (!args) args = {};
            args["value"] = controlValue;
        }
        this.fServerControlNames.push(controlName);
        page.ajax.requestControl(controlName+"WidgetEditorBox", controlName, "date_and_time", "TDatePicker", args);
    },


    /**
     * Add time drop down control
     */
    addTimeDropDown: function(text, controlName, controlValue, args) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlValue);
        }

        this.addHTML(text, controlName, "<div id='" + controlName + "WidgetEditorBox'><img src='/system/assets/images/loading.gif'/></div>\n");
        if (controlValue) {
            if (!args) args = {};
            args["value"] = controlValue;
        }
        this.fServerControlNames.push(controlName);
        page.ajax.requestControl(controlName+"WidgetEditorBox", controlName, "date_and_time", "TTimePicker", args);
    },


    /**
     * Add date field
     */
    addDateField: function(text, controlName, controlValue, args) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlValue);
        }

        this.addHTML(text, controlName, "<div id='" + controlName + "WidgetEditorBox'><img src='/system/assets/images/loading.gif'/></div>\n");
        if (controlValue) {
            if (!args) args = {};
            args["value"] = controlValue;
        }

        this.fServerControlNames.push(controlName);
        page.ajax.requestControl(controlName+"WidgetEditorBox", controlName, "date_and_time", "TDateField", args);
    },


    /**
     * Add time field
     */
    addTimeField: function(text, controlName, controlValue, args) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlValue);
        }

        this.addHTML(text, controlName, "<div id='" + controlName + "WidgetEditorBox'><img src='/system/assets/images/loading.gif'/></div>\n");
        if (controlValue) {
            if (!args) {
                args = {};
            }
            args["value"] = controlValue;
        }
        this.fServerControlNames.push(controlName);
        page.ajax.requestControl(controlName+"WidgetEditorBox", controlName, "date_and_time", "TTimeField", args);
    },


    /**
     * Add date time field
     */
    addDateTimeField: function(text, controlName, controlValue, args) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlValue);
        }

        this.addHTML(text, controlName, "<div id='" + controlName + "WidgetEditorBox'><img src='/system/assets/images/loading.gif'/></div>\n");
        if (controlValue) {
            if (!args) args = {};
            args["value"] = controlValue;
        }

        this.fServerControlNames.push(controlName);
        page.ajax.requestControl(controlName+"WidgetEditorBox", controlName, "date_and_time", "TDateTimeField", args);
    },


    /**
     * Add html editor
     */
    addHtmlEditor: function(text, controlName, controlValue, args) {
        if (!this.fEditable) {
            return this.addLabel(text, controlName, controlValue);
        }

        this.addHTML(text, controlName, "<div id='" + controlName + "WidgetEditorBox' style='height:200px'><img src='/system/assets/images/loading.gif'/></div>\n");
        if (controlValue) {
            if (!args) {
                args = {};
            }
            args["value"] = controlValue;
        }
        this.fServerControlNames.push(controlName);
        page.ajax.requestControl(controlName + "WidgetEditorBox", controlName, "html_editor", "THTMLEditor", args);
    },


    /**
     * Add html
     */
    addHTML: function(text, controlName, controlValue) {
        this.fControlNames.push(controlName);
        this.fControls.push({"type":"HTML", "text":text, "name":controlName, "value":controlValue});
    },


    /**
     * Build select tag
     */
    buildSelectTag: function(controlName, type, options, value) {
        var styleString = "";
        var multipleString = "";
        if (type == "lb") {
            styleString += "height:100px;";
            multipleString = "multiple=\"multiple\"";
        }

        htmlControl = "<select id='" + controlName + "' name='" + controlName + "' class='select' style='" + styleString + "' " + multipleString + " />";
        for (var i in options) {
            if (value && i==value) {
                htmlControl += "<option value='" + i + "' selected>" + options[i] + "</option>";
            }
            else {
                htmlControl += "<option value='" + i + "'>" + options[i] + "</option>";
            }
        }
        htmlControl += "</select>";

        return htmlControl;
    },


    /**
     * Add button
     */
    addButton: function(aLabel, aHandler, aDependOnEditable) {
        if (aDependOnEditable && aDependOnEditable == true && !this.fEditable) {
            return;
        }
        return $C(TDialog).addButton.call(this, aLabel, aHandler);
    },


    /**
     * Set dimension
     */
    setDimension: function(aWidth, aHeight, aOverflow) {
        this.setContentBoxDimension(aWidth, aHeight, aOverflow);
    },


    /**
     * Opens dialog
     */
    open: function() {
        
        var html = "";

        for (i in this.fControls) {
             var ctrl = this.fControls[i];
             var idControl = ctrl.name;
             var htmlControl;
             var ext = true;
             if (ctrl.type == "TextField") {
                 htmlControl = "<input id='" + idControl + "' name='" + idControl + "' type='text' value='" + (ctrl.value?safequot(ctrl.value):"") + "' class='text' />\n";
             }
             else if (ctrl.type == "Password") {
                 htmlControl = "<input id='" + idControl + "' name='" + idControl + "' type='password' value='" + (ctrl.value?safequot(ctrl.value):"") + "' class='text' />\n";
             }
             else if (ctrl.type == "TextArea") {
                 htmlControl = "<textarea id='" + idControl + "' name='" + idControl + "' class='textarea'>" + (ctrl.value?ctrl.value:"") + "</textarea>\n";
             }
             else if (ctrl.type == "CheckBox") {
                 var checked = false;
                 if (ctrl.value&&(ctrl.value=="t"||ctrl.value=="true"||ctrl.value=="on"||ctrl.value==true)) {
                     checked = true;
                 }
                 htmlControl = "<input id='" + idControl + "' name='" + idControl + "' type='checkbox' " + (checked?"checked":"") + " class='checkbox' />\n";
             }
             else if (ctrl.type == "HiddenField") {
                 ext = false;
                 htmlControl = "<input id='" + idControl + "' name='" + idControl + "' type='hidden' value='" + (ctrl.value?safequot(ctrl.value):"") + "' />\n";
             }
             else if (ctrl.type == "Label") {
                 htmlControl = "<span id='" + idControl + "' class='labelValue'>" + (ctrl.value?ctrl.value:"") + "</span>";
             }
             else if (ctrl.type == "DropDown") {
                 htmlControl = this.buildSelectTag(idControl, "dd", ctrl.options, ctrl.value);
             }
             else if (ctrl.type == "ListBox") {
                 htmlControl = this.buildSelectTag(idControl, "lb", ctrl.options, ctrl.value);
             }
             else if (ctrl.type == "HTML") {
                 htmlControl = ctrl.value + "\n";
             }
             else {
                 htmlControl = "";
             }

             if (ext) {
                 if (idControl && ctrl.text) {
                     html += "<div id='" + idControl + ".label' class='labelCaption'>" + ctrl.text + "</div>";
                 }
                 html += htmlControl + "<br /><br />\n";
             }
             else {
                 html += htmlControl;
             }
        }

        this.setContent(html);
        $C(TDialog).open.call(this);

        page.ajax.bindRequestedControls();
    },


    /**
     * Set control properties
     */
    setWidgetProperties: function(aName, aArgs) {
        var control = document.getElementById(aName + "WidgetEditorBox");
        if (!control) control = document.getElementById(aName);
        if (!control) return;
        if (!aArgs) return;

        control.style.position = "absolute";
        if (aArgs.length >= 5) control.style.textAlign = aArgs[4];
        if (aArgs.length >= 4) control.style.height = aArgs[3] + "px";
        if (aArgs.length >= 3) control.style.width = aArgs[2] + "px";
        if (aArgs.length >= 2) control.style.top = aArgs[1] + "px";
        if (aArgs.length >= 1) control.style.left = aArgs[0] + "px";
    },


    /**
     * Get data
     */
    getData: function() {
        var tmp = new Object();
        for (var i in this.fControlNames) {
            var name = this.fControlNames[i];
            var value = getElementValue(name);

            if (value != null) {
                tmp[name] = value;
            }
        }

        for (i in this.fServerControlNames) {
            var name = this.fServerControlNames[i];
            if (page.widget(name) && page.widget(name).getValue) {
                tmp[name] = page.widget(name).getValue();
            }
        }

        return tmp;
    },


    /**
     * Close
     */
    close: function() {
        for (var i in this.fServerControlNames) {
            page.destroyWidget(this.fServerControlNames[i]);
        }

        $C(TDialog).close.call(this);
    }
});