// future dev: http://demos.usejquery.com/ketchup-plugin/index.html?db-skill=on&db-skill=on 
// also nice: http://www.useragentman.com/blog/2010/06/20/visibleif-html5-custom-data-attributes-with-javascript-make-dynamic-interactive-forms/
//
// Form level
// - data-ios-clear
//
// field level custimisation
// - data-validation-type
// - data-required
// - data-length
// 
// data-form-init  Is het form al geinitialiseerd?
// data-label 	   Gebruikersvriendelijke naam voor het veld
//
var strValidationError = '';
var fldTooltip= null;	// field the tooltip is shown for

lib_addEvent(window, "load", form_init_all)

// Eenvoudige validatie, velden die met 'required-' beginnen zijn verplicht (of velden die in het veld Required staan, gescheiden door ; of ,)
// aanroep in form definitie => onsubmit="return form_valid(this)"
function form_valid(form) {
	var tel;
	var objfield;
	var objFocus=null;
	
	if (!(form.getAttribute("data-form-init"))) {
		form_init( form );
	}
	pSubmit    = 'Verstuur';
	pClassname = 'forgotten';
	
	strValidationError='';
	if (form){
		for (tel=0;tel<form.length;tel++) {
			objfield = form.elements[tel];
			if (objfield.type) {
				switch (objfield.type) {
					case 'checkbox':
					case 'radio':
						if (objfield.getAttribute("data-required")) {
							strfieldname = objfield.name;
							if (!form_check_required_radio_checkbox(form,strfieldname)) {
								form_valid_add_error( objfield, '<strong>' + objfield.getAttribute("data-label") + '</strong> is niet ' + (objfield.type=='checkbox'?'aangevinkt':'geselecteerd'), 'Een waarde is vereist');
								if (!objFocus) {objFocus = objfield}
							} else {
								form_valid_add_error( objfield, '','');
							}
							// skip all other instances of this element
							if (tel+1<form.length) 
								while (form[tel].name.toLowerCase()==strfieldname.toLowerCase() && tel+1<form.length) tel++;
								// skip back; als het niet de laatste is...
								if (!(form[tel].name.toLowerCase()==strfieldname.toLowerCase() && tel+1==form.length)) tel--;
						}
						break; 
						
					default:
						if (!(form_valid_field( objfield ))) {
							if (!objFocus) {objFocus = objfield}
						}
					
				}
			}

		}
		if (objFocus) {
//			try { 
				form_field_show_error( objFocus );
				objFocus.focus();
//				blnFirst=false;
//			}
//			catch(e){}
		}
		
		// custom form level validation indicated by data-validation on the form element		
		var sFormValidate = form.getAttribute("data-validation");
		if (sFormValidate) {
			eval(sFormValidate);
		}
		var sButtonName = form.getAttribute("data-button-name");
		if (sButtonName) {
			pSubmit=sButtonName;
		}

		// process it
		if (strValidationError=='') {
			if (document.all) {
				for (tel=0;tel<form.length;tel++) {
					objfield=form[tel];
					if (objfield.type=="submit"||objfield.type=="button")  
						objfield.disabled = true;
				} 
			}
			return true;
		} else {
			form_valid_report( strValidationError, pSubmit )
			return false;
		}
	}
}

//
//	Overridable function to report all errors on form-level
//
function form_valid_report( strValidErrors, strSubmitButton) {
	lib_alertbox('De volgende gegevens ontbreken of zijn niet correct\n\n'+strValidErrors+'\nHerstel de fout(en) en druk opnieuw op '+strSubmitButton+'.', "Het formulier is niet correct of niet volledig ingevuld", "form");
}

