var Calendar = function (id, params, mini, urlType, listSid ) {
	this.container = $('calendar_' + id);
	this.params = params;

	this.mini = mini;

	this.monthsContainer = mini ? $('month_' + id) : $$(this.container, 'TABLE')[0];

	this.curMonth = this.params.months[1];
	this.curYear  = this.params.years[1];

	this.minDate = new Date(this.params.years[0], this.params.months[0] - 1, 1);
	this.maxDate = new Date(this.params.years[2], this.params.months[2] - 1, 1);

	this.leftArrow  = $('larr_' + id);
	this.rightArrow = $('rarr_' + id);
	
	this.urlType = urlType;
	if(this.urlType == 'list-sid')	{ this.listSid = listSid; }
	
	if (this.mini) {
		this.params.currentIndex = 0;
		Event.add(this.leftArrow, 'click', this.moveMini.bind(this, 0));
		Event.add(this.rightArrow, 'click', this.moveMini.bind(this, 1));
	} else {
		Event.add(this.leftArrow, 'click', this.move.bind(this, 0));
		Event.add(this.rightArrow, 'click', this.move.bind(this, 1));
	}

	this.AJAX = new Ajax(this.getMonthDaysAjax,
		{
			_this		: this,
			eventPlace	: this.monthsContainer,
			container	: $$(this.container, 'UL')[mini ? 1 : 0],
			spinner		: $(this.params.ajax_spinner_id)
		}
	);

	return this;
};

Calendar.prototype.move = function (dir){
	var columns = $$(this.monthsContainer, 'TD');
	var a = [];
	var tmp, current, nextDate;

	// collecting array of original values
	for (var i = 0, l = columns.length; i < l; i++) {
		var month = columns[i];
		a[i] = month.innerHTML;
	}

	// set offsetted month into temporary array
	nextDate = this.getNextDate(dir);

	if (!nextDate) {
		return;
	}
	dir ? this.params.currentIndex-- : this.params.currentIndex++;

	if (!dir) {
		for (i = a.length - 2; i >= 0; i--) {
			tmp = a[i + 1];
			a[i + 1] = a[i];
			if (i > 0) {
				a[i] = tmp;
			} else {
				var list_url = document.location.pathname.match(/(\/\w+\/)(?:\d+)?/)[1];
				a[i] = '<a class="blue" href="' + list_url + this.createURL(nextDate) + '/">' + this.dateName(nextDate) + '</a>';
			}
		}
	} else {
		for (i = 1, l = a.length; i < l; i++) {
			tmp = a[i - 1];
			a[i - 1] = a[i];
			if (i < a.length - 1) {
				a[i] = tmp;
			} else {
				list_url = document.location.pathname.match(/(\/\w+\/)(?:\d+)?/)[1];
				a[i] = '<a class="blue" href="' + list_url + this.createURL(nextDate) + '/">' + this.dateName(nextDate) + '</a>';
			}
		}
	}

	// Rendering resulting array into table
	for (i = 0, l = a.length; i < l; i++) {
		month = a[i];
		current = columns[i];
		current.className = ((this.params.currentIndex >= 0 || this.params.currentIndex <= a.length) && i == this.params.currentIndex) ? 'orng' : '';
		current.innerHTML = month;
	}

	this.checkNextButtons(dir);
};

Calendar.prototype.moveMini = function (dir) {
	var nextDate = this.getNextDate(dir);
	if (!nextDate) {
		return;
	}
	dir ? this.params.currentIndex-- : this.params.currentIndex++;
	this.monthsContainer.innerHTML = this.dateName(nextDate);
	this.checkNextButtons(dir);

	nextDate.setMonth(this.nextDate.getMonth() + (dir ? -1 : 1));

	var ajaxUrl = nextDate.getFullYear().toString() + (nextDate.getMonth() < 9 ? '0' : '') + (nextDate.getMonth() + 1) + '01';
	this.AJAX.run(ajaxUrl);
};

Calendar.prototype.checkNextButtons = function (dir) {
	this.nextDate.setMonth(this.nextDate.getMonth() + (dir ? 1 : -1));

	Object.Class.replace(this.leftArrow, 'hidden', '', this.minDate > this.nextDate);
	Object.Class.replace(this.rightArrow, 'hidden', '', this.maxDate < this.nextDate);
};

Calendar.prototype.createURL = function (date) {
	var m = (date.getMonth() + 1).toString();
	return date.getFullYear() + (m.length == 1 ? '0' + m : m) + '01';
};

Calendar.prototype.getNextDate = function (i) {
	var offset = this.curMonth - this.params.currentIndex + (i ? (this.mini ? 1 : 5) : -1);

	var nextMonth = (((offset - 1) % 12) + 12) % 12 + 1;
	var nextYear = this.curYear + Math.floor((offset - 1) / 12);

	this.nextDate = new Date(nextYear, nextMonth - 1, 1);

	return (this.minDate > this.nextDate || this.maxDate < this.nextDate) ? false : this.nextDate;
};

Calendar.prototype.dateName = function (nextDate) {
	return this.params.monthNames[nextDate.getMonth() + 1] + ' ' + nextDate.getFullYear();
};

Calendar.prototype.selectMonth = function (newIndex) {
	var columns = $$(this.monthsContainer, 'TD');

	var deltaMonth = this.params.currentIndex - newIndex;
	var newMonth = ((((this.curMonth - deltaMonth) - 1) % 12) + 12) % 12 + 1;
	var newYear = this.curYear + Math.floor((this.curMonth - deltaMonth - 1) / 12);

	this.params.currentIndex = newIndex;
	this.curMonth = newMonth;
	this.curYear = newYear;

	for (var i = 0, l = columns.length; i < l; i++) {
		var current = columns[i];
		current.className = (i == newIndex) ? 'orng' : '';
	}
};

Calendar.prototype.getMonthDaysAjax = {
	init: function () {
		if (!this._this.mini) {
			Event.add(this.eventPlace, 'click', this.run.bind(this));
		}
	},
	run: function (e) {
		if (this._this.mini) {
			this.currentURL = e;
			//this.url = document.location.pathname.match(/(\/\w+\/)(?:\d+)?/)[1] + e + '/calendar.json?mini=1';
			if(this._this.urlType == 'list-sid')	{
				this.url = '/' + this._this.listSid + '/' + e + '/calendar.json?mini=1';
			}	else	{
				this.url = (document.location.pathname.match(/(\/\w+\/)?(?:\d+)?/)[1] || document.location.pathname) + e + '/calendar.json?mini=1';
			}
			
			this.go();
		} else {
			e = Event.elementEqual(e, 'A');
			if (!e || e.parentNode.className) { return false; }
			var currentTD = e.parentNode;
			var c = 0;
			while (currentTD.previousSibling) {
				currentTD = currentTD.previousSibling;
				c++;
			}

			this._this.selectMonth(c);

			if(this._this.urlType == 'list-sid')	{
				this.currentURL = e.href.match(/(\d+)/)[0];
				this.url = '/' + this._this.listSid + '/' + e.href.match(/(\d+)/)[0] + '/calendar.json';
			}	else	{
				//this.url = (document.location.pathname.match(/(\/\w+\/)?(?:\d+)?/)[1] || document.location.pathname) + e + '/calendar.json';
				this.currentURL = e.href.match(/\/\w+\/(\d+)/)[1];
				this.url = e.href + 'calendar.json';
			}
			this.go();
		}
	},
	after: function (response) {
		if (response.url != this.currentURL) { return; }
		this.spinnerSH(0);
		this.container.innerHTML = response.html;
	}
};
