//
//	dateValidation:
//
//	Script currently supports three date formats. System(dd-MM-yyyy), no sparator(ddMMyyyy) and divide separator(dd/MM/yyyy)
//
//	method getFormattedDate: takes a date in any of the supported formats, and if not in system format will return the date
//	in system format.
//
//  21/06/2016: added new draft date formats. pending implementation
//  22/06/2016: new dates now implemented.
//  28/03/2018: re-work script object to work with service portal.
//
function dateValidationHReForms() {
	
	// one day in milliseconds
	
	this.MilliSecondDay = 86400000+0;
	this.MilliSecondWeek = 86400000 * 7; // one week is seven days
		
	// Valid date formats.
	this.NS_format = 'ddMMyyyy';
	this.NSSY_format = 'ddMMyy'; // new
	this.Div_format = 'dd/MM/yyyy';
	this.DivSY_format = 'dd/MM/yy'; // new
	this.SY_format = 'dd-MM-yy'; // new
	this.format = 'dd-MM-yyyy';
	var date = new Date();
	var Y = date.getFullYear() + ""; // string
	this.century = Y.substr(0, Y.length-2);
	
	_initialize = function() {
		// does nothing currently
	};
	
	
	//
	//
	//
	//
	this._processDate = function(strDate, strFormat) {
		// find the day month and year component for
		// the strFormat provided.
		var isValidDate = false;
		
		var yearlen = 2;
		var yearpos = strFormat.lastIndexOf('yyyy');
		if(yearpos !=-1) {
			yearlen = 4;
		} else yearpos = strFormat.lastIndexOf('yy');
		
		var sep = 0;
		var monthpos = strFormat.lastIndexOf('MM');
		var daypos = strFormat.lastIndexOf('dd');
		if(daypos+2 == monthpos) ++sep; // no sep
		else if(strFormat.charAt(daypos+2) == strDate.charAt(daypos+2) ) ++sep;

		if(monthpos+2 == yearpos) ++sep; // no sep
		else if(strFormat.charAt(monthpos+2) == strDate.charAt(monthpos+2) ) ++sep;

		var dd = strDate.substr(daypos,2);
		var mm = strDate.substr(monthpos,2);
		var yyyy = strDate.substr(yearpos,yearlen);
		if(yearlen<4) yyyy = this.century + yyyy;
		
		var ISODate = yyyy + "-" + mm + "-" + dd;
		var re = RegExp('^[0-9]{2}$','i');
		var re2 = RegExp('^[0-9]{4}$','i');
		
		var componentsAreDigits = re.test(dd) && re.test(mm) && re2.test(yyyy);
		
		var dp = new Date(ISODate); // verify this is is real
		isValidDate = ((dp!=-1) && sep==2) && componentsAreDigits && (dp != "Invalid Date");
		
		// DEBUG
		//console.log("@@@ DEBUG (DATE) : strDate["+strDate+"] strFormat["+strFormat+"] dd["+dd+"] mm["+mm+"] yyyy["+yyyy+"] isValidDate["+isValidDate+"] dp["+dp+"] ISODate["+ISODate+"] sep["+sep+"] componentsAreDigits["+componentsAreDigits+"]");
		
		return isValidDate;
		
	};
	
	//
	//  public interface to verifying date format and validity
	//
	this._isDate = function(theDate, theFormat) {
		try {
			//console.log("@@@ _isDate testing : theDate["+theDate+"] theFormat["+theFormat+"]");
			return this._processDate(theDate, theFormat);
		} catch(e) {
			console.log("@@@ error processing date in function isDate("+e.message+").");
		}
		return false;
	};
	
	//
	//  returns the date for Today in in system format
	//
	this.ToDay = function() {
		try{
			var today = new Date();
			var M = (1 + today.getMonth()) + "";
			if(M<10) M = "0"+M;
			var D = today.getDate() + "";
			if(D<10) D = "0"+D;
			var Y = today.getFullYear() + "";
			
			var todaysDate = D +'-'+ M +'-'+ Y;
			
			//console.log("@@@ Today's date is ["+todaysDate+"]");
			return todaysDate;
			
		} catch(err) {
			console.log("@@@ An error occurred in 'ToDay', message="+err.message);
		}
	};
	//
	//	returns true if the date is in a supported format
	//
	this.isValidDate = function(theDate) {
		result = (this._isDate(theDate, this.format) || this._isDate(theDate, this.NS_format) || this._isDate(theDate, this.Div_format) || this._isDate(theDate, this.SY_format) || this._isDate(theDate, this.NSSY_format) || this._isDate(theDate, this.DivSY_format));
		return result;
	};
	
	//
	//	accepts a date in any day, month, year format that has a separator eg. dd-MM-yyyy
	//	and returns it in ISO format yyyy-MM-dd
	//
	this.toISOFormat = function(theDate) {
		// reformat date
		// found no simple client side way of doing this so...
		var dd = theDate.substr(0,2);
		var mm = theDate.substr(3,2);
		var yyyy = theDate.substr(6,4);
		formattedDate = yyyy+"-" + mm + "-"+dd;
			
		return formattedDate;
	};
	
	//
	//	returns true if refDate is a date that occurs before lDate, false otherwise.
	//
	this.isDateBefore = function(refDate, lDate) {
		try {
			if(!this.isValidDate(refDate))
				{
				//console.log("@@@ refDate: is not valid");
				return false; // error invalid date formats
			}
			if(!this.isValidDate(lDate))
				{
				//console.log("@@@ lDate: is not valid");
				return false; // error invalid date formats
			}
			
			// check refDate occurs before lDate
			// convert to javascript dates
			var bdate = new Date(this.toISOFormat(refDate));
			var adate = new Date(this.toISOFormat(lDate));
			var result = (bdate.valueOf() < adate.valueOf());
			//console.log("@@@ DEBUG: refDate["+refDate+"] bdate["+bdate+"] lDate["+lDate+"] adate["+adate+"] result["+result+"]");
			return result;
		}
		catch (err)
		{
			console.log("@@@ An error occurred in 'isDateBefore', message="+err.message);
		}
		return false;
	};

	//
	//	returns true if refDate is a date that occurs before (or equal to) lDate, false otherwise.
	//
	this.isDateTodayOrBefore = function(refDate, lDate) {
		try {
			if(!this.isValidDate(refDate))
				{
				//console.log("@@@ refDate: is not valid");
				return false; // error invalid date formats
			}
			if(!this.isValidDate(lDate))
				{
				//console.log("@@@ lDate: is not valid");
				return false; // error invalid date formats
			}
			
			// check refDate occurs before or equals lDate
			// convert to javascript dates
			var bdate = new Date(this.toISOFormat(refDate));
			var adate = new Date(this.toISOFormat(lDate));
			var result = (bdate.valueOf() <= adate.valueOf());
			//console.log("@@@ DEBUG: refDate["+refDate+"] bdate["+bdate+"] lDate["+lDate+"] adate["+adate+"] result["+result+"]");
			return result;
		}
		catch (err)
		{
			console.log("@@@ An error occurred in 'isDateTodayOrBefore', message="+err.message);
		}
		return false;
	};
	
	//
	// return false if dates are not valid, or refDate is later than lDate. 
	// also returns false, if the diff in days is greater than range.
	// Where range is in days.
	//
	this.isDateWithinRange = function(refDate, lDate, range /*is in days*/) {
		try {
			// verify that the dates are valid and that refDate < lDate
			if(!this.isDateBefore(refDate, lDate)) return false; // invalid
			
			var dstart = new Date(this.toISOFormat(refDate));
			var dend = new Date(this.toISOFormat(lDate));
			
			var diffMilliSeconds = dend.valueOf() - dstart.valueOf();
			var diffDays = diffMilliSeconds / this.MilliSecondDay;
			var MilliSecondRange = range * this.MilliSecondDay;

			var result = (diffMilliSeconds <= MilliSecondRange);
			
			//console.log("@@@ refdate["+refDate+"] ldate["+lDate+"] range["+range+"] : diffDays["+diffDays+"] result["+result+"]");
			
			return result;
			
		} catch(err) {
			console.log("@@@ An error occurred in dateValidationHReForms::isDateWithinRange, message="+err.message);
		}
	};
	//
	//	returns true if theDate is in system format
	//
	this.isSystemFormat = function(theDate) {
		return this._isDate(theDate, this.format);
	};
	
	//
	//	returns a string message detailing the supported formats.
	//	useful when displaying errors message for date fields.
	//
	this.validFormats = function() {
		return "one of these formats (" +this.NS_format + ", " + this.Div_format + ", " + this.format + ", " + this.NSSY_format + ", " + this.DivSY_format + " or " + this.SY_format+ ")";
	};
	
	//
	//	formats theDate to system format if required.
	//
	this.getFormattedDate = function(theDate) {
		
		try {
			var dd;
			var mm;
			var yy;
			var yyyy;
			
			if(this._isDate(theDate, this.format))
				{
				
				// date is valid and formatted as dd-MM-yyyy
				return theDate;
			} else if(this._isDate(theDate, this.SY_format)) {
				//console.log("@@@ Date is SY system format["+theDate+"]");
				// reformat date
				// found no simple client side way of doing this so...
				dd = theDate.substr(0,2);
				mm = theDate.substr(3,2);
				yy = theDate.substr(6,2);
				formattedDate = dd+"-"+mm+"-"+this.century+yy;
					
				return formattedDate;
				
			} else if (this._isDate(theDate, this.NS_format))
			{
				
				// reformat date
				// found no simple client side way of doing this so...
				dd = theDate.substr(0,2);
				mm = theDate.substr(2,2);
				yyyy = theDate.substr(4,4);
				formattedDate = dd+"-"+mm+"-"+yyyy;
					
				return formattedDate;
				
			} if(this._isDate(theDate, this.NSSY_format)) {
				//console.log("@@@ Date is NS SY format["+theDate+"] century["+this.century+"]");			
				// reformat date
				// found no simple client side way of doing this so...
				dd = theDate.substr(0,2);
				mm = theDate.substr(2,2);
				yy = theDate.substr(4,2);
				formattedDate = dd+"-"+mm+"-"+this.century+yy;
					
				return formattedDate;
			} else if (this._isDate(theDate, this.Div_format))
			{
				// reformat date
				formattedDate = theDate.replace('/','-'); // on firefox it only replaces the first instance
					formattedDate = formattedDate.replace('/','-');
					
				return formattedDate;
				
			} else if(this._isDate(theDate, this.DivSY_format)) {
				//console.log("@@@ Date is SY Div format["+theDate+"]");
				// found no simple client side way of doing this so...
				dd = theDate.substr(0,2);
				mm = theDate.substr(3,2);
				yy = theDate.substr(6,2);
				formattedDate = dd+"-"+mm+"-"+this.century+yy;
					
				return formattedDate;

			} else // date is not in a supported format return an empty string
				{
				return "";
			}
		} catch (err)
		{
			console.log("@@@ An error occurred in dateValidationHReForms, message="+err.message);
		}
		return "";
	};
	
	this.type = 'dateValidationHReForms';
	_initialize();
}