﻿/**
 * Forms Classes
 * Classes related to form controls
 * Dependency: cs_jscore.js
 **/
if (cs==undefined)
{
	alert("Error! cs namespace is not defined.");
	cs = {};
}

cs.forms = {};
cs.forms.Common = {};
cs.forms.Common.getFormJSON = function(frm, opt){
        var dt = {};
        // Loop thru the properties and check if it has the getValue function
        for (eleName in frm)
        {
            if (frm[eleName].getValue)
            {
                dt[eleName]=frm[eleName].getValue(opt);
            }
        }
        return dt;
    };

cs.forms.Common.syncValue = function(bo, opt){
    for (eleName in bo)
    {
        if (bo[eleName].getValue)
        {
            try
            {
                bo[eleName].setValue(bo[eleName].getValue(opt));
            }
            catch (e)
            {
                // TODO: need to handle those that do not have setValue
                //cs.debugalert(eleName + ":" + e);
            }
        }
    }
};
    
cs.forms.Common.bulksetControl = function(){
    
    var ListOfControls = arguments[0];
    var strFuncName = arguments[1];
    var strValue1 = arguments[2];
    if (arguments.length > 3)
        var strValue2 = arguments[3];
    if (arguments.length > 4)
        var strValue3 = arguments[4];
    if (arguments.length > 5)
        var strValue4 = arguments[5];
        
    if (ListOfControls!=undefined && ListOfControls.constructor==Array)
    {
        for (var i=0; i<ListOfControls.length; i++)
        {
            if (ListOfControls[i][strFuncName]!=undefined)
            {
                switch(arguments.length)
                {
                    case 3:
                    case 4:
                    case 5:
                    case 6:
                        ListOfControls[i][strFuncName](strValue1, strValue2, strValue3, strValue4);
                        break;
                    default:
                        throw "More than 4 parameters is not supported.";
                        break;
                }
            }
        }
    }            
};

cs.forms.Common.restoreDefaultState = function(bo){
    for (strItemName in bo)
    {
        if (bo[strItemName]["restoreDefaultState"]!=undefined)
            bo[strItemName].restoreDefaultState();
    }
};

cs.forms.Common.setJSDOM = function(oattb, templateStr, configObj){
    var str = oattb.toLowerCase();
    switch (str)
    {
        case "onblur":
        case "onchange":
        case "onchange1": // TODO: Temporary by CS
        case "onselect":
        case "onfocus":
        case "onclick":
        case "ondblclick":
        case "scroll":
        case "allowtransparency":
        case "onkeypress":
        case "classname":
        case "border":
        case "cellspacing":
        case "cellpadding":
            templateStr[oattb]=configObj[oattb];
            break;

        // Extended function by CS Framework
        case "onenter":
            templateStr[oattb]=configObj[oattb];
            break;
            
        case "width":
        case "height":
        case "display":
            if (templateStr["style"]==undefined)
                templateStr["style"]=oattb+":"+configObj[oattb];
            else
                templateStr["style"]+=";"+oattb+":"+configObj[oattb];
            break;
            
        case "style":
            if (templateStr["style"]==undefined)
                templateStr["style"]=configObj[oattb];
            else
                templateStr["style"]+=";"+configObj[oattb];
            break;
    }
};

cs.forms.Common.setEnableBO = function(bo, bDisable){
    for (strName in bo)
    {
        var boItem = bo[strName];
        if (boItem.constructor==cs.forms.ControlBase)
        {
            boItem.setEnable(bDisable);
        }
    }
};

/**
 * ControlBase Class
 */
cs.forms.ControlBase = function(){
	/* Basic class attributes */
	this.className = "ControlBase";
};

cs.forms.ControlBase.prototype.init = function(initConfig){
	/* Specific class attributes */
    this._configuration = {};
    for (configName in initConfig)
    {
        this._configuration[configName]=initConfig[configName];
    }		
	this._click_event = new Array();
};

cs.forms.ControlBase.prototype.getElement = function(){
    var ele = document.getElementById(this.jsdom.id);
    if (ele!=undefined)
        return ele;
    else
        return null;
};

cs.forms.ControlBase.prototype.setEnable = function(bEnable)
{
    var ele = document.getElementById(this.jsdom.id);
    if (ele!=undefined)
        ele.disabled=!bEnable;

    this.jsdom.disabled = !bEnable;
}

cs.forms.ControlBase.prototype.clone = function(){
	cs.Debug.addTrace("LOG", "Cloning: " + this.className);
	// Check if the constructClass is defined
	if (this.constructClass!=undefined)
	{
    	var newThis = new this.constructClass(this._configuration);
	}
    cs.Debug.addTrace("LOG", "End of Cloning: " + this.className);
    return newThis;	
};

cs.forms.ControlBase.prototype.restoreDefaultState = function(){

    cs.Debug.addTrace("LOG", "Restore Default State" + this.className);

    if (this["setValue"]!=undefined)
    {
        if (this._configuration["defaultvalue"]!=undefined)
            this.setValue(this._configuration.defaultvalue);
            // Commented off by CS on 20080624, because ComboBox won't accept non-array value setting
            //        else
            //            this.setValue("");
    }
    if (this["clearForm"]!=undefined)
        this.clearForm();
};

cs.forms.ControlBase.prototype.fireEvent = function()
{
    for (var intEvent=0; intEvent<this._click_event.length; intEvent++)
    {
        this._click_event[intEvent]();
    }
};

cs.forms.ControlBase.prototype.attachClickEvent = function(func, opt)
{
    if (opt==undefined)
        opt = {};
        
    this._click_event.push(cs.CreateFunctionCallBack(func, opt.module));
    this.jsdom.onClick = cs.CreateFunctionApply(this.fireEvent, this);
    
	// Check if the element is there, if there is, set the value.
	var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
	{
	    eleNode.onClick = cs.CreateFunctionApply(this.fireEvent, this);
	}    
};

cs.forms.ControlBase.prototype.clearClickEvent = function()
{
    this._click_event.length = 0;
};

cs.forms.ControlBase.prototype.setOnClick = function(func, opt)
{
    if (opt==undefined)
        opt = {};
    
    this.clearClickEvent();
    this.attachClickEvent(func, opt);
};

