/**
 * Saxotech CCE Event Recurrence Model Javascript
 * Requires jQuery 1.3.2+
 * Requires Greatwest Date.Prototype.js
**/

function SaxotechRecurrenceModel(form, p) {
	this.Settings = {
		Form: null,
		FieldArea: null,
		Preview : false,
		PreviewContent : $("div#evtPreviewTemplate").html(),
		Pattern : 1,
		FromTime: '0800',
		ToTime: '1700',
		TimeType: 0,
		Daily : {
			FromDate : new Date().addDays(1).zeroTime(),
			ToDate : new Date().addDays(1).zeroTime(),
			NumberOfOcc : 1,
			StopMethod : 1,
			SubPattern: 1,
			Jump1 : 1
		},
		Weekly : {
			FromDate : new Date().addDays(1).zeroTime(),
			ToDate : new Date().addDays(1).zeroTime(),
			NumberOfOcc : 1,
			StopMethod : 1,
			Pattern: 1,
			SubPattern: 1,
			Jump1 : 1,
			Jump2 : 1,
			Day1 : false,
			Day2 : true,
			Day3 : false,
			Day4 : false,
			Day5 : false,
			Day6 : false,
			Day7 : false
		},
		Monthly : {
			FromDate : new Date().addDays(1).zeroTime(),
			ToDate : new Date().addDays(1).zeroTime(),
			NumberOfOcc : 1,
			StopMethod : 1,
			Pattern: 1,
			SubPattern: 1,
			Jump11 : 1,
			Jump12 : 1,
			Jump21 : 1,
			Jump22 : 1,
			Weekday: 1
		}
	};

	this.Preview = {
		Target: null,
		Container: null,
		Title: null,
		Times: null,
		Venue: null,
		Address: null,
		City: null,
		Contact: null,
		Calendar: null,
		Description: null
	};
	
	this.FieldTemplate = '<input type="hidden" name="{0}" value="{1}" />';

	this.Settings.Form = $("#"+form);
	if (p) {
		this.Settings.Preview = true;
	};
	var $this = this;
	
	this.GetDates = function() {
		switch ($this.Settings.Pattern) {
			case 1:
				return GetDates_Daily();
				break;
			case 2:
				return GetDates_Weekly();
				break;
			case 3:
				return GetDates_Monthly();
				break;
			default:
				alert('No pattern specified!');
				break;
		};
	};
	
	function GetDates_Daily() {
		var Dates = [];
		var CurrentDate = $this.Settings.Daily.FromDate.Clone().zeroTime();
		var EndDate = $this.Settings.Daily.ToDate.Clone().zeroTime();
		switch ($this.Settings.Daily.StopMethod) {
			case 0:
				var sp = $this.Settings.Daily.SubPattern;
				while (CurrentDate.IsLessOrEqual(EndDate)) {
					if (sp==1) {
						Dates[Dates.length] = CurrentDate.Clone();
						CurrentDate.addDays($this.Settings.Daily.Jump1);
					} else {
						if (CurrentDate.isWeekDay()) { Dates[Dates.length] = CurrentDate.Clone(); };
						CurrentDate.addDays(1);
					};
				};
				break;
			case 1:
				var sp = $this.Settings.Daily.SubPattern;
				while (Dates.length<$this.Settings.Daily.NumberOfOcc) {
					if (sp==1) {
						Dates[Dates.length] = CurrentDate.Clone();
						CurrentDate.addDays($this.Settings.Daily.Jump1);
					} else {
						if (CurrentDate.isWeekDay()) { Dates[Dates.length] = CurrentDate.Clone(); };
						CurrentDate.addDays(1);
					};
				};
				break;
			default:
				alert("Stop method undefined");
				break;
		};
		return Dates;
	};
	
	function GetDates_Weekly() {
		var Dates = [];
		var w = $this.Settings.Weekly;
		if (w.Day1 || w.Day2 || w.Day3 || w.Day4 || w.Day5 || w.Day6 || w.Day7) {
			var CurrentDate = w.FromDate.Clone().zeroTime();
			switch ($this.Settings.Weekly.StopMethod) {
				case 0:
					var EndDate = $this.Settings.Weekly.ToDate.Clone().zeroTime();
					var x = 1;
					while (CurrentDate.IsLessOrEqual(EndDate)) {
						if ($this.Settings.Weekly['Day'+(CurrentDate.getDay()+1)]) { Dates[Dates.length] = CurrentDate.Clone(); };
						CurrentDate.addDays(1).zeroTime();
						if (x==7 && $this.Settings.Weekly.Jump1 > 1) {
							CurrentDate.addDays(x*($this.Settings.Weekly.Jump1-1)).zeroTime();
							x = 1;
						} else {
							x++;
						};
					};
					break;
				case 1:
					var x = 1;
					while (Dates.length<$this.Settings.Weekly.NumberOfOcc) {
						if ($this.Settings.Weekly['Day'+(CurrentDate.getDay()+1)]) { Dates[Dates.length] = CurrentDate.Clone(); };
						CurrentDate.addDays(1);
						if (x==7 && $this.Settings.Weekly.Jump1 > 1) {
							CurrentDate.addDays(x*($this.Settings.Weekly.Jump1-1)).zeroTime();
							x = 1;
						} else {
							x++;
						};
					};
					break;
				default:
					alert("Stop method undefined");
					break;
			};
		};
		return Dates;
	};
	
	function GetDates_Monthly() {
		var Dates = [];
		var m = $this.Settings.Monthly;
		var CurrentDate = m.FromDate.Clone().zeroTime();
		switch(m.StopMethod) {
			case 0:
				if (m.SubPattern == 1) {
					CurrentDate.setDate(m.Jump11);
					if (CurrentDate < m.FromDate) { CurrentDate.addMonths(1); };
					while (CurrentDate <= m.ToDate) {
						Dates[Dates.length] = CurrentDate.Clone().zeroTime();
						CurrentDate.addMonths(m.Jump12);
					};
				} else {
					CurrentDate = Date.getNthDayOfMonth(m.Jump21, m.Weekday-1, m.FromDate.getMonth(), m.FromDate.getFullYear());
					if (CurrentDate < m.FromDate) {
						CurrentDate.addMonths(1);
						CurrentDate.getNthDayOfMonth(m.Jump21, m.Weekday-1);
					};
					while (CurrentDate <= m.ToDate) {
						Dates[Dates.length] = CurrentDate.Clone().zeroTime();
						CurrentDate.addMonths(m.Jump22);
						CurrentDate.getNthDayOfMonth(m.Jump21, m.Weekday-1);
					};
				};
				break;
			case 1:
				if (m.SubPattern == 1) {
					CurrentDate.setDate(m.Jump11);
					if (CurrentDate < m.FromDate) { CurrentDate.addMonths(1); };
					while (Dates.length < m.NumberOfOcc) {
						Dates[Dates.length] = CurrentDate.Clone().zeroTime();
						CurrentDate.addMonths(m.Jump12);
					};
				} else {
					CurrentDate = Date.getNthDayOfMonth(m.Jump21, m.Weekday-1, m.FromDate.getMonth(), m.FromDate.getFullYear());
					if (CurrentDate < m.FromDate) {
						CurrentDate.addMonths(1);
						CurrentDate.getNthDayOfMonth(m.Jump21, m.Weekday-1);
					};
					while (Dates.length < m.NumberOfOcc) {
						Dates[Dates.length] = CurrentDate.Clone().zeroTime();
						CurrentDate.addMonths(m.Jump22);
						CurrentDate.getNthDayOfMonth(m.Jump21, m.Weekday-1);
					};
				};
				break;
			default:
				alert("Stop method undefined");
				break;
		};
		return Dates;
	};
	
	function InitPreview() {
		$(document.body).append("<div id='previewTip'></div>");
		$this.Preview.Target = $("#previewTip");
		$($this.Preview.Target).qtip({
            content: { title: { text: ""}, text: $this.Settings.PreviewContent },
            position: { target: $(document.body), corner: 'topRight', adjust: { x: -30, y: 20 } },
            show: { when: 'click', solo: true },
            hide: false,
			style: {name: 'light', width: 500, border: { width: 2, radius: 8, color: '#3C3C3C' } },
			api: {
				onShow: function() {
					$this.Preview.Container = $($this.Preview.Target).qtip("api");
					$this.Preview.Calendar = $this.Preview.Container.elements.content.find(".previewCalendar").Calendar();
					UpdatePreviewCalendar();
				},
				onHide: function() { DestroyTip(); }
			}
        });
		$($this.Preview.Target).trigger("click");
	};
	
	function DestroyTip(t) {
		$($this.Preview.Target).qtip("destroy");
		$($this.Preview.Target).remove();
	};
	
	if (this.Settings.Preview) {
		InitPreview();
		$(":input[SRMPreview]").bind("blur", function() {
			UpdatePreviewField(this);
			$("#"+this.id).unbind("blur");
			$("#"+this.id).bind("change", function() {
				UpdatePreviewField(this);
			});
		});
	};
	
	function UpdatePreviewField(el,v) {
		var f = el.attributes["SRMPreview"].value;
		if (f=='Title') {
			$this.Preview.Container.updateTitle("<h1>"+el.value+"</h1>");
		} else {
			$this.Preview.Container.elements.content.find("#lbl"+f).text(el.value);
		};
	};
	
	$(":input[SRMField]").bind("change", function() {
		UpdateSetting(this);
	});
	
	$(":input:not(:radio)[SRMField]").bind("blur", function() {
		UpdateSetting(this);
		$(this).unbind("blur");
		$(this).bind("change", function() {
			UpdateSetting(this);
		});
	});
	
	function UpdateSetting(el) {
		var f = el.attributes["SRMField"].value.split(".");
		var t = el.attributes["SRMType"].value;
		if (f.length <= 2) {
			switch (t) {
				case "number":
					var v = Number(this.value);
					if (f.length == 1) { $this.Settings[f] = Number(el.value); } else { $this.Settings[f[0]][f[1]]= Number(el.value); };
					break;
				case "date":
					var v = new Date().fromFormat(el.value, "mm/dd/yyyy").zeroTime();
					if (f.length == 1) { $this.Settings[f] = v; } else { $this.Settings[f[0]][f[1]] = v; };
					CheckToDate(f[0],f[1]);
					break;
				case 'boolean':
					var v = false;
					if (el.type == 'checkbox') {
						v = el.checked;
					} else {
						if (el.value.length > 0) { v = Boolean(el.value); };
					};
					if (f.length == 1) { $this.Settings[f] = v; } else { $this.Settings[f[0]][f[1]] = v; };
					break;
				case 'time':
					var v = el.value;
					if (f.length == 1) { $this.Settings[f] = v; } else { $this.Settings[f[0]][f[1]] = v; };
					break;
				default:
					if (f.length == 1) { $this.Settings[f] = el.value; } else { $this.Settings[f[0]][f[1]] = el.value; };
					break;
			};
			if ($this.Settings.Preview) {
				UpdatePreviewCalendar();
			};
		} else {
			alert('Invalid SRM attribute!');
		};
	};
	
	
	function UpdatePreviewCalendar() {
		var evtDates = $this.GetDates();
		var ds = [];
		for (i=0;i<evtDates.length;i++) {
			ds[ds.length] = evtDates[i].toFormat("yyyymmdd");
		};
		$this.Preview.Calendar.setDates(ds);
		switch ($this.Settings.TimeType) {
			case 0:
				var t = '';
				t+= $this.Settings.FromTime + '';
				if ($this.Settings.ToTime.length>0) { t+= ' to ' + $this.Settings.ToTime; };
				$this.Preview.Container.elements.content.find("#lblTime").html(t);
				break;
			case 1:
				$this.Preview.Container.elements.content.find("#lblTime").html("All Day");
				break;
			case 2:
				$this.Preview.Container.elements.content.find("#lblTime").html("No Times");
				break;
		};
	};
	
	function CheckToDate(a,b) {
		if ($this.Settings[a].ToDate < $this.Settings[a].FromDate) {
			$this.Settings[a].ToDate = $this.Settings[a].FromDate.Clone();
			var i = ('input[SRM="{0}.ToDate"]').replace('{0}',a);
			$(i).val($this.Settings[a].ToDate.toFormat("mm/dd/yyyy"));
		};
	};
	
	this.WriteFields = function() {
		if (!$this.Settings.FieldArea) {
			$($this.Settings.Form).append('<div id="SRMFieldArea" class="hide"></div>');
			$this.Settings.FieldArea = $("#SRMFieldArea");
		};
		var D = $this.GetDates();
		$this.Settings.FieldArea.empty();
		var f = '';
		f+= $this.FieldTemplate.split('{0}').join("Pattern").split("{1}").join($this.Settings.Pattern);
		if ($this.Settings.TimeType==0) {
				f+= $this.FieldTemplate.split("{0}").join("FromTime").split("{1}").join($this.Settings.FromTime);
				f+= $this.FieldTemplate.split("{0}").join("ToTime").split("{1}").join($this.Settings.ToTime);
		};
		f+= $this.FieldTemplate.split("{0}").join("Date").split("{1}").join(D[0].toFormat("yyyymmdd"));
		f+= $this.FieldTemplate.split("{0}").join("Expires").split("{1}").join(D[D.length-1].toFormat("yyyymmdd"));
		switch ($this.Settings.Pattern) {
			case 1:
				f+= $this.FieldTemplate.split("{0}").join("FromDate").split("{1}").join($this.Settings.Daily.FromDate.toFormat("yyyymmdd"));
				f+= $this.FieldTemplate.split("{0}").join("StopMethod").split("{1}").join($this.Settings.Daily.StopMethod);
				f+= $this.FieldTemplate.split("{0}").join("ToDate").split("{1}").join($this.Settings.Daily.ToDate.toFormat("yyyymmdd"));
				f+= $this.FieldTemplate.split("{0}").join("NumberOfOcc").split("{1}").join($this.Settings.Daily.NumberOfOcc);
				f+= $this.FieldTemplate.split("{0}").join("Pattern1Sub").split("{1}").join($this.Settings.Daily.SubPattern);
				f+= $this.FieldTemplate.split("{0}").join("Pattern1Sub1Jump1").split("{1}").join($this.Settings.Daily.Jump1);
				break;
			case 2:
				f+= $this.FieldTemplate.split("{0}").join("FromDate").split("{1}").join($this.Settings.Weekly.FromDate.toFormat("yyyymmdd"));
				f+= $this.FieldTemplate.split("{0}").join("StopMethod").split("{1}").join($this.Settings.Weekly.StopMethod);
				f+= $this.FieldTemplate.split("{0}").join("ToDate").split("{1}").join($this.Settings.Weekly.ToDate.toFormat("yyyymmdd")+'');
				f+= $this.FieldTemplate.split("{0}").join("NumberOfOcc").split("{1}").join($this.Settings.Weekly.NumberOfOcc);
				f+= $this.FieldTemplate.split("{0}").join("Pattern2Sub").split("{1}").join($this.Settings.Weekly.SubPattern);
				f+= $this.FieldTemplate.split("{0}").join("Pattern2Sub1Jump1").split("{1}").join($this.Settings.Weekly.Jump1);
				f+= $this.FieldTemplate.split("{0}").join("Pattern2Sub1Day1").split("{1}").join((($this.Settings.Weekly.Day1) ? '1' : ''));
				f+= $this.FieldTemplate.split("{0}").join("Pattern2Sub1Day2").split("{1}").join((($this.Settings.Weekly.Day2) ? '1' : ''));
				f+= $this.FieldTemplate.split("{0}").join("Pattern2Sub1Day3").split("{1}").join((($this.Settings.Weekly.Day3) ? '1' : ''));
				f+= $this.FieldTemplate.split("{0}").join("Pattern2Sub1Day4").split("{1}").join((($this.Settings.Weekly.Day4) ? '1' : ''));
				f+= $this.FieldTemplate.split("{0}").join("Pattern2Sub1Day5").split("{1}").join((($this.Settings.Weekly.Day5) ? '1' : ''));
				f+= $this.FieldTemplate.split("{0}").join("Pattern2Sub1Day6").split("{1}").join((($this.Settings.Weekly.Day6) ? '1' : ''));
				f+= $this.FieldTemplate.split("{0}").join("Pattern2Sub1Day7").split("{1}").join((($this.Settings.Weekly.Day7) ? '1' : ''));
				break;
			case 3:
				var f = '';
				f+= $this.FieldTemplate.split("{0}").join("FromDate").split("{1}").join($this.Settings.Monthly.FromDate.toFormat("yyyymmdd"));
				f+= $this.FieldTemplate.split("{0}").join("StopMethod").split("{1}").join($this.Settings.Monthly.StopMethod);
				f+= $this.FieldTemplate.split("{0}").join("ToDate").split("{1}").join($this.Settings.Monthly.ToDate.toFormat("yyyymmdd"));
				f+= $this.FieldTemplate.split("{0}").join("NumberOfOcc").split("{1}").join($this.Settings.Monthly.NumberOfOcc);
				f+= $this.FieldTemplate.split("{0}").join("Pattern3Sub").split("{1}").join($this.Settings.Monthly.SubPattern);
				f+= $this.FieldTemplate.split("{0}").join("Pattern3Sub1Jump1").split("{1}").join($this.Settings.Monthly.Jump11);
				f+= $this.FieldTemplate.split("{0}").join("Pattern3Sub1Jump2").split("{1}").join($this.Settings.Monthly.Jump12);
				f+= $this.FieldTemplate.split("{0}").join("Pattern3Sub2Jump1").split("{1}").join($this.Settings.Monthly.Jump21);
				f+= $this.FieldTemplate.split("{0}").join("Pattern3Sub2Jump2").split("{1}").join($this.Settings.Monthly.Jump22);
				f+= $this.FieldTemplate.split("{0}").join("Pattern3Sub2Day").split("{1}").join($this.Settings.Monthly.Weekday);
				break;
		};
		$this.Settings.FieldArea.append(f);
	};

	this.Destroy = function() {
		if (this.Settings.Preview) {
			$this.Preview.Container.hide();
		};
	};
};
