﻿String.prototype.trim = new Function("return this.replace(/\\s+$|^\\s*/gi,'');");

var invalidYear = 'Το έτος που πληκρολογείσατε είναι λανθασμένο. Παρακαλώ εισάγετε σωστό έτος.'
var missingFieldError = 'Please fill in @caption.';
var invalidFieldFormatError = 'Value of @caption field is false.';
var invalidDateError = 'Η ημ/νία που εισάγατε στο πεδίο @caption δεν είναι σωστή. Πρέπει να είναι της μορφής ΗΗ/ΜΜ/ΕΕΕΕ. π.χ. 14/3/2000';
var invalidMailError = 'That does not seem to be an email.';
var missingSelectField = 'You have to select a value for @caption.';

/**
* Validates a form. The validation icludes mandatory fields check and formation of the fields, if any formation - e.g. dates - is required.
* The function checks all form fields, except hidden fields and those that are disabled.
* To validate a mandatory field a isRequired attribute shlould be placed inside the form field. The valid values are "1" meaning the 
* the field is required, or "0" or no attribute meaning the field is not required so no validation if it contains no value
* To validate a format of the value in a field a format attribute is required in the field. This may include the following formats:
* 	date   : date format using dd/MM/YYYY formation. The year should be greater than 1980
*	num    : incicating that the value should be an integer
*	float  : a float number value
*   email  : pretty obvious what is it about
*   year   : The year should be greater than 1980 and less than 2200
*
*  Notes: Please keep in mind that in special business cases this generic 
*  validation schema is not sufficient and flexible. 
*  You have to make your own instance of javascript code 
*  to implement you potential more complex business logic.
*  
* param: sFormName The name of the form. String is expected. e.g. 'formName'
*/
function validateForm(sFormName)
{
	var form = document.forms[sFormName];

	var formElements = form.elements;
	var length = formElements.length;
	for (i=0; i<length; i++)
	{
		var oCtrl = formElements[i];

		if (oCtrl.disabled || oCtrl.type=='hidden') {
			continue;
		}
		
		if (oCtrl.getAttribute('isRequired')=='1' && oCtrl.type!='select-multiple' && (!oCtrl.value || !oCtrl.value.trim())) {
			var message = missingFieldError.replace('@caption', oCtrl.getAttribute('caption'));
			msg(oCtrl, message);
			return false;
		}
		
		
		if(oCtrl.getAttribute('isRequired')=='1' && oCtrl.type=="select-one") {
			if(oCtrl.selectedIndex == 0) {
				var message = missingSelectField.replace('@caption', oCtrl.getAttribute('caption'));
				msg(oCtrl, message);
				return false;
			}
		}
		
		//select multiple is handled by the same validation with the text fields so no need to 
		if(oCtrl.getAttribute('isRequired')=='1' && oCtrl.type=="select-multiple") {
			if(!oCtrl.value) {
				var message = missingSelectField.replace('@caption', oCtrl.getAttribute('caption'));
				msg(oCtrl, message);
				return false;
			}
		}
		
		var sMsg;
		if (oCtrl.value && oCtrl.getAttribute('format')!=null)
		{
	
			switch(oCtrl.getAttribute('format'))
			{
			case 'float':
				var fValue = new String(oCtrl.value);
				if(fValue.indexOf(',')!=-1)
					fValue.replace(',', '.');
				isValid = !isNaN(fValue);
				sMsg =  invalidFieldFormatError.replace('@caption', oCtrl.getAttribute('caption'));
				break;
			case 'afm':
				isValid = false;
				sMsg = CheckAFM(oCtrl.value);
				if (sMsg == null){
					isValid = true;
				} else {
					isValid = false;
				}
				break;
			case 'floatcur':
				isValid = !isNaN(oCtrl.value);
				sMsg = invalidFieldFormatError.replace('@caption', oCtrl.getAttribute('caption'));
				break;
			case 'num':
				isValid = !isNotInt(oCtrl.value);
				sMsg = invalidFieldFormatError.replace('@caption', oCtrl.getAttribute('caption'));
				//sMsg = '"' + oCtrl.caption + '" field must be integer!';
				break;
			case 'date':
				isValid = isValidDate(oCtrl.value, '/');
				sMsg = invalidDateError.replace('@caption', oCtrl.getAttribute('caption'));
				//sMsg = '"' + oCtrl.caption + '" field is a wrong date or was entered in the wrong format (correct format: dd/mm/yyyy)!';
				break;
			case 'email':
				isValid = isValidEmail(oCtrl.value);
				sMsg = invalidMailError.replace('@caption', oCtrl.getAttribute('caption'));
				//sMsg = '"' + oCtrl.caption + '" is not a valid email e.g <username>@tim.com.gr!';
				break;
			case 'time':
				isValid = isValidTime(oCtrl.value);
				sMsg = '"' + oCtrl.getAttribute('caption') + '" field must be in hh:mm format!';
				break;
			case 'totaltime':
				isValid = isValidTotalTime(oCtrl.value);
				sMsg = '"' + oCtrl.getAttribute('caption') + '" field must be in hh:mm format!';
			
			// Validation for File Upload tag
			case 'fileUpload':
				isValid = isValidFileUpload(oCtrl.value);
				sMsg = 'Το αρχείο που επισυνάψατε δεν είναι σωστό.';
				break;	
			case 'year':
				isValid = isValidYear(oCtrl.value);
				sMsg = invalidYear;
				break;				 	
			}
			if (!isValid)
			{
				msg(oCtrl, sMsg);
				return false;
			}
		}
//chkAvg = chkAvg + (new Date().getTime() - chkStarte);
	}
//alert("time before groups = " + (new Date().getTime() - starte) + "ms");
//if (length!=0) {
//alert("retAvg eval = "+(retAvg) +"ms");
//alert("evalAvg eval = "+(evalAvg) +"ms");
//alert("reqAvg eval = "+(reqAvg) +"ms");
//alert("chkAvg eval = "+(chkAvg) +"ms");
//}
//starte = new Date().getTime();
	// check groups
	var oGroups = form.getElementsByTagName('GROUP');
	var oGroup, oElements, bResult;
	var groupsLength = oGroups.length;
	for (var i=0; i<groupsLength; i++)
	{
		oGroup = oGroups[i];
		bCondition = true;
		if (oGroup.condition)
			bCondition = eval(oGroup.condition);
		if (bCondition)
		{
			oElements = oGroup.elements.split(';');
			var elementsLength = oElements.length;
			bResult = false;
			for (var j=0; j<elementsLength; j++)
			{
				oCtrl = formElements[oElements[j]];
				switch (oCtrl.type)
				{
				case 'select-one':
				case 'text':
					sValue = oCtrl.value;
					break;
				case 'checkbox':
					sValue = (oCtrl.checked?'on':'');
					break;
				case 'textarea':

					sValue = ClearTabs(oCtrl.value);
					break;
				}
				if (sValue!='')
				{
					bResult = true;
					break;
				}
			}
			if (!bResult)
			{
				groupMsg(form, oElements);
				return false;
			}
		}
	}
//alert("time for groups = " + (new Date().getTime() - starte) + "ms");
	return true;
}
function msg(oCtrl, sMessage)
{
	oCtrl.style.backgroundColor = '#ED1B2E';
	oCtrl.style.color = 'white';
	alert(sMessage);
	oCtrl.style.backgroundColor = '';
	oCtrl.style.color = '';
	if (oCtrl.type != 'hidden')
		oCtrl.focus();
}
function groupMsg(oForm, oElements)
{
	oForm.elements[oElements[0]].focus();
	for (i=0; i<oElements.length; i++)
		oForm.elements[oElements[i]].style.backgroundColor = '#ED1B2E';
	alert('One of the highlighted fields is mandatory!');
	for (i=0; i<oElements.length; i++)
		oForm.elements[oElements[i]].style.backgroundColor = '';
}
function isValidEmail(str)
{
	var at="@"
	var dot="."
	var lat=str.indexOf(at)
	var lstr=str.length
	var ldot=str.indexOf(dot)
	if (str.indexOf(at)==-1)
	   return false;
	if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr)
	   return false;
	if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr)
	    return false;
	 if (str.indexOf(at,(lat+1))!=-1)
	    return false;
	 if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot)
	    return false;
	 if (str.indexOf(dot,(lat+2))==-1)
	    return false;
	 if (str.indexOf(" ")!=-1)
	    return false;

	return true;
}

