﻿/** 
 * @fileoverview CS Javascript Framework Core
 * 
 * CS Javascript Framework Core
 * This core javascript library is developed for general use
 * All the functions here should be as generic as possible
 * 
 * Versioning Convention
 * ---------------------
 * v.[major].[minor]
 * Major : Change in signature
 * Minor : Bug fixes and feature enhancement
 * 
 * TODO
 * ----
 * Add code to check if the script had been included before
 * StringFormat function can be consider to incorporate into String Prototype
 * 
 * @author Chen Choong Seng choongseng@gmail.com
 * @version 1.0
 */

/**
 * CS Framework by Chen Choong Seng
 * Version 1.0 (2008-05-09): Addin Javascript Documentation
 */
var cs = {
    version: 1.0,
    
    Debug: {
        
        /*************************
            DEBUGGING FUNCTIONS
        **************************/
        _messageArray: new Array(),
        addTrace: function(strCategory, strMessage)
        {
            cs.Debug._messageArray.push([strCategory, strMessage]);
        },
        alertTrace: function()
        {
            var myWindow = window.open("", "_blank", 'scrollbars=yes,resizable=yes,width=600,height=600');
            for (var intMsg=0; intMsg < cs.Debug._messageArray.length; intMsg++)
            {
                if (cs.Debug._messageArray[intMsg][0]=="ERR")
                {
                    myWindow.document.write("<span style=\"color:red\">");
                    myWindow.document.write(cs.Debug._messageArray[intMsg].join(" , "));
                    myWindow.document.write("</span>");
                }
                else
                    myWindow.document.write(cs.Debug._messageArray[intMsg].join(" , "));
                myWindow.document.write("<br/>");
            }
            myWindow.document.bgColor="lightblue";
            myWindow.document.close();
        },
        clearTrace: function()
        {
            cs.Debug._messageArray.length=0;
        },
        
        /*
        Name        : showString
        Description : Show the debug message in div or popup
        Revision    : 2007-11-20 v1.0 First Release
        */
        showString: function(strObj, divName)
        {
            if (divName==undefined)
                cs.debugalert(strObj);
            else
                document.getElementById(divName).innerHTML = strObj;
        },

        /*
        Name        : show
        Description : A general function to report error during debugging session
        Revision    : 2007-11-20 v1.0 First Release
        */
        show: function(eObj, divName)
        {
            // Check if it is a String
            if (typeof(eObj)==String)
                this.showString(eObj, divName);
            else
            {
                this.showString(eObj.message, divName);
            }
        },
        
        helper_TR: function(strLabel, strValue)
        {
            var eleTR = document.createElement("TR");
            
            var eleTDLabel = document.createElement("TD");
            eleTDLabel.style.verticalAlign="top";
            eleTR.appendChild(eleTDLabel);
            eleTDLabel.appendChild(document.createTextNode(strLabel));
            
            var eleTDValue = document.createElement("TD");
            eleTDValue.style.verticalAlign="top";
            eleTR.appendChild(eleTDValue);
            
            if (strValue.constructor==String||strValue.constructor==Number||strValue.constructor==Function)
            {
                eleTDValue.appendChild(document.createTextNode(strValue));
            }
            else
            {
                // TODO: need to check its type
                eleTDValue.appendChild(strValue);
            }
            
            return eleTR;
        },
        
        inspectToHTML: function(eObj, opts)
        {
            var options = {};

            if (options!=undefined)
            {
                // Check if the iteration had done deep enough.
                if (options.depth!=undefined)
                {
                    if (options.depth<=0)
                    {
                        // do nothing first
                    }
                    else
                        options.depth-=1;
                }
            }
            
            var eleTABLE = document.createElement("TABLE");
            var eleTBODY = document.createElement("TBODY");
            eleTABLE.appendChild(eleTBODY);
            
            // Try to figure out what is the object and show its values
            if (eObj==undefined)
            {
                eleTBODY.appendChild(cs.Debug.helper_TR("Type","undefined"));
            }
            else if (eObj.constructor==String)
            {
                eleTBODY.appendChild(cs.Debug.helper_TR("String", eObj));
            }
            else if (eObj.constructor==Number)
            {
                eleTBODY.appendChild(cs.Debug.helper_TR("Number", eObj));
            }
            else if (eObj.constructor==Function)
            {
                eleTBODY.appendChild(cs.Debug.helper_TR("Function", eObj));
            }
            else if (eObj.constructor==Array)
            {
                var eleChildTABLE = document.createElement("TABLE");
                var eleChildTBODY = document.createElement("TBODY");
                eleChildTABLE.appendChild(eleChildTBODY);

                var intArrayCount=eObj.length;
                for (var i=0; i<eObj.length; i++)
                {
                    eleChildTBODY.appendChild(cs.Debug.helper_TR("Child " + i, cs.Debug.inspectToHTML(eObj[i], options)));
                }
                
                eleTBODY.appendChild(cs.Debug.helper_TR("Array", eleChildTABLE));
                
            }
            else if (eObj.constructor==Object)
            {
                var eleChildTABLE = document.createElement("TABLE");
                var eleChildTBODY = document.createElement("TBODY");
                eleChildTABLE.appendChild(eleChildTBODY);

                for (eleObj in eObj)
                {
                    eleChildTBODY.appendChild(cs.Debug.helper_TR(eleObj, cs.Debug.inspectToHTML(eObj[eleObj], options)));
                }
                
                eleTBODY.appendChild(cs.Debug.helper_TR("Object", eleChildTABLE));
                
            }
            else
            {

                var eleChildTABLE = document.createElement("TABLE");
                var eleChildTBODY = document.createElement("TBODY");
                eleChildTABLE.appendChild(eleChildTBODY);

                for (eleObj in eObj)
                {
                    eleChildTBODY.appendChild(cs.Debug.helper_TR(eleObj, cs.Debug.inspectToHTML(eObj[eleObj], options)));
                }
                
                eleTBODY.appendChild(cs.Debug.helper_TR("OtherCustomObject", eleChildTABLE));
                

            }
            
            return eleTABLE;
        },
        
        /*
        Name        : inspect
        Description : Inspect the javascript object
        Revision    : 2007-12-04
        */
        inspect: function(eObj, opts)
        {
            var options = {};
            cs.common.Object.jointo(opts, options);
            var msgArray = new Array();

            if (options!=undefined)
            {
                // Check if the iteration had done deep enough.
                if (options.depth!=undefined)
                {
                    if (options.depth<=0)
                    {
                        msgArray.push("@@");
                        return msgArray;
                    }
                    else
                        options.depth-=1;
                }
            }
            
            // Try to figure out what is the object and show its values
            if (eObj==undefined)
            {
                msgArray.push("object undefined.\n");
            }
            else if (eObj.constructor==Boolean)
            {
                msgArray.push("<Boolean> " + eObj);
            }
            else if (eObj.constructor==String)
            {
                msgArray.push(eObj);
            }
            else if (eObj.constructor==Number)
            {
                msgArray.push("<Number> " + eObj);
            }
            else if (eObj.constructor==Function)
            {
                msgArray.push("<Function> [");
                msgArray.push(eObj);
                msgArray.push("]\n");
            }
            else if (eObj.constructor==Array)
            {
                msgArray.push("<Array> [");
                var intArrayCount=eObj.length;
                for (var i=0; i<eObj.length; i++)
                {
                    msgArray = msgArray.concat(this.inspect(eObj[i], options));
                    msgArray.push(", ");
                }
                msgArray.push("]\n");
            }
            else if (eObj.constructor==Object)
            {
                msgArray.push("<Object> [");
                for (eleObj in eObj)
                {
                    msgArray.push(eleObj);
                    msgArray.push(":");
                    msgArray = msgArray.concat(this.inspect(eObj[eleObj], options));
                    msgArray.push(", ");
                }
                msgArray.push("]\n");
            }
            else
            {
                // Unknown object, likely to be a custom object
                msgArray.push("<CustomObject> [");
                for (eleObj in eObj)
                {
                    msgArray.push(eleObj);
                    msgArray.push(":");
                    //msgArray = msgArray.concat(this.inspect(eObj[eleObj], options));
                    msgArray = msgArray.concat(eObj[eleObj], options);
                    msgArray.push(", ");
                }
                msgArray.push("]\n\n");
                //msgArray.push(eObj.constructor);
            }
            
            return msgArray;
        }
        
    },
    
    /*************************
        STRING FUNCTIONS
    **************************/

    /*
    Name        : formatString
    Description : Function that immulate the behavior of String.Format in .NET
    Revision    : 2007-11-20 v1.0 First Release
    */
    formatString: function()
    {
        var templateStr = arguments[0];
        if (arguments.length>1)
        {
            if (arguments[1].constructor == Array)
            {
                var paramArray = arguments[1];
                for (var v=0; v<=paramArray.length; v++)
                {
                    var re = new RegExp("\\{"+v+"\\}", "gi")
                    templateStr = templateStr.replace(re,paramArray[v]);
                }
            }
            else
            {
                for (var v=0; v<=arguments.length -1; v++)
                {
                    var re = new RegExp("\\{"+v+"\\}", "gi")
                    templateStr = templateStr.replace(re,arguments[v+1]);
                }
            }
        }
        return templateStr;    
    },
    
    CreateFunctionCallBack : function (func, aobjParam)
    {
        //var localRef = aobjParam;
        if (aobjParam==undefined)
            return function(){func();}
        else if (aobjParam.constructor==Function)
            return function(){func(aobjParam());}
        else
            return function(){aobjParam._this = this; func(aobjParam);}
    },

    CreateFunctionApply : function (func, obj, aarg)
    {
        if (aarg!=undefined)
            return function(){func.apply(obj, aarg)};
        else
            return function(){func.apply(obj)};
    },
    
    CreateFunctionCallBackWithCall : function (func, aobjParam)
    {
        if (aobjParam==undefined)
            return function(){func();}
        else if (aobjParam.constructor==Function)
            return function(){func.call(aobjParam());}
        else
            return function(){func.call(aobjParam);}
    },    
    
    CreateFunctionReturnFalse : function (func)
    {
        return function(){
            func();
            return false;
            };
    },

    CreateFunctionOnEnter : function(objToWire, funcToWire, aarg)
    {
        return function( evt, frm )
        {
            var keyCode = null;
            
            if (window.event)
            {
                // For IE
                keyCode = window.event.keyCode;
            }
            else if (evt.which)
            {
                // For Firefox
                keyCode = evt.which;
            }
            else if (evt.keyCode)
            {
                // TODO: for unknown???
                keyCode = evt.keyCode;
            }
            
            if( 13 == keyCode )
            {
                if (objToWire!=undefined)
                    funcToWire.apply(objToWire, aarg);
                else
                    funcToWire(aarg);
                    
                return false;
            }
            
            return true;
        }
    },
    
    MergeFunction : function(f1, f2)
    {
        if (arguments.length==2)
            return function(){f1(); f2();};
        return null;
    },
    
    getMousePosition : function(arge)
    {
        // Modified by CS on 20081122
        var e = arge;
        var pos = {x:0, y:0};
        
        if (!e) e = window.event;
        if (e.pageX || e.pageY) 	{
            pos.x = e.pageX;
            pos.y = e.pageY;
        }
        else if (e.clientX || e.clientY)
        {
            pos.x = e.clientX + document.body.scrollLeft
	            + document.documentElement.scrollLeft;
            pos.y = e.clientY + document.body.scrollTop
	            + document.documentElement.scrollTop;
        }
        return pos;
    },
    
    getAbsoluteOffset : function(ele)
    {
        var p = {x:ele.offsetLeft, y:ele.offsetTop};
        var parent = ele.offsetParent;
        while (parent!=undefined && parent.tagName.toLowerCase()!="BODY")
        {
            p.x += parent.offsetLeft;
            p.y += parent.offsetTop;
            parent = parent.offsetParent;
        }
        return p;
    },

    getAbsoluteSize : function(ele)
    {
        var p = {width:ele.scrollWidth, height:ele.scrollHeight};
        return p;
    },
    
    loadJS : function(url)
    {
       var e = document.createElement("script");
       e.src = url;
       e.type="text/javascript";
       document.getElementsByTagName("head")[0].appendChild(e);
    },
    
    getIndexInArray : function(aobj, obj)
    {
        if (aobj!=undefined && aobj.constructor==Array)
        {
            for (var i=0; i<aobj.length; i++)
            {
                if (aobj[i]==obj)
                    return i;
            }
            return -1;
        }
        else
        {
            cs.debugalert("getIndexInArray function requires an array as parameter.");
            return -1;
        }
    },
    
    cloneObject: function(obj)
    {
        if (typeof obj == 'object')
        {
            if (obj == null)
                return obj;
                
            if (obj.constructor == cs.forms.ControlBase)
                return obj.clone();
            
            // TODO: should do a proper clone
            if (obj.constructor == cs.forms.FormTemplate)
                return obj;
            
            var newObj = new Object();
	        for(var i in obj)
		        newObj[i] = cs.cloneObject(obj[i]);
            return newObj;
        }
        else
            return obj;
    },
    
    getElementById: function(strID, eleTR){
        for (strEleName in eleTR.childNodes)
        {
            if (eleTR.childNodes[strEleName].id==strID)
                return eleTR.childNodes[strEleName];
        }
        return null;
    },

    getNextHighestDepth: function()
    {
        if (window.highestdepth==undefined)
            window.highestdepth=1000;
        window.highestdepth += 1;
        return window.highestdepth;
    },
            
    /*************************
        GENERAL FUNCTIONS
    *************************/
    common: {
        
        Tab: function(objConfig)
        {
            if (objConfig.winform != undefined)
            {
                objConfig.contentdiv = objConfig.winform.contentdiv;
                this.winform = objConfig.winform;
            }
            
            var eleDIV = objConfig.contentdiv;
            var strTitle = objConfig.title;
            
            // Create the content div if it is not defined
            if (eleDIV==undefined)
            {
                eleDIV = document.createElement("DIV");
                eleDIV.appendChild(document.createTextNode(strTitle));
            }

            // Initialize the values
            // strTitle
            if (strTitle==undefined)
                strTitle = "(No Name)";
            
            eleDIV.style.overflow="auto";
            
            // Create the Tab Title DIV and add to the Tab Title Bar
            var eleTitleDIV = document.createElement("DIV");
            eleTitleDIV.style.display = "inline";

            var thisRef = this;
            
            // Keep the title tab and content panel in this object
            this.TitleTab = eleTitleDIV;
            this.ContentPanel = eleDIV;
            
            // Define the actions possible on a Tab
            this.activate = function(){

                this.ContentPanel.style.display = "inline";
                //this.bo.topborder.setStyle("background-color:yellow");
                this.bo.toptable.setClassName("GreenTheme");
                // Deactivate the rest of the tabs
                for (var intTab=0; intTab<window.global_tab.length; intTab++)
                {
                    if (window.global_tab[intTab]!=this)
                    {
                        window.global_tab[intTab].deactivate();
                    }
                }
            };
            
            this.deactivate = function(){
                // Change the color of the Title Tab
                this.ContentPanel.style.display = "none";
                //this.bo.topborder.setStyle("background-color:white");
                this.bo.toptable.setClassName("GreyTheme");
            };
            
            this._destroy = function(){

                this.ContentContainer.removeChild(this.ContentPanel);
                this.TabContainer.removeChild(this.TitleTab);
                for (var intTab=0; intTab<window.global_tab.length; intTab++)
                {
                    if (window.global_tab[intTab]==this)
                    {
                        window.global_tab.splice(intTab, 1);
                        break;
                    }
                }

            };
            
            this.destroy = function(){
                
                this._destroy();
                this.winform._destroy();

                // Activate the next last tab
                if (window.global_tab.length > 0)
                {
                    window.global_tab[window.global_tab.length - 1].activate();
                }
                
            };
            
            this.bo = {
                titlebar: new cs.forms.HTMLRef(),
                topborder: new cs.forms.HTMLRef(),
                toptable:new cs.forms.HTMLRef()
            };
            
            var jcsdom = new cs.forms.FormTemplate("RootForm",
                new cs.forms.FormTemplateItem("RootForm", "titlebar", "RootForm",
                    {tag:"div", style:"display:inline; float:left;", html:
                        new cs.forms.FormTemplateItem("RootForm", "toptable", "RootForm",
                            {tag:"table", cellpadding:0, cellspacing:0, style:"display:inline; cursor:pointer", className:"GreyTheme",
                                html:[
                                    new cs.forms.FormTemplateItem("RootForm", "topborder", "RootForm",
                                        {tag:"tr", html:[
                                            {tag:"td", html:"", className:"TabTopL"},
                                            {tag:"td", html:"", className:"TabTopM"},
                                            {tag:"td", html:"", className:"TabTopR"}
                                        ]}
                                    ),
                                    {tag:"tr", html:[
                                        {tag:"td", className:"TabMidL", html:""},
                                        {tag:"td", className:"TabMidM", html:[
                                            {tag:"table", html:
                                                {tag:"tr", html:[
                                                    {tag:"td", html:
                                                        {tag:"nobr", html:strTitle},
                                                        onclick:function(){
                                                            thisRef.activate();
                                                        },
                                                        ondblclick:function(){
                                                            //cs.debugalert("double clicked");
                                                        },
                                                        onmousedown:function(){
                                                        },
                                                        onmouseup:function(){
                                                        }                         
                                                    },
                                                    {tag:"td", html:"", style:"width:10px"},
                                                    {tag:"td", html:"", className:"TabClose",
                                                        onclick:function(){
                                                            thisRef.destroy();
                                                        }
                                                    }
                                                ]}
                                            }
                                        ]},
                                        {tag:"td", html:"", className:"TabMidR"},
                                        {tag:"td", html:"", style:"width:5px"}
                                    ]},
                                    {tag:"tr", html:[
                                        {tag:"td", html:"", className:"Tabbtm"},
                                        {tag:"td", html:"", className:"Tabbtm"},
                                        {tag:"td", html:"", className:"Tabbtm"}
                                    ]}                            
                                ]
                            }
                        )
                    }
                )
                );
            var opt = {bindingParent:{RootForm:this.bo}, populatingData:false};
            pc.appendJCSDOMtoJSDOM(jcsdom, eleTitleDIV, opt);                
            
            
            if (this.winform != undefined)
            {
                this.winform.maindiv.style.display = "none";
            }
            
            // TODO: need to change this
            this.TabContainer = document.getElementById("divTabBar");
            this.TabContainer.appendChild(eleTitleDIV);

            // Add this.ContentPanel to the Tab Content DIV
            this.ContentContainer = document.getElementById("divTabContent"); // TODO: need to change this
            this.ContentContainer.appendChild(this.ContentPanel);
            
            this.activate();
        },
        
        Window: {
           
            CreateTDInTR: function(eleTR, objStyle, strClassName)
            {
                var strTDID = "td" + ((Math.random() * 1000) % 1000);
                var jcsdomTD = {tag:"td", id:strTDID,
                html:[
                    {tag:"div", style:"display:block;", classname:strClassName}
                    
                ]};
                pc.appendJCSDOMtoJSDOM(jcsdomTD, eleTR);
                return cs.getElementById(strTDID, eleTR);
            },
            
            CreateWindow: function(objConfig)
            {
                var eleDIV = objConfig.contentdiv;
                var strTitle = objConfig.title;
                
                // Create the content div if it is not defined
                if (eleDIV==undefined)
                {
                    eleDIV = document.createElement("DIV");
                }
                eleDIV.style.overflow="auto";
                eleDIV.className = "windowcontent";

                // Initialize the values
                // strTitle
                if (strTitle==undefined)
                    strTitle = "(No Name)";
                
                // Define a default minimum width and height
                if (objConfig.minwidth==undefined)
                    objConfig.minwidth = 200;
                if (objConfig.minheight==undefined)
                    objConfig.minheight = 100;
                    
                var borderStyle = {backgroundColor:"#c0c0c0", width:"5px", height:"5px"};
                
                var boWindow = {
                    mainwindow: new cs.forms.HTMLRef(),
                    tdtitle: new cs.forms.HTMLRef(),
                    tdminimize: new cs.forms.HTMLRef(),
                    tdmaximize: new cs.forms.HTMLRef(),
                    tdtab: new cs.forms.HTMLRef(),
                    tdclose: new cs.forms.HTMLRef(),
                    
                    tdnwbar: new cs.forms.HTMLRef(),
                    tdnbar: new cs.forms.HTMLRef(),
                    tdnebar: new cs.forms.HTMLRef(),
                    
                    tdwbar: new cs.forms.HTMLRef(),
                    tdtitlewbar: new cs.forms.HTMLRef(),
                    tdebar: new cs.forms.HTMLRef(),
                    tdtitleebar: new cs.forms.HTMLRef(),
                    
                    tdswbar: new cs.forms.HTMLRef(),
                    tdsbar: new cs.forms.HTMLRef(),
                    tdsebar: new cs.forms.HTMLRef(),
                    
                    wborder_nw: new cs.forms.Div({style:"display:block", classname:"window_NW_border"}),
                    wborder_n: new cs.forms.Div({style:"display:block", classname:"window_N_border"}),
                    wborder_ne: new cs.forms.Div({style:"display:block", classname:"window_NE_border"}),
                    
                    title_w_border: new cs.forms.Div({style:"display:block", classname:"title_W_border"}),
                    title_e_border: new cs.forms.Div({style:"display:block", classname:"title_E_border"}),
                    titlebar: new cs.forms.Div({defaultvalue:strTitle})
                };
                
                var jcsdomWindow = new cs.forms.FormTemplate("RootForm", new cs.forms.FormTemplateItem("RootForm", "mainwindow", "RootForm",
                {tag:"table",
                    className:"tbpanel", border:"0",
                    cellspacing:0, cellpadding:0,
                    style:"zindex:"+cs.getNextHighestDepth(),
                    html:[
                            {tag:"tr", html:[ // Top Border
                                new cs.forms.FormTemplateItem("RootForm", "tdnwbar", "RootForm", {tag:"td", html:new cs.forms.FormTemplateItem("RootForm", "wborder_nw")}),
                                new cs.forms.FormTemplateItem("RootForm", "tdnbar", "RootForm", {tag:"td", html:new cs.forms.FormTemplateItem("RootForm", "wborder_n")}),
                                new cs.forms.FormTemplateItem("RootForm", "tdnebar", "RootForm", {tag:"td", html:new cs.forms.FormTemplateItem("RootForm", "wborder_ne")})
                            ]},
                            {tag:"tr", html:[ // Title Bar
                                new cs.forms.FormTemplateItem("RootForm", "tdtitlewbar", "RootForm", {tag:"td", html:new cs.forms.FormTemplateItem("RootForm", "title_w_border")}),
                                {tag:"td", html:[
                                    {tag:"table", classname:"panelBar",
                                        html:{tag:"tr", html:[
                                                new cs.forms.FormTemplateItem("RootForm", "tdtitle", "RootForm", {tag:"td", classname:"title", html:new cs.forms.FormTemplateItem("RootForm", "titlebar")}),
                                                new cs.forms.FormTemplateItem("RootForm", "tdminimize", "RootForm", {tag:"td", html:{tag:"div", classname:"window01"}}),
                                                new cs.forms.FormTemplateItem("RootForm", "tdmaximize", "RootForm", {tag:"td", html:{tag:"div", classname:"window02"}}),
                                                new cs.forms.FormTemplateItem("RootForm", "tdtab", "RootForm", {tag:"td", html:{tag:"div", classname:"window01"}}),
                                                new cs.forms.FormTemplateItem("RootForm", "tdclose", "RootForm", {tag:"td", html:{tag:"div", classname:"window03"}})
                                            ]}
                                    }
                                ]},
                                new cs.forms.FormTemplateItem("RootForm", "tdtitleebar", "RootForm", {tag:"td", html:new cs.forms.FormTemplateItem("RootForm", "title_e_border")})
                            ]},
                            {tag:"tr", html:[ // Content
                                new cs.forms.FormTemplateItem("RootForm", "tdwbar", "RootForm", {tag:"td", classname:"window_W_border"}),
                                {tag:"td", classname:"windowcontentcell", html:eleDIV},
                                new cs.forms.FormTemplateItem("RootForm", "tdebar", "RootForm", {tag:"td", classname:"window_E_border"})
                            ]},
                            {tag:"tr", html:[ // Bottom
                                new cs.forms.FormTemplateItem("RootForm", "tdswbar", "RootForm", {tag:"td", classname:"window_SW_border"}),
                                new cs.forms.FormTemplateItem("RootForm", "tdsbar", "RootForm", {tag:"td", classname:"window_S_border"}),
                                new cs.forms.FormTemplateItem("RootForm", "tdsebar", "RootForm", {tag:"td", classname:"window_SE_border"})
                            ]}                            
                        ]
                }));
                
                var opt = {bindingParent:{RootForm:boWindow}, populatingData:false};
                pc.appendJCSDOMtoJSDOM(jcsdomWindow, window.document.body, opt);

                //cs.Debug.alertTrace();
                //cs.debugalert(boWindow.mainwindow.controlid);
                //cs.debugalert(cs.Debug.inspect(boWindow.tdmaximize.getElement().id));

                var newWindow = {
                        maindiv:boWindow.mainwindow.getElement(),
                        contentdiv:eleDIV,
                        titlebar:boWindow.titlebar.getElement(),
                        minimizebar:[boWindow.tdminimize.getElement()],
                        maximizebar:[boWindow.tdmaximize.getElement()],
                        tabbar:[boWindow.tdtab.getElement()],
                        closebar:[boWindow.tdclose.getElement()],
                        movebar:[boWindow.tdtitle.getElement()],
                        nwbar:[boWindow.tdnwbar.getElement()],
                        nbar:[boWindow.tdnbar.getElement()],
                        nebar:[boWindow.tdnebar.getElement()],
                        wbar:[boWindow.tdwbar.getElement(),boWindow.tdtitlewbar.getElement()],
                        ebar:[boWindow.tdebar.getElement(),boWindow.tdtitleebar.getElement()],
                        swbar:[boWindow.tdswbar.getElement()],
                        sbar:[boWindow.tdsbar.getElement()],
                        sebar:[boWindow.tdsebar.getElement()],
                        minwidth:objConfig.minwidth,
                        minheight:objConfig.minheight,
                        onclose_event:new Array(),
                        close:function(){
                            for (var intCloseEvent=0; intCloseEvent<this.onclose_event.length; intCloseEvent++)
                            {
                                if (this.onclose_event[intCloseEvent].constructor == Function)
                                {
                                    this.onclose_event[intCloseEvent]();
                                }
                            }
                            this.destroy();
                        },
                        switchtotab:function(){
                        
                            this.tab = new cs.common.Tab({title:strTitle, winform:this});
                            window.global_tab.push(this.tab);
                            
                            this.mode = "tab";
                        },
                        maximize:function()
                        {
                            // Store the old left, top, width, height
                            var mWindow = this.maindiv;
                            
                            if (this._ismaximized==undefined)
                                this._ismaximized = false;
                                
                            if (this._ismaximized)
                            {
                                mWindow.style.position = "absolute";
                                mWindow.style.width = mWindow.old_width;
                                mWindow.style.height = mWindow.old_height;
                                mWindow.style.left = mWindow.old_left;
                                mWindow.style.top = mWindow.old_top;
                                this._ismaximized = false;

                                this.contentdiv.style.height = "100%";
                                this.contentdiv.style.width = "100%";
                                this.contentdiv.style.display = "block";
                            }
                            else
                            {
                                mWindow.old_width = mWindow.style.width;
                                mWindow.old_height = mWindow.style.height;
                                mWindow.old_left = mWindow.style.left;
                                mWindow.old_top = mWindow.style.top;
                                
                                this.contentdiv.style.display = "none";
                                
                                mWindow.style.position = "fixed";
                                mWindow.style.width = "100%";
                                mWindow.style.height = "100%";
                                mWindow.style.left = "0px";
                                mWindow.style.top = "0px";
                                this._ismaximized = true;
                                
                                mWindow.style.width = mWindow.scrollWidth + "px";
                                mWindow.style.height = mWindow.scrollHeight + "px";
                                
                                this.contentdiv.style.height = (mWindow.scrollHeight - 35) + "px";
                                this.contentdiv.style.display = "block";
                            }
                        },
                        minimize:function()
                        {
                            if (this.contentdiv.style.display=="none")
                            {
                                this.maindiv.style.height = (parseInt(this.contentdiv.scrollHeight) + 10 + parseInt(this.titlebar.style.height)) + "px";
                                this.contentdiv.style.display = "block";
                            }
                            else
                            {
                                // Just incase if CSS class doesn't set the title bar height
                                if (this.titlebar.style.height=="")
                                    this.titlebar.style.height = "10px";

                                this.maindiv.style.height = (10 + parseInt(this.titlebar.style.height)) + "px";
                                this.contentdiv.style.display = "none";
                            }
                        },
                        setTitle:function(strTitle){this.titlebar.innerHTML=strTitle;},
                        _destroy:function(){

                            // remove myself
                            window.document.body.removeChild(this.maindiv);
                            for (var iwf=window.global_awindowform.length-1; iwf>=0; iwf--)
                            {
                                if (window.global_awindowform[iwf]==this)
                                {
                                    window.global_awindowform.splice(iwf, 1);
                                    break;
                                }
                            }
                            this.destroyed = true;

                        },
                        destroy:function(){

                            if (this.mode == "tab")
                            {
                                this.tab.destroy();
                            }
                            else
                            {
                                this._destroy();
                                
                                if (this.tab!=undefined)
                                    this.tab._destroy();

                                // make the last one visible
                                if (window.global_awindowform.length>0)
                                    window.global_awindowform[window.global_awindowform.length-1].makeactive();
                            }

                        },
                        makeactive:function(){
                            // Ensure that I am of the highest depth
                            // And my opacity is full
                            // TODO: if this is optional, then have to ensure the default is inactive theme
                            this.maindiv.style.opacity = 1;
                            this.maindiv.style.zIndex=cs.getNextHighestDepth();
                            // Make all others inactive
                            if (window.global_awindowform!=undefined)
                            {
                                for (var iwf=0; iwf<window.global_awindowform.length; iwf++)
                                {
                                    if (window.global_awindowform[iwf]!=this)
                                        window.global_awindowform[iwf].makeinactive();
                                }
                            }
                        },
                        makeinactive:function(){
                            // Set my opacity to 70%
                            this.maindiv.style.opacity = 0.7;
                        }
                    };
                
                if (objConfig.position!=undefined)
                    newWindow.position = objConfig.position;
                    
                cs.common.Window.SetupWindow(newWindow);
                
                // Keep track of this window in the global_variable
                if (window.global_awindowform==undefined)
                    window.global_awindowform = new Array();
                
                window.global_awindowform.push(newWindow);
                
                newWindow.makeactive();
                
                // TODO: This will depend on the user preference
                if (window.autotab!=false)
                    newWindow.switchtotab();
                
                return newWindow;
            },
            
            SetupWindow: function(objW)
            {
                objW.maindiv.style.position = "absolute";
                
                // Position the window
                if (objW.maindiv.style.left==""||objW.maindiv.style.top=="")
                {
                    // Check if window position is being passed in
                    if (objW.position!=undefined)
                    {
                        objW.maindiv.style.left = objW.position.x;
                        objW.maindiv.style.top = objW.position.y;
                    }
                    else
                    {
                        if (window._lastwindowposition!=undefined)
                        {
                            window._lastwindowposition.x += 20;
                            window._lastwindowposition.y += 10;
                            if (window._lastwindowposition.x > 300)
                            {
                                window._lastwindowposition.x = 100;
                                window._lastwindowposition.y = 70;
                            }
                        }
                        else
                        {
                            window._lastwindowposition = {
                                x:100, //(parseInt(document.body.offsetWidth)/2 - (objW.minwidth/2)),
                                y:70 //(parseInt(document.body.offsetHeight)/8)
                            };
                        }
                        objW.maindiv.style.left = window._lastwindowposition.x + "px";
                        objW.maindiv.style.top = window._lastwindowposition.y + "px";
                    }
                }
                
                if (objW.maindiv.style.width==""||objW.maindiv.height=="")
                {
                    objW.maindiv.style.width=objW.minwidth + "px";
                    objW.maindiv.style.height=objW.minheight + "px";
                }
                
                // Make the window top visible window if it is not defined yet
                if (objW.maindiv.style.zIndex=="")
                    objW.maindiv.style.zIndex=objW.maindiv.style.zIndex=cs.getNextHighestDepth();

                objW.maindiv.onmousedown = function(e)
                {
                    objW.makeactive();
                }; 

                cs.common.Window.SetupWindow_ClickBar(objW);

                // Attach the mousedown event to all the movebar
                for (eleName in objW.movebar)
                    cs.common.Window.SetupWindow_BehaviourBar({target:objW.movebar[eleName], window:objW, contentdiv:objW.contentdiv, maindiv:objW.maindiv, titlebar:objW.titlebar, minwidth:objW.minwidth, minheight:objW.minheight, behaviour:"move"});
                for (eleName in objW.nwbar)
                    cs.common.Window.SetupWindow_BehaviourBar({target:objW.nwbar[eleName], window:objW, contentdiv:objW.contentdiv, maindiv:objW.maindiv, titlebar:objW.titlebar, minwidth:objW.minwidth, minheight:objW.minheight, behaviour:"nw-resize"});
                for (eleName in objW.nbar)
                    cs.common.Window.SetupWindow_BehaviourBar({target:objW.nbar[eleName], window:objW, contentdiv:objW.contentdiv, maindiv:objW.maindiv, titlebar:objW.titlebar, minwidth:objW.minwidth, minheight:objW.minheight, behaviour:"n-resize"});
                for (eleName in objW.nebar)
                    cs.common.Window.SetupWindow_BehaviourBar({target:objW.nebar[eleName], window:objW, contentdiv:objW.contentdiv, maindiv:objW.maindiv, titlebar:objW.titlebar, minwidth:objW.minwidth, minheight:objW.minheight, behaviour:"ne-resize"});
                for (eleName in objW.wbar)
                    cs.common.Window.SetupWindow_BehaviourBar({target:objW.wbar[eleName], window:objW, contentdiv:objW.contentdiv, maindiv:objW.maindiv, titlebar:objW.titlebar, minwidth:objW.minwidth, minheight:objW.minheight, behaviour:"w-resize"});
                for (eleName in objW.ebar)
                    cs.common.Window.SetupWindow_BehaviourBar({target:objW.ebar[eleName], window:objW, contentdiv:objW.contentdiv, maindiv:objW.maindiv, titlebar:objW.titlebar, minwidth:objW.minwidth, minheight:objW.minheight, behaviour:"e-resize"});
                for (eleName in objW.swbar)
                    cs.common.Window.SetupWindow_BehaviourBar({target:objW.swbar[eleName], window:objW, contentdiv:objW.contentdiv, maindiv:objW.maindiv, titlebar:objW.titlebar, minwidth:objW.minwidth, minheight:objW.minheight, behaviour:"sw-resize"});
                for (eleName in objW.sbar)
                    cs.common.Window.SetupWindow_BehaviourBar({target:objW.sbar[eleName], window:objW, contentdiv:objW.contentdiv, maindiv:objW.maindiv, titlebar:objW.titlebar, minwidth:objW.minwidth, minheight:objW.minheight, behaviour:"s-resize"});
                for (eleName in objW.sebar)
                    cs.common.Window.SetupWindow_BehaviourBar({target:objW.sebar[eleName], window:objW, contentdiv:objW.contentdiv, maindiv:objW.maindiv, titlebar:objW.titlebar, minwidth:objW.minwidth, minheight:objW.minheight, behaviour:"se-resize"});

            },
            
            SetupWindow_ClickBar: function(objW)
            {
                cs.common.Window.SetupWindow_ClickBar_Assign({clickbar:objW.titlebar, windowform:objW, action:"maximize", event:"ondblclick"});

                for (eleName in objW.maximizebar)
                {
                    cs.common.Window.SetupWindow_ClickBar_Assign({clickbar:objW.maximizebar[eleName], windowform:objW, action:"maximize"});
                }
                
                for (eleName in objW.minimizebar)
                    cs.common.Window.SetupWindow_ClickBar_Assign({clickbar:objW.minimizebar[eleName], windowform:objW, action:"minimize"});
                for (eleName in objW.closebar)
                    cs.common.Window.SetupWindow_ClickBar_Assign({clickbar:objW.closebar[eleName], windowform:objW, action:"close"});
                for (eleName in objW.tabbar)
                    cs.common.Window.SetupWindow_ClickBar_Assign({clickbar:objW.tabbar[eleName], windowform:objW, action:"switchtotab"});
            },
            
            SetupWindow_ClickBar_Assign: function(objConfig)
            {
                if (objConfig.event==undefined)
                    objConfig.event = "onclick";
                
                switch (objConfig.action)
                {
                    case "maximize":
                        objConfig.clickbar.style.cursor = "pointer";
                        objConfig.clickbar[objConfig.event] = function() {objConfig.windowform.maximize()};
                        break;
                    
                    case "minimize":
                        objConfig.clickbar.style.cursor = "pointer";
                        objConfig.clickbar[objConfig.event] = function() {objConfig.windowform.minimize()};
                        break;
                        
                    case "switchtotab":
                        objConfig.clickbar.style.cursor = "pointer";
                        objConfig.clickbar[objConfig.event] = function() {objConfig.windowform.switchtotab()};
                        break;
                        
                    case "close":
                        objConfig.clickbar.style.cursor = "pointer";
                        objConfig.clickbar[objConfig.event] = function() {objConfig.windowform.close()};
                        break;
                }
            },

            SetupWindow_BehaviourBar: function(objConfig)
            {
                switch (objConfig.behaviour)
                {
                    case "move":

                        objConfig.target.onmouseup = function()
                        {
                            if (objConfig.window._ismaximized)
                                return;
                                
                            var hitPlacement = null;
                            for (var i=0; i<window.layoutplacement.length; i++)
                            {
                                if (window.layoutplacement[i].hit==true)
                                {
                                    hitPlacement = window.layoutplacement[i];
                                }
                            }
                            if (hitPlacement!=null)
                            {
                                // This is for IE, since IE won't propagate the event to document
                                document.onmouseup();
                                
                                // Put the maindiv(table) in to the hitPlacement DIV
                                // Revised: move the contentdiv to the hitPlacement DIV
                                hitPlacement.element.appendChild(objConfig.maindiv);
                                hitPlacement.element.style.borderStyle = "none";
                                
                                // Hide the maindiv
                                //objConfig.maindiv.style.display = "none";
                                
                                objConfig.maindiv.style.position = "relative";
                                objConfig.maindiv.style.left = "0px";
                                objConfig.maindiv.style.top = "0px";
                                
                                
                                // Add the tab to the tab DIV
                                
                            }
                        };
                    case "nw-resize":
                    case "n-resize":
                    case "ne-resize":
                    case "w-resize":
                    case "e-resize":
                    case "sw-resize":
                    case "s-resize":
                    case "se-resize":
                        objConfig.target.style.cursor = objConfig.behaviour;
                        break;
                }
                
                var funcChangePlacement = function()
                {
                    for (var i=0; i<window.layoutplacement.length; i++)
                    {
                        var divArea = window.layoutplacement[i].element;
                        var offsetDIVArea = cs.getAbsoluteOffset(divArea);
                        var sizeDIVArea = cs.getAbsoluteSize(divArea);
                        
                        var pos = {start:{x:parseInt(offsetDIVArea.x),
                                    y:parseInt(offsetDIVArea.y)},
                                end:{x:parseInt(offsetDIVArea.x)+parseInt(sizeDIVArea.width),
                                    y:parseInt(offsetDIVArea.y)+parseInt(sizeDIVArea.height)}};
                                    
                        window.layoutplacement[i].position = pos;
                        if (divArea.style.zIndex==undefined || divArea.style.zIndex=="")
                            window.layoutplacement[i].depth = 1;
                        window.layoutplacement[i].depth = parseInt(divArea.style.zIndex);
                    }
                                        
                    // Calculate the difference in offset of the layer and current cursor.
                    var eleTarget = objConfig.maindiv;
                    // Break the maindiv out of the parent.
                    // Get its absolute position
                    var posTarget = cs.getAbsoluteOffset(eleTarget);
                    eleTarget.style.position = "absolute";
                    eleTarget.style.left = posTarget.x + "px";
                    eleTarget.style.top = posTarget.y + "px";                
                }
                
                var funcMouseDown = function(e)
                {
                    // Ignore any activity if the window is maximized
                    if (objConfig.window._ismaximized)
                        return;
                
                    var eleTarget = objConfig.maindiv;

                    var posMouse = cs.getMousePosition(e);
                    posMouse.x -= parseInt(eleTarget.style.left);
                    posMouse.y -= parseInt(eleTarget.style.top);
                    
                    var posOrgDIV = {x:parseInt(eleTarget.style.left),
                                     y:parseInt(eleTarget.style.top),
                                     width:parseInt(eleTarget.style.width),
                                     height:parseInt(eleTarget.style.height)};
                                     
                    if (eleTarget.style.width=="100%")
                        posOrgDIV.width = parseInt(eleTarget.offsetWidth);

                    if (eleTarget.style.height=="100%")
                        posOrgDIV.height = parseInt(eleTarget.offsetHeight);

                    cs.common.Window.SetupWindow_BehaviourBarDragDrop({target:objConfig.target, maindiv:objConfig.maindiv,
                                                                    contentdiv:objConfig.contentdiv, titlebar:objConfig.titlebar,
                                                                    offset:posMouse, behaviour:objConfig.behaviour, maindivorgpos:posOrgDIV,
                                                                    minwidth:objConfig.minwidth, minheight:objConfig.minheight});
                }
                
                switch (objConfig.behaviour)
                {
                    case "move":
                        objConfig.target.onmousedown = function(e){
                                    if (objConfig.window._ismaximized)
                                        return;                        
                                    funcChangePlacement();
                                    funcMouseDown(e);
                                };
                        break;
                    default:
                        objConfig.target.onmousedown = funcMouseDown;
                        break;
                }
            },
            
            SetupWindow_BehaviourBarDragDrop: function(objConfig)
            {
                // eleMouse, eleDIV, offset
                var eleMouse = objConfig.target;
                var eleDIV = objConfig.maindiv;
                var offset = objConfig.offset;
                
                eleMouse.enableDrag = true;
                
                if (document.onmouseup==undefined)
                {
                    document.onmouseup = function()
                    {
                        eleMouse.enableDrag = false;
                        document.onmousemove = null;
                        document.onmouseup = null;
                    }
                }
                
                if (eleMouse.enableDrag)
                {
                    document.onmousemove = function(e)
                    {
                        
                        // Check if it falls on the predefined area on the page
                        
                        var posMouse = cs.getMousePosition(e);
                        
                        if (objConfig.behaviour=="move")
                        {
                            var hitPlacement = null;
                            for (var i=0; i<window.layoutplacement.length; i++)
                            {
                                var pos = window.layoutplacement[i].position;
                                if (pos.start.x < posMouse.x && posMouse.x < pos.end.x
                                    && pos.start.y < posMouse.y && posMouse.y < pos.end.y)
                                {
                                    if (hitPlacement==null)
                                    {
                                        hitPlacement = window.layoutplacement[i];
                                        hitPlacement.element.style.borderColor = "#F0F0F0";
                                        hitPlacement.element.style.borderStyle = "dashed";
                                        hitPlacement.element.style.borderWidth = "2px";
                                        hitPlacement.hit = true;
                                    }
                                    else if (window.layoutplacement[i].depth >= hitPlacement.depth)
                                    {
                                        // Hide the old one
                                        hitPlacement.element.style.borderStyle = "none";
                                        hitPlacement.hit = false;
                                        hitPlacement = window.layoutplacement[i];
                                        hitPlacement.element.style.borderColor = "#F0F0F0";
                                        hitPlacement.element.style.borderStyle = "dashed";
                                        hitPlacement.element.style.borderWidth = "2px";
                                        hitPlacement.hit = true;
                                    }
                                    else
                                    {
                                        window.layoutplacement[i].element.style.borderStyle = "none";
                                        window.layoutplacement[i].hit = false;
                                    }
                                }
                                else
                                {
                                    window.layoutplacement[i].element.style.borderStyle = "none";
                                    window.layoutplacement[i].hit = false;
                                }
                            }
                        }
                        
                        if (eleMouse.enableDrag==true)
                        {
                            var realOffset = {x:(posMouse.x - offset.x) - objConfig.maindivorgpos.x,
                                             y:(posMouse.y - offset.y) - objConfig.maindivorgpos.y};
                            var newPosition = {x:-1, y:-1};
                            var newSize = {height:-1, width:-1};
                            
                            switch(objConfig.behaviour)
                            {
                                case "move":
                                    newPosition.x = (posMouse.x - offset.x);
                                    newPosition.y = (posMouse.y - offset.y);
                                    break;
                                case "nw-resize":
                                    newPosition.x = (posMouse.x - offset.x);
                                    newPosition.y = (posMouse.y - offset.y);
                                    newSize.width = (objConfig.maindivorgpos.width - realOffset.x);
                                    newSize.height = (objConfig.maindivorgpos.height - realOffset.y);
                                    break;
                                case "n-resize":
                                    newPosition.y = (posMouse.y - offset.y);
                                    newSize.height = (objConfig.maindivorgpos.height - realOffset.y);
                                    break;
                                case "ne-resize":
                                    newPosition.y = (objConfig.maindivorgpos.y + realOffset.y);
                                    newSize.height = (objConfig.maindivorgpos.height - realOffset.y);
                                    newSize.width = (objConfig.maindivorgpos.width + realOffset.x);
                                    break;
                                    
                                case "w-resize":
                                    newPosition.x = (objConfig.maindivorgpos.x + realOffset.x);
                                    newSize.width = (objConfig.maindivorgpos.width - realOffset.x);
                                    break;
                                case "e-resize":
                                    newSize.width = (objConfig.maindivorgpos.width + realOffset.x);
                                    break;
                                    
                                case "sw-resize":
                                    newPosition.x = (objConfig.maindivorgpos.x + realOffset.x);
                                    newSize.height = (objConfig.maindivorgpos.height + realOffset.y);
                                    newSize.width = (objConfig.maindivorgpos.width - realOffset.x);
                                    break;
                                case "s-resize":
                                    newSize.height = (objConfig.maindivorgpos.height + realOffset.y);
                                    break;
                                case "se-resize":
                                    newSize.width = (objConfig.maindivorgpos.width + realOffset.x);
                                    newSize.height = (objConfig.maindivorgpos.height + realOffset.y);
                                    break;
                            }
//                            document.getElementById("divDebug").innerHTML = "newSize: " + newSize.width + " : " + newSize.height + "<br/>" +
//                                                                            "newPos: " + newPosition.x + " : " + newPosition.y + "<br/>" +
//                                                                            "Original: " + eleDIV.style.width + " : " + eleDIV.style.height + "<br/>" +
//                                                                            "realOffset: " + realOffset.x + " : " + realOffset.y + "<br/>" +
//                                                                            "offsetSize: " + objConfig.contentdiv.offsetWidth + " : " + objConfig.contentdiv.offsetHeight + "<br/>" +
//                                                                            "scrollSize: " + objConfig.contentdiv.scrollWidth + " : " + objConfig.contentdiv.scrollHeight + "<br/>";
                            if (newSize.width>=0)
                            {
                                // The width need a test on its own, different from the height detection
                                eleDIV.style.width = newSize.width + "px";
                                var intMinWidth = parseInt(objConfig.contentdiv.offsetWidth) + 10;
                                if (objConfig.minwidth>intMinWidth) intMinWidth=objConfig.minwidth;
                                if (newSize.width<intMinWidth)
                                {
                                    eleDIV.style.width = intMinWidth + "px";
                                    newPosition.x = -1;
                                    //document.getElementById("divDebug").innerHTML += "rectified width:" + intMinWidth;
                                }

                            }
                            if (newSize.height>=0)
                            {
                                // Check if the height did change or not
                                var intMinHeight = parseInt(objConfig.contentdiv.offsetHeight) + 10 + parseInt(objConfig.titlebar.offsetHeight);
                                if (objConfig.minheight>intMinHeight) intMinHeight=objConfig.minheight;
                                if (newSize.height<intMinHeight)
                                {
                                    eleDIV.style.height = intMinHeight + "px";
//                                    if (parseInt(eleDIV.style.height)!=parseInt(eleDIV.offsetHeight))
//                                    {
//                                        intMinHeight = intMinHeight - (parseInt(eleDIV.offsetHeight) - intMinHeight);
//                                        eleDIV.style.height = intMinHeight + "px";
//                                    }
                                    newPosition.y = -1;
                                    //document.getElementById("divDebug").innerHTML += "rectified height:" + intMinHeight;
                                }
                                else
                                    eleDIV.style.height = newSize.height + "px";                                
                            }
                            
                            if (newPosition.x>0)
                                eleDIV.style.left = newPosition.x + "px";
                            if (newPosition.y>0)
                                eleDIV.style.top = newPosition.y + "px";
                        }
                        return false;
                    }
                }
            }            
        
        },
        Object: {
            jointo: function(obj1, obj2)
            {
                for (ename in obj1)
                {
                    obj2[ename] = obj1[ename];
                }
            },
            
            simpleClone: function(obj1, obj2)
            {
                if (obj1.constructor==obj2.constructor)
                {
                    if (obj1.constructor==Array)
                    {
                        for (var i=0; i<obj1.length; i++)
                        {
                            obj2[i]=obj1[i];
                        }
                    }
                    else
                    {
                        cs.debugalert("clone not supported currently for " + obj1.constructor);
                    }
                }
                else
                {
                    cs.debugalert("clone is not possible with different object type.");
                }
            },
            
            clone: function(obj)
            {
                if (obj.constructor==Array)
                {
                    var newObj = new Array();
                    cs.common.Object.simpleClone(obj, newObj);
                    return newObj;
                }
                else
                {
                    cs.debugalert("clone is not possible with unknown object type.");
                    return null;
                }
            }
        },
        Document:{
            setCookie: function(strName, strValue, expiration)
            {
                var aCookie = new Array();
                aCookie.push(strName + "=" + strValue);
                
                var dateRef = new Date();
                if (expiration != undefined)
                {
                    if (expiration.constructor == Date)
                    {
                        dateRef = expiration;
                        aCookie.push(";expires=" + dateRef.toUTCString());
                    }
                    else if (expiration.constructor == Number)
                    {
                        dateRef.setHours(dateRef.getHours() + expiration);
                        aCookie.push(";expires=" + dateRef.toUTCString());
                    }
                }
                document.cookie = aCookie.join("");
            },
            getCookie: function(strName)
            {
                var aCookie = document.cookie.split(";");
                for (var i=0; i<aCookie.length; i++)
                {
                    var aEntry = aCookie[i].split("=");
                    if (aEntry.length==2)
                    {
                        if (cs.common.String.trim(aEntry[0])==strName)
                            return aEntry[1];
                    }
                }
                return null;
            }
        },
        Date:{
            convertTo: function(dt, format)
            {
                if (dt!=undefined && dt.constructor==Date)
                {
                    switch (format)
                    {
                        case "yyyy-mm-dd":
                            return String(dt.getFullYear()) + "-" + cs.common.String.frontpadding(dt.getMonth() + 1, "0", 2) + "-" + cs.common.String.frontpadding(dt.getDate(), "0", 2);
                            break;
                            
                    } 
                    return "format not defined";
                }
                else
                    return "";
            }
        },
        String:{
            // Taken from http://blog.stevenlevithan.com/archives/faster-trim-javascript
            trim: function(str)
            {
	            str = str.replace(/^\s+/, '');
	            for (var i = str.length - 1; i >= 0; i--) {
		            if (/\S/.test(str.charAt(i))) {
			            str = str.substring(0, i + 1);
			            break;
		            }
	            }
	            return str;
            },
            frontpadding: function(str, strPad, intLength)
            {
                if (str==undefined)
                    str = "";
                    
                var strP = String(str);
                while (strP.length < intLength)
                    strP = strPad + strP;
                return strP;
            }
        },
        Array:{
            removeEntryByCondition: function(alist, opt)
            {
                
                for (var i=0; i<alist.length; i++)
                {
                    var bRemove = true;
                    for (strName in opt)
                    {
                        if (alist[i][strName]!=opt[strName])
                        {
                            bRemove = false;
                        }
                    }
                    
                    if (bRemove)
                    {
                        alist.splice(i, 1);
                        i -= 1;
                    }
                }                
            },
            createArrayFromEntry: function(obj)
            {
                var afinal = new Array();
                if (obj == undefined)
                    return afinal;
                else
                {
                    if (obj.constructor == Array)
                        return obj;
                    else
                    {
                        afinal.push(obj);
                        return afinal;
                    }
                }
            }
        },
        Boolean:{
            parse: function(str)
            {
                if (str!=undefined)
                {
                    str = String(str);
                    switch (str.toLowerCase())
                    {
                        case "true":
                        case "1":
                            return true;
                            break;
                            
                        case "false":
                        case "0":
                            return false;
                            break;
                            
                    }
                    throw "cs.common.Boolean: unable to parse " + str;
                }
                else
                {
                    throw "cs.common.Boolean: unable to parse undefined string";
                }
            }
        }
    }    
};