//
//	Validate a single form field
//
function form_valid_field( objfield ) {
	var bfld_error  = false;
	
	if (objfield.name) {
		strfieldname = objfield.name;
		
		sNiceField = objfield.getAttribute("data-label");
		
		// reset error
		// form_valid_add_error( objfield, "", ""); 
		objfield.setAttribute("data-error", "")
		objfield.setAttribute("data-error-short", "")
		
		if (objfield.getAttribute("data-required")) {
			if (objfield.type) {
				switch (objfield.type) {
					case 'checkbox':
					case 'radio':
						break; 
						
					default:
						if (objfield.type!='hidden') {
							if (objfield.value=='') {
								form_valid_add_error( objfield, '<strong>'+sNiceField+'</strong> is niet ' + (objfield.type=='select-one'?'geselecteerd':'ingevuld'), 'Een waarde is vereist' );
								bfld_error = true;
							}
						}
						break;
				}
			}
		}
		
		if (!bfld_error && objfield.value!='') {
			// see if other validation types are indicated
			var sFixedLength = objfield.getAttribute("data-length");
			if (sFixedLength) {
				if (objfield.value.length!=sFixedLength) {
					form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> moet '+sFixedLength+' karakters lang zijn','Dit veld moet '+sFixedLength+' karakters lang zijn');
					bfld_error = true;
				}
			}
			
			var sValidate = objfield.getAttribute("data-validation-type");
			switch ((sValidate+'').toLowerCase()) {
				// todo expand this to datum, postalcode, url, ip-address, time
				case 'number':
					if (isNaN(objfield.value)) {
						form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> mag alleen nummers bevatten','Alleen nummers zijn toegestaan');	
						bfld_error = true;
					}
					break;
				case 'address':
					if (!objfield.value.lib_contains_numbers()) {
						form_valid_add_error( objfield, 'bij <strong>' + sNiceField + '</strong> ontbreekt het huisnummer','Het huisnummer ontbreekt');
						bfld_error = true;
					}
					break;
				case 'email':
					if (!lib_form_valid_email(objfield)) {
						form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> is geen geldig e-mail adres','Ongeldig e-mail adres');
						bfld_error = true;
					}
					break;
				case 'time':
					// regular expression to match required time format 
					var re = /^(\d{1,2})$/; 
					if(regs = objfield.value.match(re)) {
						objfield.value=objfield.value+":00";
					}
					re = /^(\d{1,2}):(\d{1,2})(:00)?([ap]m)?$/; 
					if(regs = objfield.value.match(re)) { 
						if(regs[4]) { 
							// 12-hour time format with am/pm 
							if(regs[1] < 1 || regs[1] > 12) { 
								form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> bevat een ongeldige uren-indicatie ' + regs[1],'Ongeldige uur-indicatie'); 
								bfld_error = true;
							} 
						} else { 
							// 24-hour time format 
							if(regs[1] > 23) { 
								form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> bevat een ongeldige uren-indicatie ' + regs[1],'Ongeldige uren-indicatie'); 
								bfld_error = true;
							} 
						} 
						if (regs[2] < 0 || regs[2] > 59) { 
							form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> bevat een ongeldige minuten-indicatie ' + regs[2],'Ongeldige minuten-indicatie'); 
							bfld_error = true;
						} 
						// assure time has right format, adding zero's
						objfield.value = regs[1].toString()+":"+lib_right('0'+regs[2].toString(),2)
					} else { 
						form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> is een ongeldig tijdformaat (uu:mm)', 'Ongeldige tijd (uu:mm)'); 
						bfld_error = true;
					} 
					break;
				case 'datum':
					// regular expression to match required date format (2do: specify the date range in data- fields)
					// hardcoded in dutch format, for english i suggest making a new type: date!
					// 2do: skip entire year!
					var re = /^(\d{1,2})-(\d{1,2})$/; 
					// geen jaar ingevuld, even toevoegen
					if(regs = objfield.value.match(re)) { 
						var dt = new Date();
						objfield.value = lib_right('0'+regs[1].toString(),2)+"-"+lib_right('0'+regs[2].toString(),2)+"-"+dt.getFullYear().toString()
					}
							
					var re = /^(\d{1,2})-(\d{1,2})-(\d{0,4})$/; 
					minYear = 1900;
					maxYear = 2100;
					
					if(regs = objfield.value.match(re)) { 
						if(regs[1] < 1 || regs[1] > 31) { 
							form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> bevat een ongeldige dag ' + regs[1], 'Ongeldig dag'); 
							bfld_error = true;
						} else if(regs[2] < 1 || regs[2] > 12) { 
							form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> bevat een ongeldige maand ' + regs[2], 'Ongeldig maand'); 										
							bfld_error = true;
						} else {
							if (regs[3]<=30) { 
								regs[3]=parseInt(regs[3])+2000 
							}
							if (regs[3]<100) { 
								regs[3]=parseInt(regs[3])+1900 
							}
							if (regs[3]<1000) { 
								regs[3]=parseInt(regs[3])+1000 
							}
							if (regs[3] < minYear || regs[3] > maxYear) { 
								form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> bevat een ongeldig jaar ' + regs[3], 'Ongeldig jaar'); 
								bfld_error = true;
							}
						} 
						// assure date has right format, adding zero's
						objfield.value = lib_right('0'+regs[1].toString(),2)+"-"+lib_right('0'+regs[2].toString(),2)+"-"+regs[3].toString()
					} else { 
						form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> is een ongeldig datumformaat (dd-mm-jjjj)', 'Ongeldige datum (dd/mm/yyyy)'); 
						bfld_error = true;
					} 
					break;
				case 'telefoon':
					var re = /(^\+[0-9]{2}|^\+[0-9]{2}\(0\)|^\(\+[0-9]{2}\)\(0\)|^00[0-9]{2}|^0)([0-9]{9}$|[0-9\-\s]{10}$)/;
					// strip spaces, outer and inner
					objfield.value = objfield.value.lib_trim_all();
					if (!re.test( objfield.value)) {
						form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> is een ongeldig telefoonnummer (10 cijfers)', 'Ongeldig telefoonummer'); 
						bfld_error = true;
					};
					break;
				case 'postcode':	
					var re = /[0-9]{4}\s*[a-zA-Z]{2}$/
					objfield.value = objfield.value.lib_trim_all();
					if (!re.test( objfield.value)) {
						form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> is een ongeldige postcode', 'Ongeldige postcode'); 
						bfld_error = true;
					} else {
						objfield.value = objfield.value.toUpperCase();
					}
					break;
				case 'url':
					if (objfield.value.substring(0,7).toLowerCase()!="http://" && objfield.value.substring(0,8).toLowerCase()!="https://" ) {
						objfield.value = "http://" + objfield.value 
					}
					objfield.value = objfield.value.replace(" ","%20");
					var re = /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:\/~\+#]*[\w\-\@?^=%&amp;\/~\+#])?/
					if (!re.test( objfield.value)) {
						form_valid_add_error( objfield, '<strong>' + sNiceField + '</strong> is een ongeldig internet adres', 'Ongeldig internet adres'); 
						bfld_error = true;
					}
					break;
			}
		}
	}
	return !bfld_error;
}

