var FLForm = {

	eventSet : false,
	stores : {},
	TextFieldConfigs : {},
	TextFieldControls : {},
	TextAreaConfigs : {},
	TextAreaControls : {},
	DateFieldConfigs : {},
	DateFieldControls : {},
	NumberFieldConfigs : {},
	NumberFieldControls : {},
	ComboBoxConfigs : {},
	ComboBoxControls : {},
	TreeComboBoxConfigs : {},
	TreeComboBoxControls : {},
	UploadConfigs : {},
	Callbacks : {},

	registerTextField : function(config){
		FLForm.TextFieldConfigs[config.id] = config;
		if(config["tabOnEnter"])
		    FLForm.addTabOnEnter(config.id);
		FLForm.initForm();
	},
	
	registerTextArea : function(config){
		FLForm.TextAreaConfigs[config.id] = config;
		FLForm.addTabOnEnter(config.id, true);
		FLForm.initForm();
	},
	
	registerDateField : function(config){
		config["altFormats"] = "d/m/Y|dmY";
		FLForm.DateFieldConfigs[config.id] = config;
		FLForm.addTabOnEnter(config.id);
		FLForm.initForm();
	},

	registerNumberField : function(config){
		if (!config.decimalSeparator)
			config["decimalSeparator"] = ",";
		FLForm.NumberFieldConfigs[config.id] = config;
		FLForm.addTabOnEnter(config.id);
		FLForm.initForm();
	},
	
	registerComboBox : function(config){
		config["store"] = FLForm.stores[config.id];
        config["displayField"] = "text";
        config["valueField"] = "value";
		config["mode"] = "local";
		config["editable"] = config.editable? config.editable : false;
		config["triggerAction"] = "all";
		config["hiddenName"] = config.id + "_value";
		FLForm.ComboBoxConfigs[config.id] = config;
		FLForm.addTabOnEnter(config.id);
		FLForm.initForm();
	},
	registerTreeComboBox : function(config){
	    FLForm.TreeComboBoxConfigs[config.id] = config;
	    FLForm.addTabOnEnter(config.id);
	    FLForm.initForm();
	},
	registerUpload : function(id, config){
	    var obj = document.getElementById(id);
	    FLForm.addEvent(obj, 'change', function(e){ FLForm.submitUpload(e.target? e.target : e.srcElement); });
		FLForm.UploadConfigs[id] = config;
	},
	
	registerStore : function(id, data){
		FLForm.stores[id] = data;
	},

	initForm : function(){
		if (FLForm.eventSet)
			return;
		FLForm.eventSet = true;
		Ext.QuickTips.init();
		Ext.form.Field.prototype.msgTarget='side';
		if (window.Sys && window.Sys.WebForms && window.Sys.WebForms.PageRequestManager){
			var prm = Sys.WebForms.PageRequestManager.getInstance();
			if (prm != null)
				prm.add_endRequest(FLForm.init);
		}
		Ext.EventManager.onDocumentReady(FLForm.init, FLForm, true);
	},
	
	init : function(){
		for (var id in FLForm.TextFieldConfigs)
			FLForm.initControl(id, 'text_field');
		for (var id in FLForm.TextAreaConfigs)
			FLForm.initControl(id, 'text_area');
		for (var id in FLForm.DateFieldConfigs)
			FLForm.initControl(id, 'date_field');
		for (var id in FLForm.NumberFieldConfigs)
			FLForm.initControl(id, 'number_field');
		for (var id in FLForm.ComboBoxConfigs)
			FLForm.initControl(id, 'combobox');
		for (var id in FLForm.TreeComboBoxConfigs)
			FLForm.initControl(id, 'treecombobox');
	},
		
	initControl : function(id, type){
		var config = FLForm.getConfig(id);
		var el = document.getElementById(config.id);
		
		if (el == null)
			return;
        
		if (el.style.display != "none"){
			var con = FLForm.getControl(config.id);
			if (con != null){
				con.rendered = false;
				if (type == 'combobox'){
					if (!con.listWidth)
						con.listWidth = 250;
					var cboValue = document.getElementById(config.hiddenName);
					con.setValue(cboValue.value);
				}else
					con.setValue(el.value);
					
				con.applyTo(config.id);
				con.syncSize();
				con.setSize(con.width);
			}else switch (type){
				case 'text_field'  : FLForm.initTextField(config);   break;
				case 'text_area'   : FLForm.initTextArea(config);    break;
				case 'date_field'  : FLForm.initDateField(config);   break;
				case 'number_field': FLForm.initNumberField(config); break;
				case 'combobox'    : FLForm.initComboBox(config);    break;
				case 'treecombobox': FLForm.initTreeComboBox(config);break;
			}
		}
	},
	
	addTabOnEnter : function(id, isTextArea){
	    var el = document.getElementById(id);
	    if(!el)
	        return;
	    el.nextControl = el;
	    el.updateNextControl = true;
		FLForm.setNextControl(el);
		if(!isTextArea)
		    FLForm.addEvent(el, 'keydown', FLForm.tabOnEnter);
	},
	addEvent : function(obj, ev, fn, none){
	    if (obj.addEventListener)
		    obj.addEventListener(ev, fn, none);
	    else if (obj.attachEvent)
		    obj.attachEvent('on' + ev, fn);
    },
	
	setNextControl : function(field){
        for (i = 0; i < field.form.elements.length; i++) 
            if (field.form.elements[i].updateNextControl) 
                break; 
        if(field.form.elements[i].nextControl == field)
            return;
        field.form.elements[i].nextControl = field;
        field.form.elements[i].updateNextControl = false;
	}, 
	
	tabOnEnter : function(e){   
	    var el = e.target? e.target : e.srcElement;
	    var ctrl = FLForm.getControl(el.id);
	    
	    if (e.keyCode != 13 || el.updateNextControl || (ctrl.list && ctrl.list.visible))
	        return; 
	        
	    if(ctrl.mimicBlur)
            ctrl.mimicBlur();
	            
        if(navigator.appName.indexOf('Internet Explorer') > 0)
        {
            e.keyCode = 9;
            return;
        }
        e.preventDefault();
        e.stopPropagation();
        window.setTimeout(function() {
        el.nextControl.focus();
        }, 200);
	},
	
	initTextField : function(config){
		var newField = new Ext.form.TextField(config);
		FLForm.TextFieldControls[config.id] = newField;
		newField.applyTo(config.id);
		if(config.autoTrim)
		    newField.getEl().autoTrim = config.autoTrim;
		FLForm.configureIsLabel(newField, config);
		if(config.onBlur)
		    FLForm.addEvent(newField.el.dom, 'blur', config.onBlur);
		if(config.onKeyPress)
		    FLForm.addEvent(newField.el.dom, 'keypress', config.onKeyPress);
	},
	
	initTextArea : function(config){
		var newField = new Ext.form.TextArea(config);
		FLForm.TextAreaControls[config.id] = newField;
		newField.applyTo(config.id);
		if(config.autoTrim)
		    newField.getEl().autoTrim = config.autoTrim;
		FLForm.configureIsLabel(newField, config);
	},
	
	initDateField : function(config){
		var newField = new Ext.form.DateField(config);
		FLForm.DateFieldControls[config.id] = newField;
		newField.applyTo(config.id);
		if(config.onBlur)
		    FLForm.addEvent(newField.el.dom, 'blur', config.onBlur);
		if(config.onChange)
		    newField.on('change', config.onChange);
		FLForm.configureIsLabel(newField, config);
	},
	
	initNumberField : function(config){
		var newField = new Ext.form.NumberField(config);
		FLForm.NumberFieldControls[config.id] = newField;
		newField.applyTo(config.id);
		newField.reset();
		FLForm.configureIsLabel(newField, config);
	},
	
	initComboBox : function(config){
		var fields = ['value','text'];
		var store = FLForm.stores[config.id];
		config.store = new Ext.data.SimpleStore({fields:fields,data:store});
		var newField = new Ext.form.ComboBox(config);
		FLForm.ComboBoxControls[config.id] = newField;
		newField.applyTo(config.id);
		if (config.onClientSelectedIndexChanged)
			newField.addListener("select", config.onClientSelectedIndexChanged);
		if (config.postBackFunction)
			newField.addListener("select", FLForm.selectedIndexChanged, FLForm);
		FLForm.configureIsLabel(newField, config);
        if(config.onKeyPress)
		    FLForm.addEvent(newField.el.dom, 'keypress', config.onKeyPress);
	},
	initTreeComboBox : function(config){
		var newField = new Ext.form.TreeComboBox(config);
		FLForm.TreeComboBoxControls[config.id] = newField;
		newField.applyTo(config.id);
		if (config.onClientSelectionChanged)
			newField.on("select", config.onClientSelectionChanged);
		FLForm.configureIsLabel(newField, config);
	},
	configureIsLabel : function(control, config){
	    control.setIsLabel = function(isLabel){
		    if(config.isLabel == isLabel)
		        return;
		        
		    config.isLabel = isLabel;
		    
		    this.allowBlank = true;
		    this.setVisible(!isLabel);
		    this.clearInvalid();
		    if(isLabel)
		    {
		        var txt = document.getElementById(this.id);
		        var lbl = document.createElement("div");
		        lbl.setAttribute("id",  this.id +"_lbl");
		        if(config.toolTip)
		            lbl.setAttribute("title", config.toolTip);
		        lbl.style.minHeight = "18px";
		        lbl.style._height = "18px";
		        lbl.style.paddingTop = "4px";
		        lbl.innerHTML = txt.value.split("\n").join("<br />");
		        if(this.triggerClass)
		            txt.parentNode.parentNode.appendChild(lbl);
		        else
		            txt.parentNode.appendChild(lbl);
		    }
		    else
		    {
		        var lbl = document.getElementById(this.id + '_lbl');
		        if(lbl)
		            lbl.parentNode.removeChild(lbl);
		        if(typeof config.allowBlank == 'undefined')
		            config.allowBlank = true;
		        this.allowBlank = config.allowBlank;
		    }
		};
	    control.getIsLabel = function(){ return config.isLabel; };
		if(config.isLabel) {
		    config.isLabel = false;
		    control.setIsLabel(true);
		}
	},
	
	selectedIndexChanged : function(control, record, index){
		var fn = FLForm.getConfig(control.id).postBackFunction;
		eval(fn);
	},
	
	get : function(id){
		return FLForm.getControl(id);
	},
	
	getControl : function(id){
		var lst = FLForm.getAllControls();
		return lst[id];
	},
	
	getConfig : function(id){
		var lst = FLForm.getAllConfigs();
		return lst[id];
	},
	
	getValue : function(id){
		var control = FLForm.getControl(id);
		if (control.getValue)
			return control.getValue();
		else if (control.value)
			return control.value;
		return null;
	},
	
	getAllControls : function(){
	    var lst = {};
		for (var id in FLForm.TextFieldControls)
			lst[id] = FLForm.TextFieldControls[id];
		for (var id in FLForm.TextAreaControls)
			lst[id] = FLForm.TextAreaControls[id];
		for (var id in FLForm.DateFieldControls)
			lst[id] = FLForm.DateFieldControls[id];
		for (var id in FLForm.NumberFieldControls)
			lst[id] = FLForm.NumberFieldControls[id];
		for (var id in FLForm.ComboBoxControls)
			lst[id] = FLForm.ComboBoxControls[id];
		for (var id in FLForm.TreeComboBoxControls)
			lst[id] = FLForm.TreeComboBoxControls[id];
		return lst;
	},
	
	getAllConfigs : function(){
		var lst = {};
		for (var id in FLForm.TextFieldConfigs)
			lst[id] = FLForm.TextFieldConfigs[id];
		for (var id in FLForm.TextAreaConfigs)
			lst[id] = FLForm.TextAreaConfigs[id];
		for (var id in FLForm.DateFieldConfigs)
			lst[id] = FLForm.DateFieldConfigs[id];
		for (var id in FLForm.NumberFieldConfigs)
			lst[id] = FLForm.NumberFieldConfigs[id];
		for (var id in FLForm.ComboBoxConfigs)
			lst[id] = FLForm.ComboBoxConfigs[id];
		for (var id in FLForm.TreeComboBoxConfigs)
			lst[id] = FLForm.TreeComboBoxConfigs[id];
		return lst;
	},

	validate : function(){
	    var lst = FLForm.getAllControls();
		if (arguments.length > 0)
		{
		    var itens = {};
		    for (var x=0;x< arguments.length;x++)
		          itens[arguments[x]] = lst[arguments[x]];
		    lst = itens;
		}
		var isValid = true;
		for (var id in lst)
			if (!lst[id].validate())
				isValid = false;
		return isValid;
	},
	updateComboBox : function(id, args, fn){
	    FLForm.Callbacks[id] = fn;
	    CallbackManager.callback(args, FLForm.updateCbo, id);
	},
	updateCbo : function(rs){
	    var id = rs['__FLComboBox_ID'];
	    FLForm.registerStore(id, eval(rs["__FLComboBox_STORE"]));
		var cbo = FLForm.getControl(id);
		cbo.store.removeAll();
		cbo.store.loadData(FLForm.stores[id]);
		var fn = FLForm.Callbacks[rs['targetObjectID']];
		if (fn){
			FLForm.Callbacks[rs['targetObjectID']] = null;
			if (typeof(fn) == "function")
				fn(rs);
			else
				eval(fn + "(rs)");
		}
	},
	
	getFile : function(id){
	    var value = document.getElementById(id).value;
	    if(value.lastIndexOf("\\") != -1)
		        value = value.substr(value.lastIndexOf("\\")+1);
		return value;
	},
	
	getFrameUpload : function(c, controlId) {

        var n = 'f' + Math.floor(Math.random() * 99999);
        var d = document.createElement('DIV');
        
        d.innerHTML = '<iframe style="display:none" src="about:blank" id="'+n+'" name="'+n+'" onload="FLForm.frameLoaded(\''+n+'\', \''+controlId+'\')"></iframe>';
        document.body.appendChild(d);

        var i = document.getElementById(n);
        
        if (typeof(c.onComplete) == 'function')
            i.onComplete = c.onComplete;
            
        return n;
    },
    
    submitUpload : function(control) {
            if(control.value == '')
                return;
                
            FLForm.UploadConfigs[control.id]['uploading'] = true;
            var c = FLForm.UploadConfigs[control.id];
            var f = control.form;
            f.setAttribute('target', FLForm.getFrameUpload(c, control.id));
            
            var submit = true;
            if (typeof(c.onStart) == 'function' && c.onStart() == false)
                submit = false;
                
            if(!submit)
                return;
                
            control.style.display = 'none';
            document.getElementById(control.id + '_img').style.display = '';
            control.form.submit();
    },
    
    frameLoaded : function(id, controlId) {
        var i = document.getElementById(id);
        var d;
        if (i.contentDocument)
            d = i.contentDocument;
        else if (i.contentWindow)
            d = i.contentWindow.document;
        else
            d = window.frames[id].document;
        
        if (d.location.href != "about:blank" && typeof(i.onComplete) == 'function')
            i.onComplete(d.body.innerHTML);
            
        document.getElementById(controlId + '_img').style.display = 'none';
        document.getElementById(controlId).style.display = '';
        FLForm.UploadConfigs[controlId]['uploading'] = false;
    },
    isUploading : function(id){
        return FLForm.UploadConfigs[id]['uploading'];
    }
};
