/* (c) Jean Luc Biellmann - Groupe Ressources - 2010  */

var FormCtrl = Class.create(JS,{
	initialize : function ($super) { 
		$super();
		this.fields = {};	
		this.datas = {};	
		this.tabIndex = [];	
		this.obsChg = [];	
		this.xtpl = {};
	},
	setField : function (params) {
		var args = params.split(',');
		var field = {};
		field['id'] = args.shift();
		field['type'] = args.shift();
		if (field['type']=='T[]') {
			field['sizemin'] = args.shift();
			field['sizemax'] = args.shift();
		}		
		if (field['type']=='T' || field['type']=='T[]') {
			field['min'] = args.shift();
			field['max'] = args.shift();
			field['subset'] = args.shift();
			field['options'] = args.shift();
		}
		this.fields[field.id] = field;
		this.tabIndex.push(field['id']);
		if (field['type']=='T' || field['type']=='T[]') {
			this.obsChg.push(field['id']);
		}
	},
	setData : function (id,data) {
		if ($(id)) {
			var obj = $(id);
			var value = String(data).escapeHTML();
			switch(obj.nodeName) {
				case 'INPUT':
					if (obj.type=='text') // never set a password field !
						obj.value = value;
					// take care : for radio and checkbox, we always have an array...
					if (obj.type=='radio' || obj.type=='checkbox') {
						var vals = value.split(',');
						$$('input[type="'+obj.type+'"][name="'+obj.name+'"]').each(function (obj) {
							obj.checked = (vals.inArray(String(obj.value).escapeHTML()) ? true : false);
						});
					}
					break;
				case 'TEXTAREA':
					obj.value = value;
					break;
				case 'SELECT':
					if (obj.type=='select-one')
						obj.select('option').each(function (opt) {
							opt.selected = (opt.value==value ? 'selected' : '');
						});
					if (obj.type=='select-multiple') {
						if (typeof(data)!='Object') 
							obj.select('option').each(function (opt) {
								opt.selected = (opt.value==value ? 'selected' : '');
							});
						else
							obj.select('option').each(function (opt) {
								if ($A(data).inArray(opt.value))
								opt.selected = ($A(data).inArray(opt.value) ? 'selected' : '');
							});
					}
					break;
				case 'LABEL':
				case 'SPAN':
				case 'DIV':
					obj.update(value);
					break;
			}
			if (obj.type && obj.type!='password') 
				_Cookie.set(id,data); // setData should be called on init
			
			this.datas[id] = data;
		}
	},
	setNotEmpty : function () {
		$H(this.fields).values().each(function (field) {
			if (field['min']>0) {// || (field['type']=='T[]' && field['sizemin']>0)) {
				if ($$('label[for="'+field['id']+'"]').length==0)
					_Main.err('No label for '+field['id']);
				var label = $$('label[for="'+field['id']+'"]')[0];
				label.insert({after:E('span').update(' *').addClassName('tahoma red')});
			}
		});
	},
	setDate : function (id,value) { // for Calendar returns
		var date1 = '';
		switch (lang) {
			case 'fr':
			case 'de':
				date1 = value.substr(6,2)+'/'+value.substr(4,2)+'/'+value.substr(0,4);
				break;
			case 'en':
				date1 = value.substr(0,4)+'/'+value.substr(4,2)+'/'+value.substr(6,2);
				break;
		}
		this.setData(id,date1);
	},
	getDataId : function (id) {
		// $F is ONLY for non multiple select !!!
		if (id && $(id) && $(id).disabled==false) {
			var obj = $(id);	
			switch(obj.nodeName) {
				case 'INPUT':
					if (obj.type=='text' || obj.type=='password')
						this.datas[id] = String(obj.value);
					if ((obj.type=='checkbox' || obj.type=='radio')) { 
						// take care : for radio and checkbox, we always return an array...
						this.datas[id] = []; 
						$$('input[type="'+obj.type+'"][name="'+obj.name+'"]:checked').each((function (obj) {
							this.datas[id].push(String(obj.value));
						}).bind(this));
					}
					break;
				case 'TEXTAREA':
					this.datas[id] = String(obj.value);
					break;
				case 'SELECT': 
					// always return an array
					this.datas[id] = [];
					obj.select('option:selected').each((function (obj) {
						this.datas[id].push(String(obj.value));
					}).bind(this));
					break;
			}			
			return this.datas[id];
		}
		return null;
	},
	getData : function (obj) {
		return this.getDataId(obj.id);
	},
	chkFieldSizeText : function (label,field,data) {
		if (field['min']>0 && !data.length)
			return _Lang.tr('FORM_CTRL__FIELD_EMPTY',label);
		if (data.length<field['min']) 
			return _Lang.tr('FORM_CTRL__FIELD_MIN_CHARS',label,field['min']);
		if (data.length>field['max'])
			return _Lang.tr('FORM_CTRL__FIELD_MAX_CHARS',label,field['max']);
		return '';
	},
	chkFieldSize : function (label,field,data) {
		var errors;
		switch (field['type']) {
			case 'T':
				return this.chkFieldSizeText(label,field,data);
				break;
			case 'T[]':
				if (data.length<field['sizemin'])
					return _Lang.tr('FORM_CTRL__FIELD_ARR_SIZE_MIN',label,field['sizemin']);
				if (data.length>field['sizemax']) 
					return _Lang.tr('FORM_CTRL__FIELD_ARR_SIZE_MAX',label,field['sizemax']);
				$A(data).each((function (row) {
					var err = this.chkFieldSizeText(label,field,row);
					if (err.length)
						return err;
				}).bind(this));
				break;
			default:
				return _Lang.tr('FORM_CTRL__FIELD_UNKNOW_TYPE',label);
		}		
		return '';
	},
	unknow : function (label) {
		return _Lang.tr('FORM_CTRL__FIELD_UNKNOW',label);
	},
	chkFieldSubset : function (label,field,data) {
		// ALPHABET is set from LANG
		var subsets = {
			'alpha' : _Lang.tr('ALPHABET'),
			'alphanum' : _Lang.tr('ALPHABET')+'0-9',
			'alphanumspace' : _Lang.tr('ALPHABET')+'0-9\\ ',
			'unsigned' : '0-9',
			'int' : '0-9\\-',
			'float' : '0-9\\.\\,\\-',
			'civ' : _Lang.tr('ALPHABET')+'\\.',
			'fn' : _Lang.tr('ALPHABET')+'\\-\\ ',
			'ln' : _Lang.tr('ALPHABET')+'\\-\\ \\\'',
			'adr' : _Lang.tr('ALPHABET')+'0-9\\-\\ \\"\\\'\\,\\.\\r\\n',
			'cty' : _Lang.tr('ALPHABET')+'\\ ',
			'url' : 'a-zA-Z0-9\\:\\/\\.\\-',
			'zip' : 'A-Z\\-0-9',
			'city' : _Lang.tr('ALPHABET')+'\\(\\)\\-\\ \\\'',
			'tel' : '0-9\\+\\.\\ \\-\\(\\)',
			'email' : 'a-zA-Z0-9\\.\\-\\_\\@',
			'pass' : _Lang.tr('ALPHABET')+'a-zA-Z0-9\\.\\-\\_\\@',
			'state' : _Lang.tr('ALPHABET')+'\\-',
			'comp' : _Lang.tr('ALPHABET')+'0-9\\(\\)\\-\\ \\\'',
			'role' : _Lang.tr('ALPHABET')+'\\(\\)\\-\\ \\\'',
			'text' : _Lang.tr('ALPHABET')+'0-9\\!\\?\\/\\-\\ \\\'\\_\\,\\:\\;\\.\\t\\r\\n\\&\\~\\#\\{\\(\\[\\|\\`\\ç\\@\\)\\]\\=\\+\\$\\%\\µ\\*\\²\\<\\>'
		};
		var str = String(data);
		if ($H(subsets).keys().inArray(field['subset'])) {			
			if (field['subset']=='date') {
				switch (lang) {
					case 'fr':
					case 'de':
						if (!value.match(new RegExp('^[0-3][0-9]/[0-1][0-9]/20[0-1][0-9]$','g')))
							return _Lang.tr('FORM_CTRL__FIELD_BAD_DATE');
						break;
					case 'en':
						if (!value.match(new RegExp('^20[0-1][0-9]/[0-1][0-9]/[0-3][0-9]$','g')))
							return _Lang.tr('FORM_CTRL__FIELD_BAD_DATE');
				}			
			} else {
				var subset = subsets[field['subset']];
				var re1 = new RegExp('^['+subset+']*$');
				var re2 = new RegExp('[^'+subset+']*','gi');
				if (!str.match(re1)) {
					this.setData(field['id'],str.replace(re2,''));
					return _Lang.tr('FORM_CTRL__FIELD_CLEAN_CHARS',_Lang.tr(field['id']));
				}
			}
		}		
		return '';
	},
	chkField : function (e) {
		var obj = Event.element(e);
		var id = this.getElementId(obj);
		if (id!=null) {
			this.getDataId(id);
			var err = this.chkFieldId(id);
			if (err.length)
				return _Main.err(err);
			_Cookie.set(id,this.datas[id]);
		}
	},
	chkFieldObj : function (obj) {
		return this.chkFieldId(this.getElementId(obj));
	},
	chkFieldId : function (id) {
		var fields,field,data,label;
		var err = '';
		fields = $H(this.fields).keys();
		if (!fields.inArray(id))
			return this.unknow(id);
		field = this.fields[id];
		if (field['type']=='X') // don't check eXtra fields...
			return '';
		data = this.datas[id];
		label = _Lang.tr(this.getLabelId(id));
		// CHECK SIZE
		err = this.chkFieldSize(label,field,data);
		if (err.length)
			return err;
		// CHECK SUBSETS
		err = this.chkFieldSubset(label,field,data);
		if (err.length)
			return err;
		// CHECK TYPE
		// on php side...
		return '';
	},
	chkDatas : function () {
		for (var id in this.fields) {
			this.getDataId(id);
			var err = this.chkFieldId(id);
			if (err.length) 
				return _Main.err(err);
		}
		return true;
	},
	getLabelId : function (id) {
		return $$('label[for="'+id+'"]').length ? $$('label[for="'+id+'"]')[0].innerHTML : '';
	},
	getLabelFor : function (obj) {
		return this.getLabelId(this.getElementId(obj));
	},
	getElementId : function (obj) {
		if (obj.id)
			return obj.id;
		switch(obj.nodeName) {
			case 'INPUT':
				return $$('input[type="'+obj.type+'"][name="'+obj.name+'"]').pluck('id').join('');
				break;
			case 'OPTION':
				return obj.previous('select').id;
				break;
		}	
		return null;
	},
	setObserveId : function (id) {
		if ($(id) && $(id).descendantOf(this.formId)) {
			var obj = $(id);
			if (obj.nodeName=='INPUT' && (obj.type=='checkbox' || obj.type=='radio'))
				$$('input[type="'+obj.type+'"][name="'+obj.name+'"]').each((function (obj) {
					Event.observe(obj,'change',this.chkField.bind(this));
				}).bind(this));
			else
				Event.observe(obj,'change',this.chkField.bind(this));	
		}
	},
	setObserve : function () {
		$A(this.obsChg).each((function (id) {
			this.setObserveId(id);
		}).bind(this));			
	},
	setTabIndex : function () {
		// IE bug (again) : need to force tabIndex instead of tabindex. Both syntax works on FireFox/Iceweasel..
		// http://o.dojotoolkit.org/forum/dojo-core-dojo-0-9/dojo-core-support/dojo-query-tabindex-not-working-me-ie
		var i=1;
		$A(this.tabIndex).each((function (id) {
			if ($(id) && $(id).descendantOf(this.formId)) {
				var obj = $(id);
				if (obj.nodeName=='INPUT' && (obj.type=='checkbox' || obj.type=='radio')) 
					$$('input[type="'+obj.type+'"][name="'+obj.name+'"]').each(function (obj) {
//console.log(obj.type+':'+obj.name);
						S($(obj),{'tabIndex':i++});
					});
				else
					S(obj,{'tabIndex':i++});
			}
		}).bind(this));
	},
	setDatas : function (fieldsIds,datas,fromCookie) {
		if ($(this.formId))
			$(this.formId).getElements().each(function (obj) {
				//var id = this.getElementId(obj);
				if (obj.id && fieldsIds.inArray(obj.id)) {
					var val = null;
					if (datas[obj.id] && datas[obj.id].length)
						val = datas[obj.id];
					else
						// retrieve datas from cookie
						if (fromCookie)
							val = _Cookie.get(obj.id);
//console.log('setDatas:'+obj.id+':'+val);
					if (val!=null && val.length)
						this.setData(obj.id,val);
				}
			}.bind(this));
	}
});

// tric from http://constc.blogspot.com/2008/07/undeclared-undefined-null-in-javascript.html
function isUndefined(x) {var u; return x === u;}


