(function($) {

	$.cobalt.datacalendar = function(el,o) {

		if (!el) return;
		this.element = el.jquery ? el : $(el);
		this.options = $.extend({},0);
		this.init();

	};

	$.extend($.cobalt.datacalendar.prototype,{

		scope : 'Days',

		// Next month / year / decade.
		move : function(amount)
			{
				var cal = this;
				var date;
				switch (cal.scope)
				{
					case 'Days':
						date = new Date(cal.currentYear,cal.currentMonth+amount,1);
						break;
					case 'Months':
						date = new Date(cal.currentYear+amount,cal.currentMonth,1);
						break;
					case 'Years':
						date = new Date(cal.currentYear+(amount*10),cal.currentMonth+1,1);
						break;
				}
				cal.recordDate(date);
				cal.drawCalendar();
			},

		// Draw the current calendar.
		drawCalendar : function()
			{
				var cal = this;
				switch (cal.scope)
				{
					case 'Days':
						cal.period.html($.cobalt.calendar.months[cal.currentMonth]+', '+cal.currentYear);
						cal.drawDays();
						break;
					case 'Months':
						cal.period.html(cal.currentYear);
						cal.drawMonths();
						break;
					case 'Years':
						var year = Math.floor(cal.currentYear/10)*10;
						cal.period.html(year+' - '+(year+10));
						cal.drawYears();
						break;
				}
			},

		// Draw the day calendar.
		drawDays : function()
			{
				var year = this.currentYear;
				var month = this.currentMonth;
				
				// Get the first and last day of the month.
				var firstDay = new Date(year,month,1);

				var code = firstDay.getFullYear()+'.'+firstDay.getMonth()+'.'+firstDay.getDate();
				if (code!=this.calDays.attr('_date'))
				{
					var caldate = (month+1)+'/'+this.currentDate+'/'+year;
					var url = $.getAjaxUrl(window.location.href,{DataCalendar:this.element.attr('id'),CalDate:caldate});
					var fn = function(cal,code){
						return function(results){
							cal.element.doneLoading();
							if (results && results.indexOf('<html')<0)
							{
								cal.calDetails.empty().hide();
								cal.calDays.html(results||'').attr('_date',code);
								cal.calMonths.hide();
								cal.calYears.hide();
								cal.calDays.show();
							}
							cal=null;
						};
					}(this,code);
					this.element.loading(null,{message:''});
					$.ajax({url:url,success:fn});
				}
				else
				{
					this.calMonths.hide();
					this.calYears.hide();
					this.calDays.show();
				}
			},

		// Draw the month calendar.
		drawMonths : function()
			{
				var start = this.currentYear;

				// Draw each of the days.
				var months = this.calMonths.find('td>div');
				for (var i=0;i<12;i++)
				{
					// Get the next date.
					var current = new Date(start,0+i,1);
					var code = current.getFullYear()+'.'+current.getMonth();
					var month = months.eq(i).attr('_date',code);

					// Set the class.
					if (current.getYear()==this.startDate.getYear() && current.getMonth()==this.startDate.getMonth())
						month.addClass('dcal_sel');
					else
						month.removeClass('dcal_sel');
				}

				this.calDays.hide();
				this.calYears.hide();
				this.calMonths.show();
			},

		// Draw the year calendar
		drawYears : function()
			{
				// Get the starting year.
				var start = (Math.floor(this.currentYear/10)*10)-1;

				// Draw each of the years.
				var years = this.calYears.find('td>div');
				for (var i=0;i<12;i++)
				{
					// Get the next date.
					var code = start+i;
					var year = years.eq(i).attr('_date',''+code).html(code);

					// Set the class.
					if (code==this.startDate.getYear())
						year.addClass('dcal_sel');
					else
						year.removeClass('dcal_sel');
				}

				this.calDays.hide();
				this.calMonths.hide();
				this.calYears.show();
			},

		// Draw the detailed list of events.
		drawDetails : function()
			{
				var caldate = (this.currentMonth+1)+'/'+this.currentDate+'/'+this.currentYear;
				var url = $.getAjaxUrl(window.location.href,{DataCalendar:this.element.attr('id'),Details:'true',CalDate:caldate});
				var fn = function(cal){
					return function(results){
						cal.element.doneLoading();
						if (results && results.indexOf('<html')<0)
							cal.calDetails.html(results||'');
						cal=null;
					};
				}(this);
				this.calDetails.show();
				this.element.loading(null,{message:''});
				$.ajax({url:url,success:fn});
			},

		// Select the current date.
		select : function(e)
			{
				var cal = $(this).data('cal');
				var el = $(e.target);
				
				if (el.is('div.dcal_day'))
				{
					// Fire the onselect event if one is defined.
					if (this.options && $.isFunction(this.options.onselect))
						this.options.onselect(this,date);

					cal.calDays.find('.dcal_sel').removeClass('dcal_sel');
					var d = el.addClass('dcal_sel').attr('_date').split('.');
					var date = new Date(parseInt(d[0]),parseInt(d[1]),parseInt(d[2]));
					cal.recordDate(date);
					cal.drawDetails();
				}
				else if (el.is('img'))
				{
					if (el.parents('div.dcal_prev:first').length)
						cal.move(-1);
					else if (el.parents('div.dcal_next:first').length)
						cal.move(1);
				}
				else if (el.is('div.dcal_month'))
				{
					// Update the month and year.
					var d = el.attr('_date').split('.');
					cal.currentYear = parseInt(d[0]);
					cal.currentMonth = parseInt(d[1]);
					cal.scope = 'Days';
					cal.drawCalendar();
				}
				else if (el.is('div.dcal_year'))
				{
					// Update the year.
					var d = el.attr('_date').split('.');
					cal.currentYear = parseInt(d[0]);
					cal.scope = 'Months';
					cal.drawCalendar();
				}
				else if (el.is('div.dcal_today'))
				{
					// Fire the onselect event if one is defined.
					if (this.options && $.isFunction(this.options.onselect))
						this.options.onselect(this,date);

					cal.calDays.find('.dcal_sel').removeClass('dcal_sel');
					var date = new Date();
					cal.recordDate(date);
					cal.scope = 'Days';
					cal.drawCalendar();
				}
				else if (el.is('div.dcal_period'))
				{
					// Change the scope.
					switch (cal.scope)
					{
						case 'Days':
							cal.scope = 'Months';
							break;
						case 'Months':
							cal.scope = 'Years';
							break;
					}
					cal.drawCalendar();
				}
				else if (el.is('a'))
					return;
				
				return false;
			},

		// Record the date.
		recordDate : function(d)
			{
				// Update the current date values.
				this.startDate = d;
				this.currentDate = d.getDate();
				this.currentMonth = d.getMonth();
				this.currentYear = d.getFullYear();
			},

		// Initialize the calendar.
		init : function()
			{
				// Get the elements of the calendar.
				this.caldate = this.element.find('div.dcal_date');
				this.period = this.element.find('div.dcal_period');
				this.calDays = this.element.find('div.dcal_days');
				this.calMonths = this.element.find('div.dcal_months');
				this.calYears = this.element.find('div.dcal_years');
				this.calDetails = this.element.find('div.dcal_details');
				this.today = this.element.find('div.dcal_today');

				// Initialize the calendar events.
				this.element
					.data('cal',this)
					.click(this.select);

				// Set the start date.
				var date = this.element.attr('_startdate');
				this.recordDate($.cobalt.calendar.parseDate(date,true)||new Date());
			}

	});

	// A simple scrolling ticker.
	$.fn.datacalendar = function(o){

		return this.each(function(i){

			if (!this.datacalendar)
				this.datacalendar = new $.cobalt.datacalendar(this,o);

		});
	};

})(jQuery);