function isValidDate(date, separator)
{
	function leapYear(year)
	{
		return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
	}

	function validDay (day, month, year)
	{
		var days = Array (31,28,31,30,31,30,31,31,30,31,30,31)
		if (leapYear (year)) days[1] = days[1] + 1
		return (day>=1) && (day <= days[month-1])
	}

	if (date=="") return true;
	if (date.length	> 10) return false;
	var tmp = date.split(separator);
	if (tmp.length != 3) return false;
	
	if (isNotInt(tmp[0]) || isNotInt(tmp[1]) || isNotInt(tmp[2])) return false;

	var day = parseInt (tmp[0],10);
	var month = parseInt (tmp[1],10);
	var year = parseInt (tmp[2],10);
	return (validDay(day,month, year) && (month>=1) && (month<=12) && (year>=1980) && (year<=3000));
}
function isValidTime(timeStr)
{
	// Checks if time is in HH:MM:SS AM/PM format.
	// The seconds and AM/PM are optional.
	var timePat = /^(\d{1,2}):(\d{2})(:(\d{2}))?(\s?(AM|am|PM|pm))?$/;
	if (timeStr != "")
	{
		var matchArray = timeStr.match(timePat);
		if (matchArray == null)
			return false;
		hour = matchArray[1];
		minute = matchArray[2];
		second = matchArray[4];
		ampm = matchArray[6];

		if (second=="") { second = null; }
		if (ampm=="") { ampm = null }

		if (hour < 0  || hour > 23)
			return false;
		if  (hour > 12 && ampm != null)
			return false;
		if (minute<0 || minute > 59)
			return false;
		if (second != null && (second < 0 || second > 59))
			return false;

	}
	return true;
}