cs.forms.ControlBase.prototype.focus = function()
{
	// Check if the element is there, if there is, focus on it.
	var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
	{
	    eleNode.focus();
	}
}

// TODO: need to check this
cs.forms.ControlBase.prototype.setOnKeyPress = function(func)
{
	var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
	{
	    eleNode.onkeypress = func;
	}
};

// TODO: need to check this
cs.forms.ControlBase.prototype.setOnEnter = function(objToWire, funcToWire, aarg)
{
	var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
	{

        var funcOnEnter = function( evt, frm )
        {
            var keyCode = null;
            
            if( evt.which )
            {
                keyCode = evt.which;
            } else if( evt.keyCode )
            {
                keyCode = evt.keyCode;
            }
            
            if( 13 == keyCode )
            {
                funcToWire.apply(objToWire, aarg);
                return false;
            }
            
            return true;
        }
        	
	    eleNode.setOnKeyPress(funcOnEnter);
	}
};

cs.forms.ControlBase.prototype.setClassName = function(strClass)
{
    var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
        eleNode.className = strClass;
    else
        this.jsdom.className = strClass;
};

cs.forms.ControlBase.prototype.setStyle = function(strStyle)
{
    var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
        pc.style.applyCSStoDOM(strStyle, eleNode);
    else
    {
        // the element is not rendered yet
        // Add the style to the jsdom
        if (this.jsdom.style==undefined)
            this.jsdom.style = strStyle;
        else
            this.jsdom.style += ";" + strStyle;
    }
}

/**
 * Generic HTML Control
 */
cs.forms.HTML = function(initConfig){
    this.className = "HTML";
    // TODO: check the argument first
    this.init(initConfig);
    this.jsdom = this._createJSDOM(initConfig);
};
cs.forms.HTML.prototype = new cs.forms.ControlBase();
cs.forms.HTML.prototype.constructClass = cs.forms.HTML;
cs.forms.HTML.prototype._createJSDOM = function(paramConfig){
	var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    if (configObj.tag==undefined)
    {
        cs.Debug.addTrace("ERR", "Tag attribute is not supplied for cs.forms.HTML config");
        return null;
    }
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid=this.className+intRnd+"t"+intRndTime;
    }
    
    var templateStr = {
            tag:configObj.tag,
            id:configObj.controlid
        };

    if (configObj.html!=undefined)
        templateStr.html = configObj.html;
                
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
}

/**
 * Generic HTML Control
 */
cs.forms.HTMLRef = function(initConfig){
    this.className = "HTMLRef";
    // TODO: check the argument first
    this.init(initConfig);
    this.jsdom = this._createJSDOM(initConfig);
};
cs.forms.HTMLRef.prototype = new cs.forms.ControlBase();
cs.forms.HTMLRef.prototype.constructClass = cs.forms.HTMLRef;
cs.forms.HTMLRef.prototype._createJSDOM = function(paramConfig){
	var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid=this.className+intRnd+"t"+intRndTime;
    }
    
    this.controlid = configObj.controlid;
    
    var templateStr = {
            tag:configObj.tag,
            id:configObj.controlid
        };

    if (configObj.html!=undefined)
        templateStr.html = configObj.html;
                
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
}
 

/**
 * Basic Controls 
 */

/**
 * Div
 **/
cs.forms.Div = function(initConfig){
    this.className = "Div";
    // TODO: check the argument first
    this.init(initConfig);
    this.jsdom = this._createJSDOM(initConfig);
};
cs.forms.Div.prototype = new cs.forms.ControlBase();
cs.forms.Div.prototype.constructClass = cs.forms.Div;
cs.forms.Div.prototype._createJSDOM = function(paramConfig){
	var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    if (configObj.tag==undefined)
    {
        configObj.tag="div";
    }
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid=this.className+intRnd+"t"+intRndTime;
    }
    
    var templateStr = {
            tag:configObj.tag,
            html:configObj.defaultvalue?configObj.defaultvalue:"",
            id:configObj.controlid
        };
        
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
}

    
/**
 * Span
 **/
cs.forms.Span = function(initConfig){
    this.className = "Span";
    // TODO: check the argument first
    this.init(initConfig);
    this.jsdom = this._createJSDOM(initConfig);
};
cs.forms.Span.prototype = new cs.forms.ControlBase();
cs.forms.Span.prototype.constructClass = cs.forms.Span;
cs.forms.Span.prototype._createJSDOM = function(paramConfig){
	var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    if (configObj.tag==undefined)
    {
        configObj.tag="span";
    }
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid="span"+intRnd+"t"+intRndTime;
    }
    
    var templateStr = {
            tag:configObj.tag,
            html:configObj.defaultvalue?configObj.defaultvalue:"",
            id:configObj.controlid
        };
        
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
}
cs.forms.Span.prototype.setValue = function(strValue)
{
	this.jsdom.html = strValue;
	
	// Check if the element is there, if there is, set the value.
	var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
	{
	    eleNode.innerHTML = strValue;
	}
}


    
/**
 * Script
 **/
cs.forms.Script = function(initConfig){
    this.className = "Script";
    // TODO: check the argument first
    this.init(initConfig);
    this.jsdom = this._createJSDOM(initConfig);
};
cs.forms.Script.prototype = new cs.forms.ControlBase();
cs.forms.Script.prototype.constructClass = cs.forms.Script;
cs.forms.Script.prototype._createJSDOM = function(paramConfig){
	var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    configObj.tag="script";
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid="script"+intRnd+"t"+intRndTime;
    }
    
    var templateStr = {
            tag:configObj.tag,
            id:configObj.controlid
        };
    
    if (configObj.src!=undefined)
        templateStr.src = configObj.src;
        
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
}
cs.forms.Script.prototype.setSrc = function(strSrc)
{
	this.jsdom.src = strSrc;
}
cs.forms.Script.prototype.setValue = function(strValue)
{
    this.jsdom.html = strValue;
}

/**
 * TextBox
 */
cs.forms.TextBox = function(initConfig){
	this.className = "TextBox";
    this.init(initConfig);
    this.jsdom = this._createJSDOM(initConfig);
}
cs.forms.TextBox.prototype = new cs.forms.ControlBase();
cs.forms.TextBox.prototype.constructClass = cs.forms.TextBox;

