/********************************************************\
	These functions handle common form functionality.
	The "dcs_" prefix exists to prevent conflicts.
\********************************************************/

/**** text field default values ****/
	document.observe("dom:loaded", function(){
		dcs_initDefaultValues();
	});
	function dcs_initDefaultValues() {
		var a = $A($$('input["defaultvalue"]','textarea["defaultvalue"]'));
		a.each(function(e){
			dcs_setDefaultValue(e);
			dcs_setDefaultValueEvents(e);
		});
	}
	function dcs_setDefaultValueEvents(e) {
		e.observe('focus', function(){dcs_clearDefaultValue(e)});
		e.observe('blur', function(){dcs_setDefaultValue(e)});
	}
	function dcs_setDefaultValue(e) {
		if(e.value.blank()) e.value = e.readAttribute('defaultvalue');
	}
	function dcs_clearDefaultValue(e) {
		if(e.value == e.readAttribute('defaultvalue')) e.select();
	}

/**** validation ****/
	function dcs_validate(settings) {
		/*
		settings -- object, not required:
			
			long name	|	short name	|	info
			=============================================================================================================================================
			form				f			--	string
												- value is the ID of the form
			
			return_only			ro			--	boolean, default FALSE unless form_id is not set, then forced to TRUE regardless of setting
												- if FALSE will submit the form if valid and return false to prevent default behaviour
												- if TRUE will not submit the form but return is_valid value (true/false)
			
			required	 		r			--	single string or array of strings
												- values are the IDs of required fields
												- currently supports: text, textarea, and select(value of 0 or "" counted as invalid, all others valid)
												- SPECIAL VALUES (strings, may be included in array - i.e. check all text fields and specified selects)
													- all: validates all supported fields, form ID required
													- alltext: validates all text fields (input type=text, textarea), form ID required
													- allselect: validates all select fields, form ID required
			
			equal				e			--	single array or array of arrays
												- each array containing element IDs whose values must match, such as password and confirm password fields
												- if they are required, they should be in the required id list -- this only checks for matching values
												- only text fields are supported
			
			clear				c			--	single string or array of strings
												- values are non-required fields IDs with defaultvalue settings
												- will clear default value from field if still present
												- SPECIAL VALUE (string):
													- all: clears all text fields, form ID required -- won't interfere with required fields
			
			---------------------------------------------------------------------------------------------------------------------------------------------
			DATA TYPES(below)				--	these rules apply to each of the following specific data type requirements
												- single string or array of strings
												- values are the IDs of text fields
												- if they are required, they should be in the required id list -- if left blank or default, it is ignored
												
			email		 		m			--	requires valid email address
			numeric		 		n			--	requires a numeric value ([0-9.-]+)
			integer				i			--  requires an integer ([0-9-]+)
			positiveinteger		pi			--  requires a positive integer ([0-9]+)
			
			---------------------------------------------------------------------------------------------------------------------------------------------
			
			Nothing is required, but if form ID is not set, then return_only will be forced to TRUE.
				This allows use for only clearing default values, returning a boolean to another
				function, to dcs_validate and submit the form, any combination of those, or nothing at all.
			=============================================================================================================================================
		*/
		var is_valid = true;
		var s = settings;
		
		if(s.f) s.form = s.f;
		if(s.ro) s.return_only = s.ro;
		if(s.r) s.required = s.r;
		if(s.e) s.equal = s.e;
		if(s.c) s.clear = s.c;
		if(s.m) s.email = s.m;
		if(s.n) s.numeric = s.n;
		if(s.i) s.integer = s.i;
		if(s.pi) s.positiveinteger = s.pi;
		
		var form = (s.form) ? $(s.form) : false;
		var return_only = (!form) ? true : ((s.return_only) ? true : false);
		
		if(form) {
			var fields = $A(form.getElements());
			s.required = dcs_validate_get_special(fields, s.required, 'req');
			s.clear = dcs_validate_get_special(fields, s.clear, 'clear');
		}
		
		//check required fields
		if(!dcs_validate_fields(s.required,'req')) is_valid = false;
		
		//check matching value fields
		if(!dcs_validate_matches(dcs_makeArray(s.equal))) is_valid = false;
		
		//check specific data types
		if(!dcs_validate_fields(s.email, 'email')) is_valid = false;
		if(!dcs_validate_fields(s.numeric, 'numeric')) is_valid = false;
		if(!dcs_validate_fields(s.integer, 'integer')) is_valid = false;
		if(!dcs_validate_fields(s.positiveinteger, 'positiveinteger')) is_valid = false;
		
		//clear default text from unrequired fields before submitting
		if(is_valid) dcs_validate_clear_defaults(s.clear);
		
		//if return only, return the boolean
		if(return_only) return is_valid;
		//otherwise, submit and return false
		if(is_valid) form.submit();
		return false;
	}
	function dcs_validate_get_special(fields, a, type) {
		a = dcs_makeArray(a);
		if(a.length == 0) return a;
		var get_all = (a.indexOf('all') > -1);
		var get_text = (get_all || a.indexOf('alltext') > -1);
		var get_select = (type != 'clear' && (get_all || a.indexOf('allselect') > -1));
		if(get_text || get_select) {
			a = a.without('all','alltext','allselect');
			fields.each(function(f){
				switch(f.nodeName.toLowerCase()) {
					case 'input': if(get_text && f.readAttribute('type') == 'text') a.push(f.readAttribute('id')); break;
					case 'textarea': if(get_text) a.push(f.readAttribute('id')); break;
					case 'select': if(get_select) a.push(f.readAttribute('id')); break;
					default: break;
				}
			});
		}
		return a.uniq();
	}
	function dcs_validate_matches(a) {
		if(a.length == 0) return true;
		//if(!a[0] instanceof Array) a = [a];
		if(Object.isString(a[0])) a = $A([a]);
		var is_valid = true;
		a.each(function(i){
			if(!dcs_validate_match(i)) is_valid = false;
		});
		return is_valid;
	}
	function dcs_validate_match(a) {
		var is_valid = true;
		var cv = false;
		$A(a).each(function(i){
			var e = $(i);
			var v = e.value;
			if(!cv) cv = v;
			else if(v != cv) is_valid = false;
		});
		if(!is_valid) a.each(function(i){Effect.Pulsate($(i))});
		return is_valid;
	}
	function dcs_validate_fields(a, type) {
		a = dcs_makeArray(a);
		if(a.length == 0) return true;
		var is_valid = true;
		a.each(function(i){
			var e = $(i);
			if(e) {
				var r = true;
				var node = e.nodeName.toLowerCase();
				if(node == 'textarea' || node == 'input') {
					var v = e.value;
					var dv = (e.hasAttribute('defaultvalue')) ? e.readAttribute('defaultvalue') : "";
					//only check if user input present
					if(type == 'req' || (!v.blank() && v != dv)) {
						var r = true;
						switch(type) {
							case 'req': r = (!v.blank() && v != dv); break;
							case 'email': r = v.match(/^[a-zA-Zs0-9_!#%&"=`'{}~.$*+?^|\/\\-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i); break;
							case 'numeric': r = v.match(/^[0-9.-]+$/i); break;
							case 'integer': r = v.match(/^[0-9-]+$/i); break;
							case 'positiveinteger': r = v.match(/^[0-9]+$/i); break;
							default: break;
						}
					}
				} else if(node == 'select') {
					var v = e.getValue();
					r = (v != '0' && v != "");
				}
				if(!r) {
					is_valid = false;
					Effect.Pulsate(e);
				}
			}
		});
		return is_valid;
	}
	function dcs_validate_clear_defaults(a) {
		a = dcs_makeArray(a);
		if(a.length == 0) return;
		a.each(function(i){
			var e = $(i);
			if(e.hasAttribute('defaultvalue')) {
				if(e.value == e.readAttribute('defaultvalue')) e.setValue("");
			}
		});
	}

/**** helpers ****/
	function dcs_makeArray(a) {
		if(!a) a = [];
		if(Object.isString(a)) a = (a.blank()) ? [] : [a];
		return $A(a);
	}
