/*
	Copyright (c) 2006-2007, ePages GmbH
	All Rights Reserved.
*/
dojo.provide("epages.cartridges.de_epages.calendar.widget.Appointmentcalendar");
dojo.require("epages.widget.Calendar");
dojo.require("epages.lang.array");
dojo.require('epages.io.json');
dojo.require("dojo.date.stamp");
dojo.require('epages.lang.hitch');
dojo.require("epages.cartridges.de_epages.calendar.widget.Appointmenttimeitem");
dojo.require("epages.widget.Tooltip");

dojo.declare(
	"epages.cartridges.de_epages.calendar.widget.Appointmentcalendar",
	epages.widget.Calendar,
	{

		/**
		 * public properties
		 */
		objectId: '', // CalendarId
		productId: '',
		datastoreId: 'Datastore',
		waitForFloating: '500',
		availableQuantity: '',
		requestedQuantity: '',
		requestedMinutes: '',

		url: '?',
		classNames: null,
		appointmentClassNames: {
			'IsLocked': 'Locked',
			'IsUsed'  : 'Used',
			'IsBusy'  : 'Busy'
		},

		_appListSmallTemplateString :	'<div class="AppointmentListSmall"><table><thead>'
			+'	<tr class="AppointmentItem Small">'
			+'		<th class="Time">{Time}</td>'
			+'		<th class="NumberOfDates">{NumberOfDates}</td>'
			+'		<th class="BookedBy">{BookedBy}</td>'
			+'	</tr></thead>'
			+'<tfoot></tfoot><tbody><tr class="NoDates"><td colspan="3">{NoDates}</td></tbody></table></div>',

		_timeoutShortList: undefined, // _onOver, _onOut, resetTimeouts
		_timeoutListDate: undefined,  // _onOver, _onOut, resetTimeouts
		_visibleFloating: undefined,  // _onOver, _onOut, resetTimeouts
		_visibleOverview: undefined,  // _onClick

		_dictionary: undefined,

		_dateFormats: null,
		_datastore: undefined,
		_monthMoveCount: undefined,
		_moveCountInterval: undefined,

		postMixInProperties: function () {
			this.inherited('postMixInProperties',arguments);
			this.classNames= [];
			this._dateFormats = {};
			this._monthMoveCount = {
				step: 0,
				amount: ''
			};
			for(var name in this.appointmentClassNames) {
				if (this.classNames[name] === undefined){
					this.classNames[name] = this.appointmentClassNames[name];
				}
			}
			if($$(this.datastoreId)){
				this._datastore = $$(this.datastoreId);
			}
			// prepare template
			dojo.require('epages.io.translation');
			this._dictionary = new epages.io.Translation(dojo.moduleUrl('epages.cartridges.de_epages.calendar.widget', "templates/translation"), "auto");
			this._appListSmallTemplateString = this._dictionary.replaceLanguageTags(this._appListSmallTemplateString);
		},

		postCreate: function () {
			this.inherited('postCreate',arguments);
			this.connect(this.domNode, "onmouseover", "_onOver");
			this.connect(this.domNode, "onmouseout",  "_onOut");
			this.connect(this.domNode, "onmousedown", "_onClick");
			//change connects for increment/decrement month/year to avoid errors with reloaded content
			this.connect(this.incrementMonth ,"onmousedown", function(){
				this._countMonthMoves('month',1);
			});
			this.connect(this.incrementMonth ,"onmouseup", '_doMonthMoves');
			this.connect(this.decrementMonth ,"onmousedown", function(){
				this._countMonthMoves('month', -1);
			});
			this.connect(this.decrementMonth ,"onmouseup", '_doMonthMoves');
			this.connect(this.nextYearLabelNode ,"onclick", function(){
				this._adjustDisplay('year', 1);
			});
			this.connect(this.previousYearLabelNode ,"onclick", function(){
				this._adjustDisplay('year', -1);
			});
		},

		_countMonthMoves: function(amount,step){
			this._addMonthStep(amount,step);
			this._moveCountInterval = window.setInterval(dojo.hitch(this,function(amount,step){
				this._addMonthStep(amount,step);
			},amount,step),500);
		},

		_doMonthMoves: function(){
			window.clearInterval(this._moveCountInterval);
			this._adjustDisplay(this._monthMoveCount.amount, this._monthMoveCount.step);
			this._monthMoveCount.amount = '';
			this._monthMoveCount.step = 0;
		},

		_addMonthStep:function(amount,step){
			this._monthMoveCount.amount = amount;
			this._monthMoveCount.step = this._monthMoveCount.step + step;
			var month = dojo.date.add(this.displayMonth, this._monthMoveCount.amount, this._monthMoveCount.step);
			// Fill in localized month name
			var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
			this._setText(this.monthLabelNode, monthNames[month.getMonth()]);
		},

		_onReceiveRequest: function (result) {
			if(!result){
				return false;
			}
			var pad = dojo.string.pad;
			dojo.query(".dijitCalendarDateLabel", this.domNode).forEach(function(label, i){
				var node = this._dateNode(label);
				if(node){//in some wired cases node can be undefined
					var nodeDate = new Date(node.dijitDateValue);
					var datekey = [pad(nodeDate.getFullYear(), 4), pad(nodeDate.getMonth() + 1, 2), pad(nodeDate.getDate(), 2)].join("-");
					var dateData = result[datekey+'T00:00:00'];
					for(var key in dateData) {
						if(this.classNames[key]){
							if (dateData[key] == 1) {
								dojo.addClass(node, this.classNames[key]);
							} else {
								dojo.removeClass(node, this.classNames[key]);
							}
						}
					}
				}
			}, this);
		},

		_originalPopulateGrid: function(){
			var month = this.displayMonth;
			month.setDate(1);
			var firstDay = month.getDay();
			var daysInMonth = dojo.date.getDaysInMonth(month);
			var daysInPreviousMonth = dojo.date.getDaysInMonth(dojo.date.add(month, "month", -1));
			var today = new Date();
			var selected = this.value;

			var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
			if(dayOffset > firstDay){ dayOffset -= 7; }

			// Iterate through dates in the calendar and fill in date numbers and style info
			dojo.query(".dijitCalendarDateTemplate", this.domNode).forEach(function(template, i){
				i += dayOffset;
				var date = new Date(month);
				var number, clazz = "dijitCalendar", adj = 0;

				if(i < firstDay){
					number = daysInPreviousMonth - firstDay + i + 1;
					adj = -1;
					clazz += "Previous";
				}else if(i >= (firstDay + daysInMonth)){
					number = i - firstDay - daysInMonth + 1;
					adj = 1;
					clazz += "Next";
				}else{
					number = i - firstDay + 1;
					clazz += "Current";
				}

				if(adj){
					date = dojo.date.add(date, "month", adj);
				}
				date.setDate(number);

				if(!dojo.date.compare(date, today, "date")){
					clazz = "dijitCalendarCurrentDate " + clazz;
				}

				if(!dojo.date.compare(date, selected, "date")){
					clazz = "dijitCalendarSelectedDate " + clazz;
				}

				if(this.isDisabledDate(date, this.lang)){
					clazz = "dijitCalendarDisabledDate " + clazz;
				}

				template.className =  clazz + "Month dijitCalendarDateTemplate";
				template.dijitDateValue = date.valueOf();
				var label = dojo.query(".dijitCalendarDateLabel", template)[0];
				this._setText(label, date.getDate());
			}, this);

			// Fill in localized month name
			var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
			this._setText(this.monthLabelNode, monthNames[month.getMonth()]);

			// Fill in localized prev/current/next years
			var y = month.getFullYear() - 1;
			var d = new Date();
			dojo.forEach(["previous", "current", "next"], function(name){
				d.setFullYear(y++);
				this._setText(this[name+"YearLabelNode"], d.getFullYear() );
			}, this);
		},

		_populateGrid: function (days) {
			this.inherited('_populateGrid', arguments);
			this._originalPopulateGrid();
			this.displayMonth.setMinutes(0);
			this.displayMonth.setSeconds(0);
			this.displayMonth.setHours(0);
			if(this._datastore){
				this._onReceiveRequest(this._datastore.getDateFormats({
					objectId  : this.objectId,
					startDate : this.displayMonth,
					endDate   : dojo.date.add(this.displayMonth, "day", dojo.date.getDaysInMonth(this.displayMonth)),
					available : this.availableQuantity,
					requested : this.requestedQuantity,
					requestedMinutes : this.requestedMinutes
				}));
			}
		},

		resetTimeouts: function() {
			clearTimeout(this._timeoutShortList);
		},

		_onOver: function (evt) {

			this.resetTimeouts();
			var dateNode = this._dateNode(evt.target);
			if (!dateNode){
				return;
			}
			this._timeoutListDate = dateNode.dijitDateValue;
			var x = evt.clientX + document.documentElement.scrollLeft;
			var y = evt.clientY + document.documentElement.scrollTop;
			this._timeoutShortList = setTimeout(epages.lang.hitch(this, this.showShortList, [dateNode, x, y]), Number(this.waitForFloating));
		},

		_onOut: function (evt) {
			this.resetTimeouts();
		},

		_onClick: function (evt) {
			this.resetTimeouts();

			var dateNode = this._dateNode(evt.target);
			if (!dateNode){
				return;
			}
			var dateString = dateNode.dijitDateValue;
			dojo.publish(this.id+'/select',[{date: new Date(dateString)}]);
		},

		findDateElement: function (dateString) {
			var dateNode = null;
			dojo.query(".dijitCalendarDateLabel", this.domNode).forEach(function(label, i){
				var node = this._dateNode(label);
				if (node.dijitDateValue == dateString){
					dateNode = node;
				}
			});
			return dateNode;
		},

		loadLists: function(dateString, listName) {
			if ($(listName +'_' + dateString) == null) {
				// load data from datastore
				var data = this._datastore.getDayList(new Date(Number(dateString)));

				// create floating list
				// for positioning var dateTd = this.findDateElement(dateString);
				var floatingDiv = document.createElement('div');
				floatingDiv.id = 'floating_' + dateString;
				floatingDiv.style.display = 'none';
				floatingDiv.className="AppointmentListSmallWrapper";
				floatingDiv.innerHTML=this._appListSmallTemplateString;

				$(this.domNode.parentNode).insertBefore(floatingDiv, this.domNode);

				// fill lists with data
				// filelist.setChildren(data);
				var e,d;
				for( var i=0,l=data.length ; i<l ; i++ ) {
					d = data[i];
					d.objectId = this.objectId;
					d.productId  = this.productId;
					d.url = this.url;
					d.isinactive = (dojo.date.stamp.fromISOString(d.EndDate) < new Date()) ? '1' : '0';
					d.availableQuantity = this.availableQuantity;

					if (d.IsBusiness || d.Appointments.length > 0) {
						e = document.createElement('tr');
						floatingDiv.getElementsByTagName("tbody")[0].appendChild(e);
						new epages.cartridges.de_epages.calendar.widget.Appointmenttimeitem(d, e);
					}
				}

				// remove NoDates node if empty
				var tbody=floatingDiv.getElementsByTagName("tbody")[0];
				if(tbody.lastChild.className != "NoDates" ){
					tbody.removeChild(tbody.firstChild);
				}

			}
		},

		showShortList: function(dateNode, x,y) {
			oldTooltip = $$(this._visibleFloating);

			this.loadLists(this._timeoutListDate, 'floating');
			this._visibleFloating = 'floating_' + this._timeoutListDate;

			var tooltip = $$(this._visibleFloating);
			if(tooltip !== oldTooltip){
				oldTooltip.hide();
			}

			if(tooltip === undefined) {
				tooltip = new epages.widget.Tooltip({
					tooltipArea: dateNode,
					interactive: true,
					forceOrientation: 'B',
					'class' : 'Wide Plain'
				}, $(this._visibleFloating));
				tooltip.show(x,y);
			}
		},

		_onDayClick: function(){
				this.inherited('_onDayClick',arguments);
			if (this.timer != null){
				this.timer.fillTimes(this.value);
			}
		}
});