var archive = function(obj)
{
	this.obj = obj;
	this.now = new Date();
	this.cur = $(obj).attr('date');
	//this.min = new Date(this.now.getFullYear(), this.now.getMonth(), this.now.getDate()); //new Date(2005, 2, 12);
	this.max = new Date(this.now.getFullYear() + 5, this.now.getMonth(), this.now.getDate());
	if(this.cur)
	{
		var parts = this.cur.match(/([0-9]{2})\.([0-9]{2})\.([0-9]{4})/);
		this.cur = new Date(parts[3], parts[2] - 1, parts[1]);
	}
	else
	{
		this.cur = new Date(this.now.getFullYear(), this.now.getMonth(), this.now.getDate());
	}
	this.min = new Date(this.now.getFullYear(), this.now.getMonth(), this.now.getDate());	
	this.min.compare = new Date(this.min.getFullYear(), this.min.getMonth(), 1);
	//this.url = $(obj).attr('url');
	//this.url = '/' + sport + (section != '' ? '/_' + section : '');
	
	this.url = '{day}.{month}.{year}';
	
	this.sel = new Date(this.cur.getFullYear(), this.cur.getMonth(), 1);
	this.names = ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"];
	
	this.init = function()
	{
		this.control = $(that.obj).data('control');
		this.trueInput = $(that.obj).data('trueInput');
		
		if(obj)
		{
			that.obj.month = $('.month', this.obj);
			that.obj.year = $('.year', this.obj);
			that.obj.body = $('table tbody', this.obj);
			
			$('a:first', that.obj.month).bind('click', 'monthPrev', that.set);
			$('a:last', that.obj.month).bind('click', 'monthNext', that.set);

			$('a:first', that.obj.year).bind('click', 'yearPrev', that.set);
			$('a:last', that.obj.year).bind('click', 'yearNext', that.set);
			
			$(that.obj).bind('click', function (e) {
				e.stopPropagation();
			})
		}
	};
	
	this.generate = function()
	{
		var html = '<tr>',
		    dt = new Date(that.sel),
		    last = 0,
		    month = dt.getMonth() + 1,
			year = dt.getFullYear(),
		    //str = '/' + year + '-' + (month < 10 ? '0' + month : month),
			//availableDates = [],
			currentDateData = {
				year : year,
				month : month
			},
			paintHtml = function()
			{
				
				
				html += that.emptyCells(dt.getDay() == 0 ? 6 : dt.getDay() - 1);
				for(var i = 1; i < 32; i++)
				{
					dt.setDate(i);
					if(!dt || dt.getDate() != i) break;
					
					last = dt.getDay();
					var day = dt.getDate();
					if(day < 10) day = '0' + day;
					
					if(last == 1 && i != 1) html += '<tr>';
					if(dt > that.max || dt < that.min)
					{
						html += '<td><span>'+ dt.getDate() +'</span></td>';
					}
					else
					{
						var sel = (+dt == +that.cur) ? 'current ' : '',
							currentDateHtml = (function(){
								var date = dt.getDate() + '',
									url = '',
									dateUnavailable = !!(that.jsonWithAvailableDates) && ($.inArray(date, availableDates) === -1);
								
								if(dateUnavailable) 
								{
									date = '<span>' + date + '</span>';
								}
								else
								{
									currentDateData.day = day;
									currentDateData.month = (month < 10 ? '0' + month : month);
									url = that.url.supplant(currentDateData);
									date = '<a href="' + url + '" currentdate="' + url + '">' + date + '</a>';
								}
								
								return date;
							})();
		
						sel += (dt.getDay() == 6 || dt.getDay() == 0) ? 'holiday' : '';
						if(sel != '') sel = ' class="' + sel + '"';
						html += '<td' + sel + '>' + currentDateHtml + '</td>';
					}
					if(last == 0) html += '</tr>';
				}
				if(last != 0) html += that.emptyCells(7 - last);
				
				$(that.obj.body).html(html);
				$('span', that.obj.month).html(that.names[that.sel.getMonth()]);
				$('span', that.obj.year).html(that.sel.getFullYear());
		
				$('a:first', that.obj.month).attr('class', (that.monthPrev() < that.min.compare) ? 'prev disabled' : 'prev');
				$('a:first', that.obj.year).attr('class', (that.yearPrev() < that.min.compare) ? 'prev disabled' : 'prev');
				
				$('a:last', that.obj.month).attr('class', (that.monthNext() > that.max) ? 'next disabled' : 'next');
				$('a:last', that.obj.year).attr('class', (that.yearNext() > that.max) ? 'next disabled' : 'next');
				
				$('td > a', that.obj.body).bind('click', function (e) {
					e.preventDefault();
					
					var currentDate = $(this).attr('currentdate');
					
					that.control
						.val(currentDate)
						.removeAttr('disabled');
						
					$(that.obj)
						.closest('.cal')
							.hide();
												
					var parts = currentDate.match(/([0-9]{2})\.([0-9]{2})\.([0-9]{4})/);
					that.sel = new Date(parts[3], parts[2] - 1, 1);
					that.cur = new Date(parts[3], parts[2] - 1, parts[1]);
					that.generate();
						
					that.trueInput
						.val(parts[3] + '-' + parts[2] + '-' + parts[1]);
					
					if (that.nextCalendarObj) {
						var nextCalendarObj = that.nextCalendarObj,
							nextControl = that.nextControl,
							nextCur = new Date(that.cur.getTime() + 86400000),
							nextSel = new Date(nextCur.getFullYear(), nextCur.getMonth(), 1),
							nextVal = nullAddiction(nextCur.getDate()) + '.' + nullAddiction(nextCur.getMonth() + 1) + '.' + nullAddiction(nextCur.getFullYear()),
							nextTrueInput = nextControl.next('input:text');
							
						nextCalendarObj.min = that.cur;
						nextCalendarObj.generate();
						
						if (nextControl.val() !== 'дд.мм.гггг' && nextControl.val()) {
							return;
						}
						
						nextCalendarObj.sel = nextSel;
						nextCalendarObj.cur = nextCur;
						
						nextCalendarObj.generate();
						nextControl.val(nextVal);
						
						var nextTrueVal = nextCur.getFullYear() + '-' + nullAddiction(nextCur.getMonth() + 1) + '-' + nullAddiction(nextCur.getDate());
						nextTrueInput.val(nextTrueVal);
					}
					
					function nullAddiction (whereToAdd) {
						return (whereToAdd < 10) ?
							'0' + whereToAdd :
							whereToAdd;
					}
				});
			};
		
		paintHtml();
	};
	
	this.emptyCells = function(cnt)
	{
		var str = '';
		for(var i = 0; i < cnt; i++) str += '<td><span></span></td>';
		return str;
	};
	
	this.monthPrev = function(event)
	{
		var month = that.sel.getMonth();
		return new Date(that.sel.getFullYear() - (month == 0 ? 1 : 0), month == 0 ? 11 : month - 1, 1);
	};
	this.monthNext = function(event)
	{
		var month = that.sel.getMonth();
		return new Date(that.sel.getFullYear() + (month == 11 ? 1 : 0), month == 11 ? 0 : month + 1, 1);
	};

	this.yearPrev = function(event)
	{
		var year = that.sel.getFullYear();
		return new Date(year - 1, that.sel.getMonth(), 1);
	};
	this.yearNext = function(event)
	{
		var year = that.sel.getFullYear();
		return new Date(year + 1, that.sel.getMonth(), 1);
	};
	this.selectCurrent = function(event)
	{
		return new Date()
	};
	
	this.set = function(event)
	{
		event.preventDefault();
		if(this.className.indexOf('disabled') == -1)
		{
			that.sel = that[event.data]();
			that.generate();
		}
	};

	var that = this;
	
	that.init();
	that.generate();
};