/**
 * Name        : _createJSDOM
 * Description : To create a textbox with call back
 * Revision    : 2007-11-21 v1.0 First Release
 *               2007-11-21 v1.1 Renamed to _createJSDOM
 * TODO        : Add overlay label feature
 **/
cs.forms.TextBox.prototype._createJSDOM = function(paramConfig)
{
    var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    if (configObj.tag==undefined)
        configObj.tag="INPUT";
    
    if (configObj.disabled==undefined)
        configObj.disabled = false;
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid="txt"+intRnd+"t"+intRndTime;
    }
    
    // TODO: have to validate if the type is in the acceptable values
    if (configObj.type==undefined)
    {
        configObj.type="text";
    }

    var templateStr = {
            tag:configObj.tag,
            type:configObj.type,
            value:configObj.defaultvalue?configObj.defaultvalue:"",
            id:configObj.controlid,
            name:configObj.controlid,
            disabled:configObj.disabled
        };
        
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
};

cs.forms.TextBox.prototype.setValue = function(strValue)
{
	this.jsdom.value = strValue;
	
	// Check if the element is there, if there is, set the value.
	var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
	{
	    eleNode.value = strValue;
	}
}

cs.forms.TextBox.prototype.getValue = function()
{
    var ele = document.getElementById(this.jsdom.id);
    if (ele == undefined)
        return this.jsdom.value;
    else
        return ele.value;
}

cs.forms.Image = function(initConfig){
    this.className = "Image";
    this.init(initConfig);
    this.jsdom = this._createJSDOM(initConfig);
};
cs.forms.Image.prototype = new cs.forms.ControlBase();
cs.forms.Image.prototype.constructClass = cs.forms.Image;
cs.forms.Image.prototype.setSrc = function(strSrc)
{
    this.jsdom.src = strSrc;
    var ele = document.getElementById(this.jsdom.id);
    if (ele!=undefined)
    {
        ele.src = strSrc;
    }
};
cs.forms.Image.prototype._createJSDOM = function(paramConfig)
{

	var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    if (configObj.tag==undefined)
    {
        configObj.tag="img";
    }
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid=configObj.tag+intRnd+"t"+intRndTime;
    }
    
    var templateStr = {
            tag:configObj.tag,
            src:configObj.src,
            id:configObj.controlid,
            name:configObj.controlid
        };
        
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
    
};

// IFRAME

cs.forms.IFrame = function(initConfig){
    this.className = "IFrame";
    this.init(initConfig);
    this.jsdom = this._createJSDOM(initConfig);
};
cs.forms.IFrame.prototype = new cs.forms.ControlBase();
cs.forms.IFrame.prototype.constructClass = cs.forms.IFrame;
cs.forms.IFrame.prototype.setSrc = function(strSrc)
{
    this.jsdom.src = strSrc;
    var ele=document.getElementById(this.jsdom.id);
    if (ele!=undefined)
    {
        ele.src = strSrc;
    }
};
cs.forms.IFrame.prototype._createJSDOM = function(paramConfig)
{

	var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    if (configObj.tag==undefined)
    {
        configObj.tag="iframe";
    }
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid=configObj.tag+intRnd+"t"+intRndTime;
    }
    
    var templateStr = {
            tag:configObj.tag,
            src:configObj.src,
            id:configObj.controlid,
            name:configObj.controlid
        };
        
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
};

cs.forms.IFrame.prototype.setOnLoad = function(funcOnLoad)
{
	this.jsdom.onload = funcOnLoad;
}


/**
 * JSHiddenField
 **/
cs.forms.JSHiddenField = function(initConfig){
    this.className = "JSHiddenField";
    // TODO: check the argument first
    this.init(initConfig);
    this.jsdom = this._createJSDOM(initConfig);
};
cs.forms.JSHiddenField.prototype = new cs.forms.ControlBase();
cs.forms.JSHiddenField.prototype.constructClass = cs.forms.JSHiddenField;

cs.forms.JSHiddenField.prototype._createJSDOM = function(paramConfig)
{
    return {};
};

cs.forms.JSHiddenField.prototype.setValue = function(strValue)
{
	this.jsdom.value = strValue;
}

cs.forms.JSHiddenField.prototype.getValue = function()
{
    return this.jsdom.value;
}

/**
 * CheckBox
 **/
cs.forms.CheckBox = function(initConfig){
    this.className = "CheckBox";
    // TODO: check the argument first
    this.init(initConfig);
    this.jsdom = this._createJSDOM(initConfig);    
}
cs.forms.CheckBox.prototype = new cs.forms.ControlBase();
cs.forms.CheckBox.prototype.constructClass = cs.forms.CheckBox;
        
cs.forms.CheckBox.prototype._createJSDOM = function(paramConfig)
{
    var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    configObj.tag="input";
    configObj.type="checkbox";
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid="cbx"+intRnd+"t"+intRndTime;
    }
    
    if (configObj.defaultvalue==undefined)
    {
        configObj.defaultvalue=false;
    }
    else if (configObj.defaultvalue.constructor!=Boolean)
    {
        cs.debugalert("Default value for checkbox must be Boolean");
    }
    
    if (configObj.disabled!=true)
    {
        configObj.disabled=false;
    }
    
    var templateStr = {
            tag:configObj.tag,
            checked:configObj.defaultvalue?configObj.defaultvalue:false,
            id:configObj.controlid,
            type:configObj.type,
            disabled:configObj.disabled
        };
        
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
};

cs.forms.CheckBox.prototype.setValue = function(bValue)
{
    if (bValue!=undefined && bValue.constructor!=Boolean)
    {
        cs.debugalert("setValue for CheckBox must be Boolean.");
        return;
    }
	this.jsdom.checked = bValue;
	
	// Check if the element is there, if there is, set the value.
	var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
	{
	    eleNode.checked = bValue;
	}
}

cs.forms.CheckBox.prototype.getValue = function()
{
    var eleNode = document.getElementById(this.jsdom.id);
    if (eleNode!=undefined)
        return eleNode.checked;
    else
        return this.jsdom.checked;
}

