/* Custom calendar plugin */
(function($){
	function counter(){
		if (typeof counter.index == 'undefined'){counter.index = 0;}
		return counter.index++;
	};
	
	// plugin definition
	$.fn.CustomCalendar = function (options){
		if (typeof options == 'string'){
			switch (options){
				// get calendar instance
				case 'get':
					return $(this).data('CustomCalendar');
				break;
				case 'show':
					$(this).data('CustomCalendar').show();
				break;
				default:
					trow('CustomCalendar - unkwnown option');
				break;
			}
			return;
		}
		
		var options = $.extend({}, $.fn.CustomCalendar.defaults, options);
		return this.each(function (){
			$(this).data('CustomCalendar', new CustomCalendar(options, this));
		});
		
		function CustomCalendar(options, el){
			// console.log('CustomCalendar', arguments);
			var
				uid = 'CustomCalendar-'+counter(),
				date = new Date(), // parsed date
				today = new Date(), // today
				element = $(el), // binding element
				last_href = '', // last loaded data
				
				container = null,
				// special_days = {}, // days with fixed travel nights
				return_days = {}, // return days on selected day
				nights_content = '', // nights select
				nights = '', // nights selected
				hotel_only = true; // nights selected
			
			this.render = function (){
				if (options.href){
					var href = options.href;
					if (typeof options.href != 'string'){
						href = options.href.call();
					}
					if (href){
						// add days
						href += '&month='+(date.getMonth()+1);
						href += '&year='+date.getFullYear();
						if (options.nights){
							href += '&min_nights='+options.min_nights;
							href += '&max_nights='+options.max_nights;
						}
						if (options.months_span){
							href += '&months_span='+options.months_span;
						}
						var pos = element.offset();
						pos.top += element.outerHeight();
						if (pos.left+container.outerWidth() > $('body').width()){
							pos.left -= pos.left+container.outerWidth() - $('body').width();
						}
						if (pos.top+container.outerHeight() > $('body').height()){
							pos.top -= pos.top+container.outerHeight() - $('body').height();
						}
						container.css(pos);
						// if changed
						if (href != last_href){
							$('tbody', container).html('<tr><td colspan="7">Loading ...</td></tr>');
							// set title
							// $('.ui-custom-calendar-title', container).html(options.months[date.getMonth()]+' '+date.getFullYear());
							$('.ui-custom-calendar-title select[name=month]', container).val(date.getMonth());
							$('.ui-custom-calendar-title select[name=year]', container).val(date.getFullYear());
							$.getJSON(href, function (data){
								renderDays(data);
								last_href = href;
							});
						}
					}
				}
			};
			
			this.show = function (){
				this.render();
				container.show();
			}
			
			var renderDays = function (days){
				var html = '', sel_date = $.trim(element.val()), sel_date_found = false;
				// special_days = {};
				if (options.nights && options.nights.val()){
					nights = options.nights.val();
				}
				var tr_count = 0, day = false;
				for (i=0;i<days.length;i++){tr_count = Math.max(tr_count, days[i].length);}
				// update month names
				container.find('th.month-n').each(function (i){
					$(this).html(options.months_long[(date.getMonth()+i) % 12]);
				});
				// main loop
				tr_count /= 7;
				for (_tr=0;_tr<tr_count;_tr++){
					html += '<tr>';
					for (_month=0;_month<options.months_span;_month++){
						for (_day=0;_day<7;_day++){
							// console.log('add days[', _month, ']', '[', _tr*7+_day, '] = ', days[_month][_tr*7+_day]);
							day = days[_month][_tr*7+_day];
							if (!day){
								html += '<td class="ui-state-disabled">&nbsp;</td>';
							}
							else if (day.out){
								html += '<td class="ui-state-disabled">'+day.day+'</td>';
							}
							else if (day.enabled){
								// console.log('add days[', _month, ']', '[', _tr*7+_day, '] = ', days[_month][_tr*7+_day], day);
								return_days[day.date] = false;
								hotel_only = typeof(day.return_days) == 'undefined';
								var cls = 'ui-state-default ui-custom-calendar-enabled';
								if (sel_date == day.date){cls += ' ui-state-active'; sel_date_found = day.date;}
								if (day.special){cls += ' ui-custom-calendar-special';}
								if (typeof(day.return_days) !== 'undefined'){
									if (day.return_days){
										return_days[day.date] = '';
										for (j=0;j<day.return_days.length;j++){
											return_days[day.date] += '<option value="'+day.return_days[j]+'">'+day.return_days[j]+'</option>';
										}
									}
								}
								html += '<td><span class="'+cls+'" title="'+day.date+'">'+day.day+'</span></td>';
							}
							else{
								html += '<td class="ui-state-disabled"><span class="ui-state-default">'+day.day+'</span></td>';
							}
						}
						html += '<td class="spacer">&nbsp;</td>';
					}
					html += '</tr>';
				}
				$('tbody', container).html(html);
				// console.log(return_days);
				// hover
				$('tbody .ui-custom-calendar-enabled', container).hover(
					function (){$(this).addClass('ui-state-hover');},
					function (){$(this).removeClass('ui-state-hover');}
				);
				// special hover
				if ($.fn.qtip){
					$('.ui-custom-calendar-special').qtip({
						content: {text: 'This is a special offer', prerender: true}
						, show: { delay: 10 }
					});
				}
				// console.log(hotel_only);
				if (hotel_only){
					options.nights && options.nights.html(nights_content).val(nights);
				}
				else{
					if (!sel_date_found){
						element.val('');
						if (options.nights){options.nights.html('');}
					}
					else{
						if (options.nights){options.nights.html(return_days[sel_date_found]).val(nights);}
					}
				}
			};
			
			this.init = function (){
				// date
				if ($.trim(element.val()) != ''){
					var d = $.trim(element.val()).split('.');
					date.setFullYear(parseInt(d[2], 10), parseInt(d[1], 10)-1, parseInt(d[0], 10));
				}
				// build container
				var html = '<div id="'+uid+'" class="ui-widget ui-widget-content ui-corner-all ui-custom-calendar" unselectable="on" style="width: '+(options.months_span * 7 * 27 + 5)+'px;">';
				html += '<div class="ui-widget-header ui-corner-top ui-custom-calendar-header">';
				html += '<span class="ui-icon ui-icon-circle-triangle-w">Prev</span>';
				html += '<span class="ui-icon ui-icon-circle-triangle-e">Next</span>';
				// html += '<span class="ui-custom-calendar-title">'+options.months[date.getMonth()]+' '+date.getFullYear()+'</span>';
				html += '<span class="ui-custom-calendar-title">';
				var months = [];
				if (options.months_span > 1){
					for (i=0;i<12;i++){months.push('<option value="'+i+'">'+options.months_short[i]+' - '+options.months_short[(i + options.months_span - 1) % 12]+'&nbsp;</option>');}
				}
				else{
					for (i=0;i<12;i++){months.push('<option value="'+i+'">'+options.months_short[i]+'&nbsp;</option>');}
				}
				html += '<select name="month">'+months.join('')+'</select>';
				// html += '<select name="year"><option value="'+today.getFullYear()+'">'+today.getFullYear()+'</option><option value="'+(today.getFullYear()+1)+'">'+(today.getFullYear()+1)+'</option></select>';
				html += '<select name="year">';
				for (i=0;i<options.years_span;i++){
					html += '<option value="'+(today.getFullYear()+i)+'">'+(today.getFullYear()+i)+'</option>';
				}
				html += '</select>';
				html += '</span>';
				html += '</div>'; // end header
				// body
				html += '<table cellspacing="0" cellpadding="0" class="ui-custom-calendar-body">';
				// html += '<thead><tr><th width="14%">'+options.daysofweek.join('</th><th width="14%">')+'</th></tr></thead>';
				var html_h = '';
				for (i=0;i<options.months_span;i++){
					if (i){html_h += '<td class="spacer">&nbsp;</td>';}
					html_h += '<th colspan="7" class="month-n">'+options.months_long[(date.getMonth()+i) % 12]+'</th>';
				}
				html_h += '</tr><tr>';
				for (i=0;i<options.months_span;i++){
					if (i){html_h += '<td class="spacer">&nbsp;</td>';}
					html_h += '<td>'+options.daysofweek.join('</td><td>')+'</td>';
				}
				html += '<thead><tr>'+html_h+'</tr></thead>';
				html += '<tbody></tbody>';
				html += '</table>';
				html += '<div class="ui-helper-clearfix"></div>'; // end container
				html += '</div>'; // end container
				$('body').append(html);
				container = $('#'+uid);
				if ($.browser.msie && (parseFloat($.browser.version) < 7) && $.bgiframe){
					container.bgiframe();
				}
				// events
				var self = this;
				if (options.nights){
					nights_content = options.nights.html();
					nights = options.nights.val();
					options.min_nights || (options.min_nights = parseInt($('option:first', options.nights).val()), 10);
					options.max_nights || (options.max_nights = parseInt($('option:last', options.nights).val(), 10));
				}
				$('tbody', container).click(function (e){
					if ($(e.target).is('.ui-custom-calendar-enabled')){
						element.val(e.target.title);
						container.hide();
						$('.ui-state-active', this).removeClass('ui-state-active');
						$(e.target).addClass('ui-state-active');
						if (options.nights){
							if (hotel_only){
								options.nights.html(nights_content);
								options.nights.val(nights);
							}
							else{
								options.nights.html(return_days[e.target.title]);
								// options.nights.val(nights);
								try{
									options.nights.val(nights);
								} catch (err){
									setTimeout(function (){options.nights.val(nights);}, 1);
								}
							}
						}
					}
				});
				// prev
				$('.ui-icon-circle-triangle-w', container).click(function (e){
					date.setFullYear(date.getFullYear(), date.getMonth()-1, 1);
					self.render();
					return false;
				});
				// next
				$('.ui-icon-circle-triangle-e', container).click(function (e){
					date.setFullYear(date.getFullYear(), date.getMonth()+1, 1);
					self.render();
					return false;
				});
				// select
				$('.ui-custom-calendar-title select', container).change(function (e){
					date.setFullYear($('.ui-custom-calendar-title select[name=year]', container).val(), $('.ui-custom-calendar-title select[name=month]', container).val(), 1);
					self.render();
					return false;
				});
				// element.bind('blur', function (){container.hide();});
				element.bind('click', function (e){container.show(); return false;});
				container.click(function (){return false;});
				$(document).click(function (){container.hide();});
				// fill in days
				this.render();
			}
			this.init();
		};
	};
	// plugin defaults
	$.fn.CustomCalendar.defaults = {
		href: false
		, months_long: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
		, months_short: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
		, daysofweek: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']
		, nights: false
		, min_nights: false
		, max_nights: false
		, months_span: 1
		, years_span: 5
	};
})(jQuery);