var calendarManager = (function () {
	var CONFIG = {
		calendarsSelector : '.cal',
		calendarPluginSelector : '.cal .cal-in',
		controlsSelector : '.dates',
		classesSynonyms : {
			'date-begin' : 'cal-first',
			'date-end' : 'cal-last'
		}
	}
	
	var _calendars, _controls, _submitButton, _submitForm;
	
	function reset () {
		_calendars.hide();
		_controls
			.removeAttr('disabled');
	}
	
	function formatDate (formatWithHyphens) {
		if (!formatWithHyphens) {
			return '';
		}
		
		var formatWithDots,
			parts = formatWithHyphens.match(/([0-9]{4})\-([0-9]{2})\-([0-9]{2})/);
			
		formatWithDots = parts[3] + '.' + parts[2] + '.' + parts[1];
		
		return formatWithDots;
	}
	
	return {
		init : function (opt) {
			$.extend(CONFIG, opt);
			
			_calendars = $(CONFIG.calendarsSelector);
			_controls = $(CONFIG.controlsSelector);
			
			_submitForm = _controls.closest('form').submit(function () {
				_controls.attr('disabled', 'disabled');
			});
			
			reset();
			
			for (var i = 0, l = _controls.length; i < l; i++) {
				(function (i) {
					var control, calendar, calendarForPlugin, calendarObj, controlName, trueInput, value, pseudoValue;
					
					control = $(_controls[i]);
					calendar = $(_calendars[i]); 
					
					comingDate = control.attr('date');
					
					controlName = control.attr('name');
					trueInput = $('<input value="' + comingDate + '" type="text" style="display:none" name="' + controlName + '" />').insertAfter(control);
					
					pseudoValue = (comingDate) ? formatDate(comingDate) : 'дд.мм.гггг';
					
					control.val(pseudoValue);

					calendarForPlugin = calendar.find('.cal-in').data({
						'control' : control,
						'trueInput' : trueInput
					}).attr('date', formatDate(comingDate));
					
					calendarObj = new archive(calendarForPlugin[0]);
					
					control.data('calendar', calendarObj);
					
					control.attr('name', 't_' + controlName);
										
					control.bind('focus click', function (e) {
						e.stopPropagation();
						
						reset();

						// control.attr('disabled', 'disabled');
						calendar.show();
					}).bind('keypress', function (e) {
						e.preventDefault();
					}).bind('keyup', function (e) {
						switch (e.keyCode) {
							// delete
							case 46:
							// backspace
							case 8:
							case 32:
								control.val('');
								trueInput.val('');
								calendar.hide();
								break;
							default:
								return true;
						}						
					});					
				})(i);
			}
			
			var firstControl = $(_controls[0]),
				secondControl = $(_controls[1]),
				firstCalendarObj = firstControl.data('calendar'),
				secondCalendarObj = secondControl.data('calendar');
				
			firstCalendarObj.nextCalendarObj = secondCalendarObj;
			firstCalendarObj.nextControl = secondControl;
			
			$(document).click(reset);
		}
	};
})();

$(function () {
	calendarManager.init();
});


String.prototype.supplant = function (o) {
    return this.replace(/{([^{}]*)}/g,
        function (a, b) {
            var r = o[b];
            return typeof r === 'string' || typeof r === 'number' ? r : a;
        }
    );
};