cs.forms.CheckBox.prototype.restoreDefaultState = function()
{
    if (this._configuration["checked"]!=undefined)
        this.setValue(this._configuration["checked"]);
    else
        this.setValue(false);
}


/**
 * Anchor
 **/
cs.forms.Anchor = function(initConfig){
        this.className = "Anchor";
        this.init(initConfig);
		this.jsdom = this._createJSDOM(initConfig);
}
cs.forms.Anchor.prototype = new cs.forms.ControlBase();
cs.forms.Anchor.prototype.constructClass = cs.forms.Anchor;

cs.forms.Anchor.prototype._createJSDOM = function(paramConfig)
{
    var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    if (configObj.tag==undefined)
    {
        configObj.tag="a";
    }
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid="a"+intRnd+"t"+intRndTime;
    }
    
    var templateStr = {
            tag:configObj.tag,
            html:configObj.defaultvalue?configObj.defaultvalue:"",
            id:configObj.controlid
        };

    if (configObj.href!=undefined)
        templateStr.href=configObj.href;
    
    if (configObj.target!=undefined)
        templateStr.target=configObj.target;
    
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
};

cs.forms.Anchor.prototype.setValue = function(strValue)
{
	this.jsdom.html = strValue;
	
	// Check if the element is there, if there is, set the value.
	var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
	{
	    eleNode.innerHTML = strValue;
	}
}

cs.forms.Anchor.prototype.setHref = function(strValue)
{
    this.jsdom.href = strValue;
	// Check if the element is there, if there is, set the value.
	var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
	{
	    eleNode.href = strValue;
	}
}

/**
 * TextArea
 */
cs.forms.TextArea = function(initConfig){
		this.className = "TextArea";
		this.init(initConfig);
		this.jsdom = this._createJSDOM(initConfig);
}

cs.forms.TextArea.prototype = new cs.forms.ControlBase();
cs.forms.TextArea.prototype.constructClass = cs.forms.TextArea;
        
/*
	Name        : _createJSDOM
	Description : To create a textbox with call back
	Revision    : 2007-11-21 v1.0 First Release
	              2007-11-21 v1.1 Renamed to _createJSDOM
	TODO        : Add overlay label feature
*/
cs.forms.TextArea.prototype._createJSDOM = function(paramConfig)
{
    var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    if (configObj.tag==undefined)
    {
        configObj.tag="textarea";
    }
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid="txa"+intRnd+"t"+intRndTime;
    }
    
    var templateStr = {
            tag:configObj.tag,
            html:configObj.defaultvalue?configObj.defaultvalue:"",
            id:configObj.controlid
        };
        
    if (configObj.disabled!=undefined)
    {
        templateStr.disabled=configObj.disabled;
    }   
                     
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
};

cs.forms.TextArea.prototype.setValue = function(strValue)
{
	this.jsdom.value = strValue;
	
	// Check if the element is there, if there is, set the value.
	var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
	{
	    eleNode.value = strValue;
	}
}

cs.forms.TextArea.prototype.getValue = function()
{
    var ele = document.getElementById(this.jsdom.id);
    if (ele == undefined)
        return this.jsdom.value;
    else
        return ele.value;
}

/**
 * Button 
 */            
cs.forms.Button = function(initConfig){
        this.className = "Button";
        this.init(initConfig)
        this.jsdom = this._createJSDOM(initConfig);            
}

cs.forms.Button.prototype = new cs.forms.ControlBase();
cs.forms.Button.prototype.constructClass = cs.forms.Button;
        
/*
Name        : _createJSDOM
Description : To create a button with call back
Revision    : 2007-11-21 v1.0 First Release
*/
cs.forms.Button.prototype._createJSDOM = function(configObj)
{
    this._originalConfigObj = configObj;
    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    if (configObj.tag==undefined)
    {
        configObj.tag="input";
    }
    
    if (configObj.defaultvalue==undefined)
    {
        configObj.defaultvalue="(Button)";
    }
    
    if (configObj.statevalue==undefined)
    {
        configObj.statevalue = {};
        configObj.statevalue.any = configObj.defaultvalue;
    }
    else if (configObj.statevalue.any==undefined)
    {
        configObj.statevalue.any = configObj.defaultvalue;
    }
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid="btn"+intRnd+"t"+intRndTime;
    }
    
    // TODO: have to validate if the type is in the acceptable values
    if (configObj.type==undefined)
    {
        configObj.type="button";
    }

    // Check if it is the correct config type and the version is acceptable
    /* commented until it is finalized
    if (!(configObj.configType=="formconfig"&&configObj.version>=1))
    {
        cs.debugalert("Invalid version of framework code is mixed.");
        return;
    }
    */
    
    var templateStr = {
            tag:configObj.tag,
            type:configObj.type,
            value:configObj.defaultvalue,
            id:configObj.controlid
        };

    if (configObj.disabled!=undefined)
    {
        templateStr.disabled=configObj.disabled;
    }
                        
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
};

cs.forms.Button.prototype.setState = function(strState, bEnable)
{
    if (bEnable != undefined)
    {
        this.setEnable(bEnable);
    }
    
    // Check for my state texts
    var strStateText = this._originalConfigObj.statevalue[strState];
    if (strStateText == undefined)
    {
        strStateText = this._originalConfigObj.statevalue.any;
    }
    this.setValue(strStateText);
}
  
cs.forms.Button.prototype.getValue = function()
{
    var ele = document.getElementById(this.jsdom.id);
    if (ele!=undefined)
        return ele.value;
    else
        return jsdom.value;
}

cs.forms.Button.prototype.setValue = function(strValue)
{
    this.jsdom.value = strValue;
    
    var ele = document.getElementById(this.jsdom.id);
    if (ele!=undefined)
        ele.value = strValue;
}

/**
 * ComboBox
 */
cs.forms.ComboBox = function(initConfig){
	this.className = "ComboBox";
	this.init(initConfig);
    this.jsdom = this._createJSDOM();
}
cs.forms.ComboBox.prototype = new cs.forms.ControlBase();
cs.forms.ComboBox.prototype.constructClass = cs.forms.ComboBox;
        