//
//	Enkele velds validatie
//
function form_valid_add_error( fld, cLongError, cShortError) {
	if (!cShortError) {
		cShortError = cLongError.replace("<strong>","").replace("</strong>","")
	}
	if (cLongError!="")
		strValidationError+=(' - ' + cLongError + '.\n');
	// bewaar de error 
	if (fld) {
		fld.setAttribute( "data-error", cLongError);
		fld.setAttribute( "data-error-short", cShortError);
		form_field_show_error( fld );
	}
}

//
//	Overridable function to show a field error
//
function form_field_show_error( fld ) {
	var cShortError = fld.getAttribute( "data-error-short");
	var obj_pos = fld;
	if (fld.type=='checkbox' || fld.type=='radio') {
		obj_pos = form_find_suitable_parent(obj_pos);
	} 
	form_field_set_valid_classname ( obj_pos, !(cShortError));
	if (cShortError) {
		tooltip.show(cShortError, null, lib_getAbsoluteOffsetLeft(obj_pos) + obj_pos.offsetWidth, lib_getAbsoluteOffsetTop(obj_pos) );	
		fldTooltip = fld;
	}
}

//
//	Default handler for field focus, shows tooltip if needed
//
function form_field_focus( e ) {
	var fld = e.target ? e.target : e.srcElement;
	var cShortError = fld.getAttribute( "data-error-short");
	if (cShortError) {
		var obj_pos = fld;
		if (fld.type=='checkbox' || fld.type=='radio') {
			obj_pos = form_find_suitable_parent(fld);
		} 
		tooltip.show(cShortError, null, lib_getAbsoluteOffsetLeft(obj_pos) + obj_pos.offsetWidth, lib_getAbsoluteOffsetTop(obj_pos) );		
		fldTooltip = fld;
	}
}

