/**
 * Calendar
 * @author Rygor Kharytanovich
 * @extends jquery
 * Usage: $(<selector>).calendar();
 */

jQuery.fn.extend({
	calendar: function (options) {
		
		if (this) {
			
			var me = $(this),
				options = options || {},
				date = options.date || new Date(),
				activeDate = date,
				datesElement = me.find('.dates table');
			
			var isLeapYear = function (year) {
				return (!(year % 4) && !!(year % 100) || !(year % 400));
			}
			
			var getDaysOfMonth = function (month, year) {
				
				switch (month) {
					case 0: case 2: case 4: case 6: case 7: case 9: case 11:
						return 31;
					case 3: case 5: case 8: case 10: 
						return 30;
					case 1:
						return isLeapYear(year) ? 29 : 28;
				}
				
			}
			
			var setYear = function (year) {
				date = new Date(year, date.getMonth());
				me.find('.years li.active').removeClass('active');
				updateCalendar();
			}
			
			var setMonth = function (month) {
				date = new Date(date.getFullYear(), month);
				me.find('.monthes li.active').removeClass('active');
				updateCalendar();
			}
			
			var setDate = function (d) {
				activeDate = new Date(date.getFullYear(), date.getMonth(), d);
				me
					.find('.dates td.active')
						.removeClass('active')
					.end()
					.find('.dates a[innerHTML=' + d + ']:parent').parent()
						.addClass('active')
					.end();
			}
			
			var populateDays = function () {
				
				var content = '',
					firstDay = (new Date(date.getFullYear(), date.getMonth(), 1).getDay() + 6) % 7,
					numDays = getDaysOfMonth(date.getMonth(), date.getFullYear());
				
				// create array of dates by days
				var days = new Array();
				for (var i = 0, l = 7; i < l; i++) {
					days[i] = i < firstDay ? new Array(null) : new Array();
				}
				
				// fill dates array
				var day;
				for (var i = 1, l = numDays; i <= l; i++) {
					var d = new Date(date.getFullYear(), date.getMonth(), i);
					day = (d.getDay() + 6) % 7;
					days[day].push(d);
				}
				
				// flush dates
				datesElement.empty();
				
				var rowLength = days[0].length;
				for (var i = 0, il = days.length; i < il; i++) {
					
					// create row
					var row = document.createElement('tr');
					
					for (var j = 0, jl = days[i].length; j < jl; j++) {
						
						var d = days[i][j],
							td = document.createElement('td');
						
						if (d) {
							
							var a = document.createElement('a');
							
							// create table cell
							a.appendChild(document.createTextNode(d.getDate()));
							a.href = "/date/"+d.getFullYear()+'/'+(d.getMonth()+1)+'/'+d.getDate();

							$(a).bind('click', {date: d.getDate()}, function (evt) {
								setDate(evt.data.date);
							})
							
							td.appendChild(a);
							
							// if date is eq to active
							if (d.getTime() == activeDate.getTime()) {
								// make it active
								td.className = 'active';
							}
							
						} else {
							
							td.appendChild(document.createTextNode(" "));
							
						}
						
						row.appendChild(td);
						
						if (j == jl-1) {
							// add extra cell
							td = document.createElement('td');
							td.appendChild(document.createTextNode(" "));
							row.appendChild(td);
						}
						
					}
					
					datesElement.append(row);
					
				}
				
			}
			
			var updateCalendar = function () {
				me.find('.years li:contains("' + date.getFullYear() + '")').addClass('active');
				me.find('.monthes li:eq(' + date.getMonth() + ')').addClass('active');
				populateDays();
			}
			
			me.find('.years a').click(function () {
				setYear($(this).text());
			});
			
			me.find('.monthes a').each(function (idx) {
				$(this).click(function () {
					setMonth(idx);
				})
			});
			
			me.find('.submit:button').click(function () {
				alert('Выбрана дата: ' + activeDate)
			});
			
			updateCalendar();
			
		}
		
	}
});