/*
Name        : _createJSDOM
Description : To create a combobox with call back
Revision    : 2007-11-21 v1.0 First Release
              2007-11-21 v1.1 Renamed to _createJSDOM
TODO        : Add overlay label feature
*/
cs.forms.ComboBox.prototype._createJSDOM = function()
{
    var configObj = {};

    for (configName in this._configuration)
    {
        configObj[configName]=this._configuration[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    if (configObj.tag==undefined)
        configObj.tag = "SELECT";
    
    if (configObj.multiple==undefined)
        configObj.multiple = false;
    
    if (configObj.options==undefined)
    {
        configObj.options = new Array();
    }
    
    var intRnd = parseInt((Math.random() * 10000) % 10000);
    var intRndTime = (new Date()).getMilliseconds();
    configObj.controlid="dll"+intRnd+"t"+intRndTime;

    var templateStr = {
            tag:configObj.tag,
            id:configObj.controlid,
            multiple:configObj.multiple,
            html:new Array()
        };

    if (configObj.disabled!=undefined)
    {
        templateStr.disabled=configObj.disabled;
    }
                        
    // Have to interprete the options
    for (var i=0; i<configObj.options.length; i++)
    {
        templateStr.html.push({tag:"option",
                label:configObj.options[i].text,
                html:configObj.options[i].text,
                value:configObj.options[i].value,
                selected:configObj.options[i].selected});
    }
    
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
};

cs.forms.ComboBox.prototype.setOptions = function(aOptions)
{
    //cs.debugalert("set options:" + cs.Debug.inspect(aOptions).join(""));
    
    // Verify that aOptions is in the correct format
    // Correct format: {text:"Label", value:"Value", selected:true}
    for (var i=0; i<aOptions.length; i++)
    {
        if (aOptions[i].text==undefined || aOptions[i].value==undefined)
        {
            cs.debugalert("Invalid option list set for combobox.");
            return false;
        }
        
        if (aOptions[i].selected==undefined)
            aOptions[i].selected=false;
    }
    
    this._configuration.options = aOptions;
    this.jsdom.html = new Array();
     
    // Have to interprete the options
    for (var i=0; i<aOptions.length; i++)
    {
        this.jsdom.html.push({tag:"option",
                label:aOptions[i].text,
                html:aOptions[i].text,
                value:aOptions[i].value,
                selected:aOptions[i].selected});
    }
    
    // Update also the real DOM if available
    var ddl = document.getElementById(this.jsdom.id);
    if (ddl!=undefined)
    {
        // Clear off the options
        while (ddl.options.length>0)
        	ddl.options[0] = null;

        // Add my options
        for (var intNewOpt=0; intNewOpt<aOptions.length; intNewOpt++)
        {
            ddl.options[ddl.options.length] = new Option(aOptions[intNewOpt].text,
                                                    aOptions[intNewOpt].value,
                                                    false,
                                                    aOptions[intNewOpt].selected);
        }
    }
    
    return undefined;
};

cs.forms.ComboBox.prototype.setValue = function(astrValue)
{
    //cs.debugalert("set value:" + astrValue);
    // We are accepting an array of values
    // TODO: need to filter out those values that is no in the options list
	this.jsdom.value = astrValue;
	
	//cs.debugalert("some one called me ComboBox setValue:" + astrValue);

	// Set the value in the yet to render jsdom
	for (var i=0; i<this.jsdom.html.length; i++)
	{
	    var op = this.jsdom.html[i];
	    if (op.tag=="option")
	    {
	        if (cs.getIndexInArray(astrValue, op.value)>-1)
	            op.selected = true;
	        else
	            op.selected = false;
	    }
	}
	
	// Check if the element is there, if there is, set the value.
	var ddl = document.getElementById(this.jsdom.id);
	if (ddl!=undefined)
	{
        for (var i=0; i<ddl.options.length; i++)
        {
            if (cs.getIndexInArray(astrValue, ddl.options[i].value)>-1)
                ddl.options[i].selected=true;
            else
                ddl.options[i].selected=false;
        }
	}
}

cs.forms.ComboBox.prototype.getValue = function()
{
    // Get the options and get the selected one
    var ddl = document.getElementById(this.jsdom.id);
    if (ddl!=undefined)
    {
        var astrSelected = new Array();
        for (var i=0; i<ddl.options.length; i++)
        {
            if (ddl.options[i].selected==true)
            {
                astrSelected.push(ddl.options[i].value);
            }
        }
        return astrSelected;
    }
    else
    {
        var astrSelected = new Array();
        for (var i=0; i<this.jsdom.html.length; i++)
        {
            var op = this.jsdom.html[i];
            if (op.tag=="option")
            {
                if (op.selected)
                {
                    astrSelected.push(op.value);
                }
            }
        }
        return astrSelected;      
    }
}
     
/**
 * Form Template Related Controls
 */
 
/**
 * Form and template elements
 */
cs.forms.Form = function(objFormItemCollection){
	this.className = "Form";
	
    /**
     * _formElements
     * Array to hold the form data elements
     **/
    this._formElements = {};
    
    /**
     * Name        : _positionMarker
     * Description : A string to hold the position marker ID
     **/
    this._startPositionMarkerID = null;
    this._endPositionMarkerID = null;
    
    /**
     * Name        : _templateJCSDOM
     * Description : Pointer to the tempalte JCSDOM
     **/
    this._templateJCSDOM = null;
    
    /**
     * Name        : _parentNode
     * Description : Pointer to the parent node element
     **/
    this._parentNode = null;
    
    // Initialization
    if (objFormItemCollection!=undefined)
    {
        for (feleName in objFormItemCollection)
        {
			cs.Debug.addTrace("CPT", "initializing new Form : " + feleName);
            this.addFormElement(feleName, objFormItemCollection[feleName]);
        }
    }
}
cs.forms.Form.prototype = new cs.forms.ControlBase();
cs.forms.Form.prototype.constructClass = cs.forms.Form;
                
cs.forms.Form.prototype.setPositionMarkerID = function(objMarkerID){
    this._startPositionMarkerID = objMarkerID.startID;
    this._endPositionMarkerID= objMarkerID.endID;
};
cs.forms.Form.prototype.getPositionMarkerID = function(){
    return {startID:this._startPositionMarkerID, endID:this._endPositionMarkerID};
}

cs.forms.Form.prototype.setTemplateJCSDOM = function(refJCSDOM){
    this._templateJCSDOM = refJCSDOM;
}
cs.forms.Form.prototype.getTemplateJCSDOM = function(){
    return this._templateJCSDOM;
}

cs.forms.Form.prototype.setParentNode = function(ele){
    this._parentNode = ele;
}
cs.forms.Form.prototype.getParentNode = function(){
    return this._parentNode;
}

/**
 * Name        : addFormElement
 * Description : Add form data element to the _formElements array
 **/
cs.forms.Form.prototype.addFormElement = function(strFormName, objFormElement){
    
    // TODO: Check if the objFormElement is valid
    if (objFormElement==undefined)
    {
        cs.debugalert("Error objFormElement is invalid");
    }
    this._formElements[strFormName]=objFormElement;
};

/**
 * Name        : removeFormElement
 * Description : Reform form data element from the _formElements array
 **/
cs.forms.Form.prototype.removeFormElement = function(strFormName)
{

    var bSuccess = false;
    
    // TODO: Check if the objFormElement is valid
    if (objFormElement==undefined)
    {
        cs.debugalert("Error objFormElement is invalid");
    }
    
    if (this._formElements[strFormName]!=undefined)
    {
        this._formElements[strFormName]=null;
        bSuccess=true;
    }
    
    return bSuccess;
    
};

/**
 * Name        : getElementByName
 * Description : Return the element by its name
 **/
cs.forms.Form.prototype.getElementByName = function(strElementName)
{
    return this._formElements[strElementName];
}

cs.forms.Form.prototype.getValue = function()
{
    cs.Debug.addTrace("LOG", "BEGIN: getValue for Form.");
    
    var dataArray = {};
    
    for (eleX in this._formElements)
    {
        cs.Debug.addTrace("Get value for element : " + eleX);
        if (this._formElements[eleX].getValue==undefined)
            cs.Debug.addTrace("getValue function not defined for element : " + eleX);
        else
            dataArray[eleX]=this._formElements[eleX].getValue();
    }

    cs.Debug.addTrace("LOG", "END: getValue for Form.");
    
    return dataArray;
};

cs.forms.Form.prototype.highlightDOM = function(color)
{
    if (color==undefined)
        color = "#F0F0F0";
        
    // First remove the DOM
	var myEleDOMParent = this.getParentNode();
	
	var intChildNodesNo = myEleDOMParent.childNodes.length;
	var intStartIndex = null;
	var intEndIndex = null;
	for (var intSeek=0; intSeek<intChildNodesNo; intSeek++)
	{
		if (myEleDOMParent.childNodes.item(intSeek).id==this._startPositionMarkerID)
		{
			intStartIndex=intSeek;
		}
		if (myEleDOMParent.childNodes.item(intSeek).id==this._endPositionMarkerID)
		{
			intEndIndex=intSeek;
		}
	}
	
	//cs.debugalert("Index : " + strObjMarkerID_startID + ":" + strObjMarkerID_endID);
	
	if (intStartIndex==null||intEndIndex==null)
	{
	    //cs.debugalert("Index not found: " + this._startPositionMarkerID + ":" + this._endPositionMarkerID);
		cs.Debug.addTrace("ERR", "Start Index and End Index not found.");
		return null;
	}
	else
	{
		for (var intSeek=intStartIndex; intSeek<=intEndIndex; intSeek++)
		{
			myEleDOMParent.childNodes.item(intSeek).style.backgroundColor=color;
		}
	}
	
	return undefined;
};

cs.forms.Form.prototype.setStyle = function(strStyle)
{
	// First remove the DOM
	var myEleDOMParent = this.getParentNode();
	
	var intChildNodesNo = myEleDOMParent.childNodes.length;
	var intStartIndex = null;
	var intEndIndex = null;
	for (var intSeek=0; intSeek<intChildNodesNo; intSeek++)
	{
		if (myEleDOMParent.childNodes.item(intSeek).id==this._startPositionMarkerID)
		{
			intStartIndex=intSeek;
		}
		if (myEleDOMParent.childNodes.item(intSeek).id==this._endPositionMarkerID)
		{
			intEndIndex=intSeek;
		}
	}
	
	
	if (intStartIndex==null||intEndIndex==null)
	{
	    //cs.debugalert("Index not found: " + this._startPositionMarkerID + ":" + this._endPositionMarkerID);
		cs.Debug.addTrace("ERR", "Start Index and End Index not found.");
		return null;
	}
	else
	{
	    //cs.debugalert("Index found: " + this._startPositionMarkerID + ":" + this._endPositionMarkerID);
		for (var intSeek=intStartIndex+1; intSeek<intEndIndex; intSeek++)
		{
		    pc.style.applyCSStoDOM(strStyle, myEleDOMParent.childNodes.item(intSeek));
		}
	}
	
	return undefined;
}

cs.forms.Form.prototype.removeDOM = function()
{
	// First remove the DOM
	var myEleDOMParent = this.getParentNode();
	
	var intChildNodesNo = myEleDOMParent.childNodes.length;
	var intStartIndex = null;
	var intEndIndex = null;
	for (var intSeek=0; intSeek<intChildNodesNo; intSeek++)
	{
		if (myEleDOMParent.childNodes.item(intSeek).id==this._startPositionMarkerID)
		{
			intStartIndex=intSeek;
		}
		if (myEleDOMParent.childNodes.item(intSeek).id==this._endPositionMarkerID)
		{
			intEndIndex=intSeek;
		}
	}
	
	//cs.debugalert("Index : " + strObjMarkerID_startID + ":" + strObjMarkerID_endID);
	
	if (intStartIndex==null||intEndIndex==null)
	{
	    //cs.debugalert("Index not found: " + this._startPositionMarkerID + ":" + this._endPositionMarkerID);
		cs.Debug.addTrace("ERR", "Start Index and End Index not found.");
		return null;
	}
	else
	{
		for (var intSeek=0; intSeek<=intEndIndex-intStartIndex; intSeek++)
		{
			myEleDOMParent.removeChild(myEleDOMParent.childNodes.item(intStartIndex));
		}
	}
	
	return undefined;
}

cs.forms.Form.prototype.clone = function()
{
    var newThis = new this.constructClass();
    for (strEleName in this._formElements)
    {
		cs.Debug.addTrace("LOG", "BEGIN Cloning: " + strEleName);
        try
        {
            newThis._formElements[strEleName]=this._formElements[strEleName].clone();
        }
        catch (e)
        {
            cs.Debug.addTrace("ERR", "Error at:\n\n" + strEleName + "\n\nCode:200712071512");
			return null;
        }
		cs.Debug.addTrace("LOG", "END cloning: " + strEleName)
    }
    return newThis;
}

    
/**
 * FormArray
 * A special array class to hold a form model
 * the model will be duplicated to create multipl forms
 **/
cs.forms.FormArray = function(objFormItemCollection){
	this.className = "FormArray";
    this._objFormItemCollection = objFormItemCollection;
    // Create and store a template for the repeater list
    this._myFormModel = new cs.forms.Form(objFormItemCollection);
    this._realForm = new Array();
}

cs.forms.FormArray.prototype = new cs.forms.ControlBase();
cs.forms.FormArray.prototype.constructClass = cs.forms.FormArray;

cs.forms.FormArray.prototype.getFormModel = function()
{
    return this._myFormModel;
}

cs.forms.FormArray.prototype.addNew = function(opts)
{
    if (opts==undefined)
    {
        opts = {bindObject:null, newIndex:null, referenceChild:null, insertPosition:null};

//        // Check this is a already binded form array
//        if (this.getElement()==undefined)
//        {
//            cs.debugalert("un defined!");
//        }
//        else
//        {
//            cs.debugalert("defined!");
//        }
    }
    
    cs.Debug.addTrace("CPT", "INVOKE: FormArray addNew");

	var newThis = null;
	
    if (opts.bindObject==undefined)
    {
        // Duplicate the form model
        newThis = this._myFormModel.clone();
    }
    else
    {
        cs.debugalert("Binding not implemented yet.");
    }

	if (opts.referenceChild!=undefined&&opts.insertPosition!=undefined)
	{
		var bProcessed = false;
		var intFindPos = 0;
		for (intFindPos = 0; intFindPos < this._realForm.length; intFindPos++)
		{
			cs.Debug.addTrace("LOG", "Checking " + intFindPos);
			if (this._realForm[intFindPos]==opts.referenceChild)
			{
				var intRealFormLength = this._realForm.length;
				if (opts.insertPosition=="insertBefore")
				{
					cs.Debug.addTrace("CHK", "Inserting Before");
					for (var intShift=intRealFormLength; intShift>intFindPos; intShift--)
					{
						this._realForm[intShift]=this._realForm[intShift-1];
					}
					this._realForm[intFindPos] = newThis;
					opts.newIndex = intFindPos;
				}
				else if (opts.insertPosition=="insertAfter")
				{
					cs.Debug.addTrace("CHK", "Inserting After");
					for (var intShift=intRealFormLength; intShift>intFindPos+1; intShift--)
					{
						this._realForm[intShift]=this._realForm[intShift-1];
					}
					this._realForm[intFindPos+1] = newThis;
					opts.newIndex = intFindPos+1;
				}
				bProcessed = true;
				break;
			}
		}
		
		if (bProcessed==false)
		{
			if (opts.referenceChild._ignoreReferenceBO==false)
			{
				cs.Debug.addTrace("ERR", "Not found " + opts.referenceChild.className)
			}
			else
			{
				opts.newIndex = this._realForm.length;
				this._realForm.unshift(newThis);
			}
		}
	}
	else
	{
        opts.newIndex = this._realForm.length;
        this._realForm.push(newThis);
	}
	cs.Debug.addTrace("CPT", "END: addNew");
    return newThis;
}

cs.forms.FormArray.prototype.removeFormByIndex = function(intFormIndex){
	this._realForm.splice(intFormIndex, 1);
}

cs.forms.FormArray.prototype.removeForm = function(objFormElement)
{
	var intIndexSeek = null;
	for (var i=0; i<this._realForm.length; i++)
	{
		if (this._realForm[i]==objFormElement)
		{
			intIndexSeek = i;
			break;
		}
	}
	if (intIndexSeek!=null)
		this._realForm.splice(intIndexSeek, 1);
	else
	{
		cs.Debug.addTrace("ERR", "Failed to find the form in this._realForm.");
		return false;
	}
	
	return undefined;
}

cs.forms.FormArray.prototype.clearForm = function()
{
    this._realForm.length = 0;
};

cs.forms.FormArray.prototype.clearFormAndDOM = function()
{
    for (var i=0; i<this._realForm.length; i++)
    {
        this._realForm[i].removeDOM();
    }
    this._realForm.length = 0;
};

cs.forms.FormArray.prototype.clone = function()
{
	cs.Debug.addTrace("LOG", "Cloning: " + "FormArray");
    var newThis = new this.constructClass(this._objFormItemCollection);
    return newThis;
}

cs.forms.FormArray.prototype.getForm = function(intFormIndex)
{
    return this._realForm[intFormIndex];
}

cs.forms.FormArray.prototype.getFormCount = function()
{
    return this._realForm.length;
}

cs.forms.FormArray.prototype.getValue = function(opt)
{
    var dataArray = new Array();
    var intRealFormCount = this._realForm.length;
    for (var intCnt=0; intCnt<intRealFormCount; intCnt++)
    {
        // Check if the selection checkbox is checked
        var objSelectionCheckBox = this._realForm[intCnt].getElementByName("selection");
        //cs.debugalert(cs.Debug.inspect(objSelectionCheckBox).join(""));
        if (objSelectionCheckBox==undefined||(objSelectionCheckBox.getValue()==true&&opt.selectedonly==true))
        {
            //cs.debugalert(cs.Debug.inspect(this._realForm[intCnt]).join(""));
            var newData = this._realForm[intCnt].getValue();
            dataArray.push(newData);
        }
    }
    return dataArray;
}

/**
 * FormTemplate Class
 **/
cs.forms.FormTemplate = function(strFormName, jcsdomTemplate){
	this.className = "FormTemplate";
    this._myName = strFormName;
    this._myJCSDOMTemplate = jcsdomTemplate;
}   
cs.forms.FormTemplate.prototype.getJCSDOMTemplate = function()
{
    return this._myJCSDOMTemplate;
}

cs.forms.FormTemplate.prototype.getTemplateName = function()
{
    return this._myName;
}

/**
 * FormTemplateItem
 **/    
cs.forms.FormTemplateItem = function(strParentName, strParentFieldName, strMyName, jcsdomTemplate, emptyTemplate){
    this.className = "FormTemplateItem";
    
    this._parentName = strParentName;
    this._parentFieldName = strParentFieldName;
    
    if (strMyName!=undefined)
    {
        this._myName = strMyName;
    }
    
    if (jcsdomTemplate!=undefined)
    {
        this._myJCSDOMTemplate = jcsdomTemplate;
    }
	
	if (emptyTemplate!=undefined)
	{
		this._emptyTemplate = emptyTemplate;
	}
}

cs.forms.FormTemplateItem.prototype.getParentName = function()
{
    return this._parentName;
}

cs.forms.FormTemplateItem.prototype.getParentFieldName = function()
{
    return this._parentFieldName;
}

cs.forms.FormTemplateItem.prototype.getJCSDOMTemplate = function()
{
    return this._myJCSDOMTemplate;
}

cs.forms.FormTemplateItem.prototype.getEmptyTemplate = function()
{
	return this._emptyTemplate;
}

cs.forms.FormTemplateItem.prototype.getTemplateName = function()
{
    return this._myName;
}            






/**
 * Graph
 **/
cs.forms.Graph = function(initConfig){
    this.className = "Graph";
    // TODO: check the argument first
    this.init(initConfig);
    this.jsdom = this._createJSDOM(initConfig);
};
cs.forms.Graph.prototype = new cs.forms.ControlBase();
cs.forms.Graph.prototype.constructClass = cs.forms.Graph;
cs.forms.Graph.prototype._createJSDOM = function(paramConfig){

	var configObj = {};
    for (configName in paramConfig)
    {
        configObj[configName]=paramConfig[configName];
    }
                    
    // Check if configObj is defined
    if (configObj==undefined)
    {
        // Create a default config object
        configObj = {configType:"formconfig",
                    version:1};
    }

    if (configObj.tag==undefined)
    {
        configObj.tag="div";
    }
    
    // TODO: have to validate if the controlid is valid in syntax
    if (configObj.controlid==undefined)
    {
        var intRnd = parseInt((Math.random() * 10000) % 10000);
        var intRndTime = (new Date()).getMilliseconds();
        configObj.controlid=configObj.tag+intRnd+"t"+intRndTime;
    }
    
    var templateStr = {tag:configObj.tag, style:"background-color:gray", id:configObj.controlid}
    
    if (configObj.defaultValue!=undefined)
        templateStr.html = this._constructGraph(configObj.defaultValue);
    
    // Add other attributes into the object
    for (oattb in configObj)
    {
        cs.forms.Common.setJSDOM(oattb, templateStr, configObj);
    }
    
    return templateStr;
};

cs.forms.Graph.prototype._constructGraph = function(gValue){

    // Expecting gValue as a 2D series
    
    // Normalise gValue to dValue
    var dValue = new Array();
    
    // Get the max
    var intMaxValue = 0;
    for (var intG=0; intG<gValue.length; intG++)
    {
        if (parseFloat(gValue[intG].value)>intMaxValue)
            intMaxValue = parseFloat(gValue[intG].value);
    }
    for (var intG=0; intG<gValue.length; intG++)
    {
        var cloneG = cs.cloneObject(gValue[intG]);
        cloneG.value = (parseFloat(cloneG.value) / intMaxValue) * 100;
        dValue.push(cloneG);
    }
    
    var aGraphBar = new Array();
    var aGraphLabel = new Array();
    for (var intGraphValue=0; intGraphValue<dValue.length; intGraphValue++)
    {
        aGraphBar.push({tag:"td", style:"width:12px", html:{tag:"div", style:"background-color:red; height:"+dValue[intGraphValue].value+"px; width:10px"}});
        aGraphBar.push({tag:"td", style:"width:12px", html:""});
        aGraphLabel.push({tag:"td", html:dValue[intGraphValue].label});
        aGraphLabel.push({tag:"td", style:"width:12px", html:""});
    }
    
    // Construct the graph jcsdom
    var templateStr = 
                [{tag:"table", style:"display:block; height:120px", cellpadding:0, cellspacing:0, html:[
                    {tag:"tr", style:"valign:bottom", html:[
                            {tag:"td", style:"width:30px", html:[
                                {tag:"div", style:"height:20px; width:10px; valign:top", html:Math.round(intMaxValue * 1 * 100) / 100},
                                {tag:"div", style:"height:20px; width:10px; valign:top", html:Math.round(intMaxValue * 0.8 * 100) / 100},
                                {tag:"div", style:"height:20px; width:10px; valign:top", html:Math.round(intMaxValue * 0.6 * 100) / 100},
                                {tag:"div", style:"height:20px; width:10px; valign:top", html:Math.round(intMaxValue * 0.4 * 100) / 100},
                                {tag:"div", style:"height:20px; width:10px; valign:top", html:Math.round(intMaxValue * 0.2 * 100) / 100},
                                {tag:"div", style:"height:10px; width:10px; valign:top", html:""},
                            ]},
                            aGraphBar
                        ]
                    },
                    {tag:"tr", style:"valign:bottom; height:20px", html:[
                            {tag:"td", html:""},
                            aGraphLabel
                        ]
                    }
                ]},
                {tag:"br"} // This is to fix firefox not setting the div according to the table size
                ];
            
    return templateStr;
};

cs.forms.Graph.prototype.setValue = function(gValue)
{
    var templateStr = this._constructGraph(gValue);
    
	this.jsdom.html = templateStr;
	
	// Check if the element is there, if there is, set the value.
	var eleNode = document.getElementById(this.jsdom.id);
	if (eleNode!=undefined)
	{
	    eleNode.innerHTML = "";
	    //cs.debugalert(cs.Debug.inspect(this.jsdom));
	    pc.appendJCSDOMtoJSDOM(this.jsdom, eleNode);
	    //cs.Debug.alertTrace();
	}
};