//
//	Default handler for field focus loss, always hides tooltip
//
function form_field_blur( e ) {
	var fld = e.target ? e.target : e.srcElement;
	if (form_valid_field( fld ) ) {
		form_field_set_valid_classname ( fld, true);
		if (fldTooltip==fld) { 
			tooltip.hide();
			fldTooltip = null;
		}
	}
}

function form_init_all(){
	for (var tel=0;tel<document.forms.length;tel++) {
		form_init( document.forms[tel] );
	}
}


//
//	Initialises form
//
function form_init( form ) {
	var strfieldname;
	var blnRequired;
	var flds_arr;
	
	//
	//	Bewaar de required indicatie in data-required (oude notaties: hidden veld required en de required- prefix in de naam omzetten)
	//
	var req_fld = form["required"];
	if (req_fld) flds_arr=lib_array_split( req_fld.value );
	
	for (var tel=0;tel<form.length;tel++) {
		blnRequired = false
		objfield = form.elements[tel];
		if (objfield.name) {
			strfieldname = objfield.name;
			
			if (!(objfield.getAttribute("data-label"))) {
				var sNiceField = '';
				var lbl_elt = form[strfieldname+'__label'];
				if (lbl_elt) {
					sNiceField = lbl_elt.value;
				} 
				if (sNiceField=='') {
					// revert to fieldname
					sNiceField = strfieldname;
					if (strfieldname.substring(0,8).toLowerCase()=='required') {
						sNiceField = sNiceField.substring(8);
					}
					sNiceField=sNiceField.replace(/_/gi, " ");
					sNiceField=sNiceField.replace(/-/gi, "");
				}
				sNiceField = sNiceField.substring(0,1).toUpperCase() + sNiceField.substring(1);
				objfield.setAttribute("data-label",sNiceField);
			}
			
			if (strfieldname.substring(0,8).toLowerCase()=='required') {
				blnRequired = true;
			} else {
				if (flds_arr) blnRequired = ( lib_array_find(flds_arr, strfieldname) != -1 )
			} 
			
			if (blnRequired) {
				objfield.setAttribute("data-required","J");
			}
			if (objfield.getAttribute("data-validation-type")=='number') {
				if (isIE) {
					lib_addEvent(objfield, "keydown", lib_form_digitsonly);
				} else {
					objfield.setAttribute("onkeydown", "return lib_form_digitsonly(event);")
				} 
			}
			if (objfield.getAttribute("data-validation-type")=='time') {
				if (isIE) {
					lib_addEvent(objfield, "keydown", lib_form_timekey);
				} else {
					objfield.setAttribute("onkeydown", "return lib_form_timekey(event);")
				} 
			}
			
			lib_addEvent(objfield, "blur" , form_field_blur);
			lib_addEvent(objfield, "focus", form_field_focus);
		}
	}

	if (form.getAttribute("data-ios-clear")) {
		var aFlds = form.getElementsByTagName("textarea");
		for (var i = 0; i < aFlds.length; i++) { 
			aFlds[i].style.paddingRight = "20px";
			aFlds[i].supports_clear = true;
			lib_addEvent(aFlds[i], "focus", form_control_focus);
		}
		// 
		var aFlds = form.getElementsByTagName("input");
		for (var i = 0; i < aFlds.length; i++) { 
			// IE: empty defaults to edit field
			aFlds[i].supports_clear = false;
			if (aFlds[i].type=="text" || aFlds[i].type=="") {
				// 2do: skip fields in the hidden required field list
				if ( !( aFlds[i].readOnly || aFlds[i].getAttribute("data-required") || aFlds[i].maxLength<=10 || aFlds[i].name.substring(0,8).toLowerCase()=='required')) {
					aFlds[i].style.paddingRight = "20px";
					aFlds[i].supports_clear = true;
				}
				// 2do call lib_form_digitsonly for numeric fields (dates?)
			}
			lib_addEvent(aFlds[i], "focus", form_control_focus);
		}
		var aFlds = form.getElementsByTagName("select");
		for (var i = 0; i < aFlds.length; i++) { 
			aFlds[i].supports_clear = false;
			lib_addEvent(aFlds[i], "focus", form_control_focus);
		}
	}
	form.setAttribute("data-form-init","J");
}

