/***********************************************************************
*                                                                      *
*  Interactive Calendar & Appointments Component                       *
*  ------------------------------------------------------------------  *
*  (c) 2010 by Andreas Windt for IT-Direkt Business Technologies GmbH  *
*                                                                      *
***********************************************************************/
if (typeof(cab_calendarModlet) == "undefined" && typeof(Prototype) != "undefined")
	var cab_calendarModlet = Class.create({
		initialize: function( element, options ) {
			this.element = $(element);
			this.options = Object.extend({
				browse_months:		false,
				browse_days:		false,
				show_appointments:	false,
				month:				(new Date()).getMonth() + 1,
				day:				(new Date()).getDate(),
				year:				(new Date()).getFullYear(),
				modletid:			0,
				daynames:			["M", "T", "W", "T", "F", "S", "S"],
				monthnames:			["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
			}, options || {});
			if (this.options.modletid == 0) throw "xx-Error :: No Modlet info found! Cannot proceed without.";
			if (this.options.browse_months) {
				var temp;
				if (!!(temp = this.element.down(".cab_calendar_navigate_prev")))
					temp.observe("click", function( event ) { this.loadPreviousMonth(); event.stop(); }.bind(this));
				if (!!(temp = this.element.down(".cab_calendar_navigate_next")))
					temp.observe("click", function( event ) { this.loadNextMonth(); event.stop(); }.bind(this));
			}
			this.monthview = [];
			this.loadCurrentMonth();
		},
		loadPreviousMonth: function() {
			if ((--this.options.month) == 0) {
				this.options.month = 12;
				--this.options.year;
			}
			this.loadCurrentMonth();
		},
		loadNextMonth: function() {
			if ((++this.options.month) == 13) {
				this.options.month = 1;
				++this.options.year;
			}
			this.loadCurrentMonth();
		},
		loadCurrentMonth: function() {
			this.element.down(".cab_calendar_yearview").down(".cab_calendar_loader").show();
			this.month_responder = new Ajax.Request("/app/modlets/calendar/", {
				parameters: ("modletid=" + this.options.modletid + "&mode=monthview&month=" + this.options.month + "&year=" + this.options.year + "&day=" + this.options.day),
				evalJSON: true,
				onSuccess: function( transport ) {
					if (transport.responseJSON) {
						this.manageMonthFromJSON(transport.responseJSON);
						this.element.down(".cab_calendar_yearview").down(".cab_calendar_loader").hide();
					}
					// else: could not process fetched calendar details
				}.bind(this),
				onFailure: function( transport ) {
					// error #transport.status# while fetching calendar details
				}.bind(this)
			});
			if (this.options.show_appointments)
				this.loadAppointments();
		},
		manageMonthFromJSON: function( json ) {
			var target, line, mv, week, ww, day, date, todd = (new Date()).getDate(), todm = (new Date()).getMonth() + 1, tody = (new Date()).getFullYear();
			if (!Object.isArray(json.monthview))
				return;
			this.monthview = json.monthview;
			line = new Element("div", { "class": "cab_calendar_events_header" });
			target = this.element.down(".cab_calendar_yearview").down(".cab_calendar_eventlist");
			target.select(".cab_calendar_date", ".cab_calendar_events_header").invoke("remove");
			target.insert({ top: line });
			ww = this.options.daynames;
			day = ww.length;
			while (day--)
				line.insert({ top: (new Element("span", { "class": ("cab_calendar_weekday cab_calendar_weekday" + (day+1)) })).update(ww[day]) });
			line.insert({ top: new Element("span", { "class": "cab_calendar_weekday cab_calendar_weekofyear" }) });
			target = line;
			mv = this.monthview;
			week = mv.length;
			while (week--) {
				line = new Element("div", { "class": "cab_calendar_date" });
				ww = mv[week].days;
				day = ww.length;
				while (day--) {
					date = (new Element("span", { "class": ("cab_calendar_weekday cab_calendar_weekday" + (day+1)) })).update(ww[day].date);
					if (ww[day].currentmonth != "true")
						date.addClassName("cab_calendar_disable");
					if (ww[day].events == "true")
						date.addClassName("cab_calendar_event");
					if (todd == ww[day].date && todm == ww[day].month && tody == ww[day].year)
						date.addClassName("cab_calendar_date_today");
					if (this.options.day == ww[day].date && this.options.month == ww[day].month && this.options.year == ww[day].year) {
						if (!!this.date_element)
							this.date_element.removeClassName("cab_calendar_date_selected");
						this.date_element = date.addClassName("cab_calendar_date_selected");
					}
					if (this.options.browse_days && this.options.show_appointments && (this.options.month == ww[day].month || this.options.browse_months))
						date.observe("mouseover", function( event ) { Event.element(event).addClassName("cab_calendar_weekday_hover"); })
							.observe("mouseout", function( event ) { Event.element(event).removeClassName("cab_calendar_weekday_hover"); })
							.observe("click", function( event ) { this.loadAppointmentsByElement(Event.element(event)); }.bind(this));
					ww[day].element = date;
					line.insert({ top: date });
				}
				target.insert({ after: line.insert({ top: (new Element("span", { "class": "cab_calendar_weekday cab_calendar_weekofyear" })).update(mv[week].weekofyear) }) });
			}
			target = this.element.down(".cab_calendar_yearview");
			target.down(".cab_calendar_navigate_current").update(this.options.monthnames[this.options.month - 1]);
			target.down(".cab_calendar_navigate_prev").down("a").writeAttribute("title", this.options.monthnames[(this.options.month - 2) < 0 ? 11 : (this.options.month - 2)]);
			target.down(".cab_calendar_navigate_next").down("a").writeAttribute("title", this.options.monthnames[this.options.month == 12 ? 0 : this.options.month]);
		},
		loadAppointments: function( year, month, day ) {
			this.element.down(".cab_calendar_appointments").down(".cab_calendar_loader").show();
			var refresh_monthview = false;
			year = year || this.options.year;
			month = month || this.options.month;
			if (year != this.options.year || month != this.options.month)
				refresh_monthview = true;
			this.options.year = year || this.options.year;
			this.options.month = month || this.options.month;
			this.options.day = day || this.options.day;
			this.appointments_responder = new Ajax.Request("/app/modlets/calendar/", {
				parameters: ("modletid=" + this.options.modletid + "&mode=appointments&month=" + this.options.month + "&year=" + this.options.year + "&day=" + this.options.day),
				evalJSON: true,
				onSuccess: function( transport ) {
					if (transport.responseText) {
						var c = this.element.down(".cab_calendar_appointments").down(".cab_calendar_eventlist");
						c.select(".cab_calendar_date", ".cab_calendar_event", ".cab_calendar_message").invoke("remove");
						c.insert({ top: decode(transport.responseText) });
						this.element.down(".cab_calendar_appointments").down(".cab_calendar_loader").hide();
					}
					// else: could not process fetched appointments
				}.bind(this),
				onFailure: function( transport ) {
					// error #transport.status# while fetching appointments
				}.bind(this)
			});
			if (refresh_monthview)
				this.loadCurrentMonth();
		},
		loadAppointmentsByElement: function( element ) {
			if (Object.isUndefined(element))
				return;
			var mv = this.monthview, week = mv.length, ww, day;
			while (week--) {
				ww = mv[week].days;
				day = ww.length;
				while (day--)
					if (ww[day].element == element) {
						if (!!this.date_element)
							this.date_element.removeClassName("cab_calendar_date_selected");
						this.date_element = ww[day].element.addClassName("cab_calendar_date_selected");
						return this.loadAppointments(ww[day].year, ww[day].month, ww[day].date);
					}
			}
		}
	});

