/********************************************************\
	These functions handle common form functionality.
	The "dcs_" prefix exists to prevent conflicts.
\********************************************************/

jQuery(function($){
	dcs_initDefaultValues($);
	dcs_validate_init($);
	dcs_submit_btn_init($);
});
/**** text field default values ****/
function dcs_initDefaultValues($){
	$('input[defaultvalue],textarea[defaultvalue]').each(function(){
		var $field = $(this);
		dcs_setDefaultValue($,$field);
		$field.focus(function(){dcs_clearDefaultValue($,$field)});
		$field.blur(function(){dcs_setDefaultValue($,$field)});
	});
}
function dcs_setDefaultValue($,$field) {
	if($.trim($field.val()) == "") $field.val($field.attr('defaultvalue'));
}
function dcs_selectDefaultValue($,$field) {
	if($.trim($field.val()) == $field.attr('defaultvalue')) $field.select();
}
function dcs_clearDefaultValue($,$field) {
	if($.trim($field.val()) == $field.attr('defaultvalue')) $field.val("");
}

/**** a.submit_btn clicks (within form tags) ****/
function dcs_submit_btn_init($){
	$('form a.submit_btn').click(function(e){
		e.preventDefault();
		$(this).parents('form:first').submit();
	});
}

/**** validation ****/
function dcs_validate_init($){
	//on submit
	$('form').submit(function(e){
		var $form = $(this), $fields = $form.find('[validate]'), $dv_fields = $form.find('input[defaultvalue],textarea[defaultvalue]');
		$dv_fields.each(function(){dcs_clearDefaultValue($,$(this))}); //clear any present default values
		if($fields.length == 0) return; //if there aren't any fields to validate, we are done
		//validate:
		var $invalid = $fields.filter(function(){return(!dcs_validate_field($,$(this)))});
		$form.find('.select.dcs_invalid').removeClass('dcs_invalid'); //clear div.selects previously marked invalid
		$invalid = $invalid.add($invalid.filter('input:hidden').parents('.select'));
		if($invalid.length > 0) { //form did not pass validation
			e.preventDefault(); //stop form submit
			$dv_fields.each(function(){dcs_setDefaultValue($,$(this))}); //restore default values where appropriate
			dcs_validate_alert($,$invalid); //flash fields, display message, etc
			return;
		}
	});
	//remove invalid class on click or focus (they are presumably fixing it)
	//this should make it obvious if it fails validation again that it is still incorrect
	$('.dcs_invalid').live('click focus', function(){$(this).removeClass('dcs_invalid')});
}

function dcs_validate_alert($,$invalid){ //flash fields, display message, etc
	$invalid.addClass('dcs_invalid'); //can style for this class, if desired
	$invalid.fadeOut('fast').fadeIn('fast').fadeOut('fast').fadeIn('fast'); //pulse invalid fields
}
function dcs_validate_field($,$field){ //validate this field
	$field.removeClass('dcs_invalid'); //first clear any previous results
	var ok = true, v = $field.val(), t = $.trim(String(v)), reqs = $field.attr('validate').split(';');
	$.each(reqs, function(i,r){if(!dcs_validate_requirement($,v,t,r)) ok = false;});
	return ok;
}
function dcs_validate_requirement($,v,t,req){ //validate single requirement
	// v = raw value, t = text value
	var ok = true, ra = req.split(':'), r = ra[0], c = ra[1];
	switch(r) {//simple reqs
		//not blank
		case 'text': ok = (t != ""); break;
		//specific data types
		case 'email': ok = t.match(/^[a-zA-Zs0-9_!#%&"=`'{}~.$*+?^|\/\\-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i); break;
		case 'numeric': ok = t.match(/^[0-9.-]+$/i); break;
		case 'integer': ok = t.match(/^[0-9-]+$/i); break;
		case 'positiveinteger': ok = t.match(/^[0-9]+$/i); break;
		default: break;
	}
	if(ok && c) {//reqs with variables(c)
		var ca = c.split(','); //for array (csv) options (may be single value)
		switch(r) {
			case 'text': //min length
				c = parseInt(c);
				if(!isNaN(c)) ok = (t.length >= c);
				break;
			case 'match': //field values must match (ie confirm password); c = other field ID(s)
				$.each(ca, function(i,c){if(v != $('#'+c).val()) ok = false});
				break;
			case 'not': //value must not be in supplied list (useful for select)
				$.each(ca, function(i,c){if(v == c || (c == '_blank' && v == "")) ok = false});
				break;
			default: break;
		}
	}
	return ok;
}