function form_field_set_valid_classname ( fld, bValid) {
	// eventuele oude weg
	if (fld.type!="button" && fld.type!="submit") {
		fld.className = fld.className.replace( "invalid", "");
		fld.className = fld.className.replace( "valid", "");
		fld.className = fld.className.replace( "  ", " ");
		fld.className = (fld.className ? fld.className + ' ':'') + (bValid ? 'valid' : 'invalid');
	}
}

var lib_clear_elt_name = "lib_clear_editbutton"
//
// 2do: scrolling breaks link between control and clear button
//
function form_create_clearcontrol( elt ) {
	library_clear_control_elt = $(lib_clear_elt_name);
	if (!library_clear_control_elt) {
		library_clear_control_elt = document.getElementsByTagName("body")[0].appendChild(document.createElement("a"));
	}
	library_clear_control_elt.className = "lib_clear_editbutton";
	library_clear_control_elt.id = lib_clear_elt_name;
	library_clear_control_elt.style.top = (lib_getAbsoluteOffsetTop(elt) + 2).toString() + "px";
	library_clear_control_elt.style.left = (lib_getAbsoluteOffsetLeft(elt) + elt.offsetWidth - library_clear_control_elt.offsetWidth - 3).toString() + "px";
	library_clear_control_elt.title = "Maak veld leeg";
	library_clear_control_elt.edit_field = elt;
	lib_addEvent(library_clear_control_elt, "click", form_clear_fieldvalue);
}

// for now, creates the clear control, but named it general for future enhancements (popup help for instance)
// 
function form_control_focus( evt ) {
	var elt = document.activeElement ? document.activeElement : evt.currentTarget;
	if (elt.supports_clear) {
		form_create_clearcontrol( elt );
	} else {
		form_hide_clearcontrol( );
	}
}

function form_hide_clearcontrol( ) {
	var library_clear_control_elt = $(lib_clear_elt_name);
	if (library_clear_control_elt) {
		library_clear_control_elt.style.top="-30px";
	}
}

function form_clear_fieldvalue( elt ) {
	var library_clear_control_elt = $(lib_clear_elt_name);
	var edt = library_clear_control_elt.edit_field;
	if (edt) {	
		edt.value="";
		edt.focus();
	}	
}

function form_check_required_radio_checkbox( frm, rad_name ) {
	var bRet=false;

	for (var t=0;t<frm.length;t++) {
		if (frm[t].name) {
		    if (frm[t].name.toLowerCase()==rad_name.toLowerCase()) {
			    if (frm[t].checked) bRet=true;
			}
		}
	}
	return bRet; 
}

//	Zoekt het formulier bij een invoerveld
//
function form_find_form( elt ) {
	var cur_elt = elt;
	var the_form = null;
	while (cur_elt.parentNode && !the_form ) {
		if (cur_elt.tagName.toLowerCase()=="form") the_form = cur_elt;
		cur_elt = cur_elt.parentNode;
	}
	return the_form;
}

//	Zoekt een parent van een checkbox/radiobutton waarin de layout kan vallen
//
function form_find_suitable_parent( elt ) {
	var the_elt = null;
	var cur_elt = elt;
	while (cur_elt.parentNode && !the_elt ) {
		if (cur_elt.tagName.toLowerCase()=="td" || cur_elt.tagName.toLowerCase()=="div" || cur_elt.tagName.toLowerCase()=="span") the_elt = cur_elt;
		cur_elt = cur_elt.parentNode;
	}
	return the_elt;
}