function isValidTotalTime(timeStr)
{
	// Checks if time is in HH:MM:SS AM/PM format.
	// The seconds and AM/PM are optional.
	var timePat = /^(\d{1,3}):(\d{2})(:(\d{2}))?(\s?(AM|am|PM|pm))?$/;
	if (timeStr != "")
	{
		var matchArray = timeStr.match(timePat);
		if (matchArray == null)
			return false;
		hour = matchArray[1];
		minute = matchArray[2];
		second = matchArray[4];
		ampm = matchArray[6];

		if (second=="") { second = null; }
		if (ampm=="") { ampm = null }

		if (hour < 0  || hour > 2000)
			return false;
		if  (hour > 12 && ampm != null)
			return false;
		if (minute<0 || minute > 59)
			return false;
		if (second != null && (second < 0 || second > 59))
			return false;

	}
	return true;
}

function isNotInt(num){
	return(isNaN(num) || num.indexOf(".")!=-1);
}

function ClearTabs(val){
	if(val!=''){
		val=val.split('\t').join('');
	}
	return val;
}

function isNumber(Num) {
	var b = true;
	for (var j=0; j < Num.length; j++) {
		if (b == true) {
			if ((Num.charAt(j) > -1) && (Num.charAt(j) < 10))
				b = b;
			else
				b = false;
		}
	}
	return b;
}

function CheckAFM(AFM) {
	var msg = "";
	var i;
	var nn;
	var S = 0;
	var V = 512;
	var Y = 0;
	var tempchar;
	var lastchar;

	if (AFM.length < 9)
		msg = 'Το ΑΦΜ που εισάγατε δεν είναι σωστό.';
	if (!isNumber(AFM))
		msg = 'Το ΑΦΜ που εισάγατε δεν είναι σωστό.';
	if (msg == "") {
		for (var i= 0 ; i < AFM.length-1; i++){
			tempchar = AFM.charAt(i);
			V = V / 2;
			S += tempchar * V;
		}
		Y = S % 11;
		lastchar = AFM.charAt(AFM.length-1);
		if ((Y == 10 && lastchar == "0") || (Y == lastchar)){
			msg = null;
		} else {
			msg = 'Το ΑΦΜ που εισάγατε δεν είναι σωστό.';
		}
	}
	return msg;
}



/**
 *  @author doxaras
 *	Generic funttion that facilitates javacript regular expressions 
 *   to validate file upload.
 */
function isValidFileUpload(fileName) {
	//currently only checks extention.
	var pattern = '\.(jpg|jpeg|png|gif|pdf|doc|docx)';
	//var pattern = "^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w ]*))+(?i)\.(txt|TXT|doc|DOC)$";
	var res = calculateDynamicRegExp(fileName, pattern , "g");
	return res;
}

/**
 * function to validate if year is in the interval 
 *  1970 <= year <= present year
 */
function isValidYear(yearValue) {
	var year = parseInt(yearValue); 	
	var d = new Date();
	var currentYear = d.getFullYear();
	
	if( year >= 1980 && year<=2200)
		return true;
	return false;
}


/**
 * @author doxaras	
 * Reusable method to calculate regualr expressions.
 */
function calculateDynamicRegExp(string, pattern, gFlag)
{
	var matching = new RegExp(pattern);
  	var m = null;
	try
	{	
		m = matching.exec(string,gFlag);
	}
	catch(error)
	{
		
	}
	return m==null? false: true;
}
