// Entango Scheduled JavaScript
/*jslint browser: true */ /*global window, Ent */
if(Ent.isUndefined(Ent.scheduled)){Ent.addMember("scheduled");}
if(Ent.isObject(Ent.scheduled) && (Ent.scheduled.entango === true)){
if(Ent.modules.ent_scheduled !== true){
Ent.modules.ent_scheduled = true;
// backwards compatibility, deprecated
Ent.ent_scheduled_included = true;
var Ent_Scheduled = Ent.scheduled;
// current start of day
Ent.scheduled.today = function(){
	if(Ent.today){return Ent.today;}
	var today = new Date();
	return new Date(today.getFullYear(),today.getMonth(),today.getDate());
};
// Get standard names and month period for Entango frequencies or intervals. Defaults to "One Time" data for unrecognized frequencies and "month" for unrecognized intervals
Ent.scheduled.periods = {};
Ent.scheduled.periods.frequencies = {
	"one time": { frequency: "One Time", months: 0, interval: "day" },
	monthly: { frequency: "Monthly", months: 1, interval: "month" },
	quarterly: { frequency: "Quarterly", months: 3, interval: "quarter" },
	"semi-annually": {frequency: "Semi-annually", months: 6, interval: "semiannum" },
	annually: { frequency: "Annually", months: 12, interval: "year" }
};
Ent.scheduled.periods.intervals = {
	day: Ent.scheduled.periods.frequencies["one time"],
	month: Ent.scheduled.periods.frequencies.monthly,
	quarter: Ent.scheduled.periods.frequencies.quarterly,
	semiannum: Ent.scheduled.periods.frequencies["semi-annually"],
	year: Ent.scheduled.periods.frequencies.annually
};
Ent.scheduled.periods.isValidFrequency = function(frequency){return !Ent.isNUN(Ent.scheduled.periods.frequencies[Ent.getString(frequency).toLowerCase()]);};
Ent.scheduled.periods.isValidInterval = function(interval){return !Ent.isNUN(Ent.scheduled.periods.intervals[Ent.getString(interval).toLowerCase()]);};
Ent.scheduled.periods.frequencyInfo = function(frequency){var info = Ent.scheduled.periods.frequencies[Ent.getString(frequency).toLowerCase()]; return Ent.isNUN(info) ? Ent.scheduled.periods.frequencies["one time"] : info;};
Ent.scheduled.periods.intervalInfo = function(interval){var info = Ent.scheduled.periods.intervals[Ent.getString(interval).toLowerCase()]; return Ent.isNUN(info) ?Ent.scheduled.periods.intervals.month : info;};
// check if object can be used as a date for scheduled methods
Ent.scheduled.isScheduleDate = function(item){return Ent.scheduled.getScheduleDate(item) !== null;};
// convert an object to a standard format schedule date object - not guaranteed to be a full or valid date
Ent.scheduled.getScheduleDate = function(item){
	var matchArray, scheduleDate = null;
	if(Ent.isObject(item) && (!Ent.isNUN(item.day) || !Ent.isNUN(item.month) || !Ent.isNUN(item.year))){scheduleDate = item;}
	else if(item instanceof Date){scheduleDate = {day: item.getDate(), month: item.getMonth() + 1, year: item.getFullYear()};}
	else{
		matchArray = Ent.getString(item).match(Ent.dateHelper.standardDatePattern);
		if(matchArray !== null){
			scheduleDate = {};
			scheduleDate.year = Ent.getInt(matchArray[1]);
			scheduleDate.month = Ent.getInt(matchArray[2]);
			scheduleDate.day = Ent.getInt(matchArray[3]);
		}
	}
	return scheduleDate;
};

// retrieve a year from the input item
Ent.scheduled.getYear = function(year){
	var scheduleDate = Ent.scheduled.getScheduleDate(year);
	year = Ent.getInt(scheduleDate ? scheduleDate.year : year);
	return year <= 0 ? Ent.scheduled.today().getFullYear() : year;
};
// retrieve a month from the input item (1 - 12)
Ent.scheduled.getMonth = function(month){
	var scheduleDate = Ent.scheduled.getScheduleDate(month);
	month = Ent.getInt(scheduleDate ? scheduleDate.month : month);
	if(month > 12){month = 12;}
	return month <= 0 ? Ent.scheduled.today().getMonth() + 1 : month;
};
// retrieve a day from the input item (1 - 31).
Ent.scheduled.getDay = function(day){
	var scheduleDate = Ent.scheduled.getScheduleDate(day);
	day = Ent.getInt(scheduleDate ? scheduleDate.day : day);
	if(day > 31){day = 31;}
	return day <= 0 ? Ent.scheduled.today().getDate() : day;
};
// check if a year is a leap year
Ent.scheduled.isLeapYear = function(year){
	year = Ent.scheduled.getYear(year);
	return ((year % 4) === 0) && (((year % 400) === 0) || ((year % 100) !== 0));
};
// Get the actual maximum number of days in a given year
Ent.scheduled.daysInYear = function(year){
	return Ent.scheduled.isLeapYear(year) ? 366 : 365;
};
// Get the actual maximum number of days in a given month for a given year
Ent.scheduled.daysInMonth = function(month,year){
	year = Ent.scheduled.getYear((arguments.length < 2) && ((month instanceof Date) || (Ent.isObject(month) && month.year)) ? month : year);
	month = Ent.scheduled.getMonth(month);
	switch(month){
		case 2: return Ent.scheduled.isLeapYear(year) ? 29 : 28;
		case 4: case 6: case 9: case 11: return 30;
		default: return 31;
	}
};
// Get the day of year
Ent.scheduled.dayOfYear = function(day,month,year){
	if((arguments.length === 1) && Ent.scheduled.isScheduleDate(day)){
		year = Ent.scheduled.getYear(day);
		month = Ent.scheduled.getMonth(day);
	}
	else{
		year = Ent.scheduled.getYear(year);
		month = Ent.scheduled.getMonth(month);
	}
	day = Ent.scheduled.getDay(day);
	var index;
	day = Math.min(day,Ent.scheduled.daysInMonth(month,year));
	var count = 0;
	for(index = 1; index < month; index++){count += Ent.scheduled.daysInMonth(index,year);}
	return count + day;
};
// Get the stopdate string for a given start date, frequency and number of years term - deprecated
Ent.scheduled.stopdate = function(start_day,start_month,start_year,freq,years){
	if(typeof start_day === "string"){start_day = parseInt(start_day,10);}
	if(typeof start_month === "string"){start_month = parseInt(start_month,10);}
	if(typeof start_year === "string"){start_year = parseInt(start_year,10);}
	if(typeof years === "string"){years = parseInt(years,10);}
	if((freq === "One Time") || (years <= 0)){return "";}
	switch(freq){
		case "Monthly": var payments = 12 * years; break;
		case "Quarterly": payments = 4 * years; break;
		case "Semi-annually": payments = 2 * years; break;
		case "Annually": payments = years; break;
	}
	return Ent.scheduled.stopdatePayments(start_day,start_month,start_year,freq,payments);
};
// Get the stopdate string for a given start date, frequency and number of payments - deprecated
Ent.scheduled.stopdatePayments = function(start_day,start_month,start_year,freq,payments){
	if(typeof start_day === "string"){start_day = parseInt(start_day,10);}
	if(typeof start_month === "string"){start_month = parseInt(start_month,10);}
	if(typeof start_year === "string"){start_year = parseInt(start_year,10);}
	if(typeof payments === "string"){payments = parseInt(payments,10);}payments -= 1;if((freq === "One Time") || (payments <= 0)){return "";}switch(freq){case "Monthly": var months = payments; break;case "Quarterly": months = payments * 3; break;case "Semi-annually": months = payments * 6; break;case "Annually": months = payments * 12; break;}var stop_month = start_month + months;var stop_year = start_year + Math.floor((stop_month-1)/12);stop_month = 1 + ((stop_month-1)%12);var stop_day = start_day;var max = Ent.scheduled.maxDay(stop_month,stop_year);if(stop_day > max){stop_day = max;}return stop_year + "-" + (stop_month < 10 ? "0" : "") + stop_month + "-" + (stop_day < 10 ? "0" : "") + stop_day + " 00:00:00";};
// Find the number of payments for a given number of years and a given frequency - deprecated
Ent.scheduled.payments = function(freq,years){
	if((typeof freq !== "string") || (freq === "")){freq = "One Time";}
	if(typeof years === "string"){
		years = parseInt(years,10);
		if(isNaN(years) || (years < 1)){years = 1;}
	}
	else if(typeof years === "number"){
		years = Math.floor(years);
		if(years < 1){years = 1;}
	}
	else{years = 1;}
	var payments = 1;
	switch(freq){
		case "Monthly": payments = 12 * years; break;
		case "Quarterly": payments = 4 * years; break;
		case "Semi-annually": payments = 2 * years; break;
		case "Annually": payments = years; break;
	}
	return payments;
};
// Create the correctly formatted stop date string from a given date - deprecated
Ent.scheduled.createStopDate = function(year,month,day){
	return year + "-" + ((typeof month === "number") && (month < 10) ? "0" : "") + month + "-" + ((typeof day === "number") && (day < 10) ? "0" : "") + day + " 00:00:00";
};
// Get the maximum number of days in a given month and year - deprecated
Ent.scheduled.maxDay = function(month,year){
	switch(month){
		case 2: if(((year % 4) !== 0) || (((year % 100) === 0) && ((year % 400) !== 0))){return 28;} else{return 29;}
		case 4: case 6: case 9: case 11: return 30;
		default: return 31;
	}
};
// Create a full stopdate string - the given date at the beginning of the day
Ent.scheduled.stopdateString = function(year,month,day){
	var maxDays;
	var scheduleDate = Ent.scheduled.getScheduleDate(year);
	day = Ent.scheduled.getDay(Ent.isNUN(day) && scheduleDate ? scheduleDate : day);
	month = Ent.scheduled.getMonth(Ent.isNUN(month) && scheduleDate ? scheduleDate : month);
	year = Ent.scheduled.getYear(scheduleDate ? scheduleDate : year);
	maxDays = Ent.scheduled.daysInMonth(month,year);
	if(day > maxDays){day = maxDays;}
	return year + "-" + (month < 10 ? "0" : "") + month + "-" + (day < 10 ? "0" : "") + day + " 00:00:00";
};
// Create a pretty stopdate display string
Ent.scheduled.stopdateDisplayString = function(year,month,day){
	var maxDays, monthInfo;
	var scheduleDate = Ent.scheduled.getScheduleDate(year);
	day = Ent.scheduled.getDay(Ent.isNUN(day) && scheduleDate ? scheduleDate : day);
	month = Ent.scheduled.getMonth(Ent.isNUN(month) && scheduleDate ? scheduleDate : month);
	year = Ent.scheduled.getYear(scheduleDate ? scheduleDate : year);
	maxDays = Ent.scheduled.daysInMonth(month,year);
	if(day > maxDays){day = maxDays;}
	monthInfo = Ent.dateHelper.months[month];
	return monthInfo.abbrev + (monthInfo.abbrev === monthInfo.full ? " " : ". ") + day + ", " + year;
};
// Fill the stopdate fields with a valid stopdate strings
Ent.scheduled.calcStopdate = function(year,month,day){Ent.setElementValue("clientField.entango_scheduled_stopdate",Ent.scheduled.stopdateString(year,month,day));if(Ent.client && Ent.isFunction(Ent.client.calcStopdate)){Ent.client.calcStopdate(year,month,day);}};
Ent.scheduled.datePicker = (function(){
	var childWindow;
	return {
		open: function(){
			if(Ent.isNUN(childWindow)){childWindow = window.open("/entango/html/EndDatePicker.html","datepicker" + (new Date()).getTime(),"height=225,width=275,resizable=yes,toolbar=no,status=no,scrollbars=no,menubar=no",true);}
			else if(childWindow.closed === true){childWindow = window.open("/entango/html/EndDatePicker.html","datepicker" + (new Date()).getTime(),"height=225,width=275,resizable=yes,toolbar=no,status=no,scrollbars=no,menubar=no",true);}
			else{childWindow.location.reload();}
			childWindow.focus();
		},
		close: function(){if(!Ent.isNUN(childWindow) && !childWindow.closed){childWindow.closeDatePicker();childWindow.close();}},
		reload: function(){if(!Ent.isNUN(childWindow) && !childWindow.closed){childWindow.location.reload();childWindow.focus();}}
	};
}());
}}else{window.alert("Ent.scheduled already defined outside Entango code.");}


