var calendar = { // NAMESPACE
	archive : {},
	get : function(id) {
		if (typeof this.archive[id] == "undefined") {
			this.archive[id] = new this.create(id);
		}
		return this.archive[id];
	}
};

calendar.create = function(id) { // Namespace
	// Vars
	this.id = id;
	this.curYear = 0;
	this.curMohth = 0;
	this.curDay = 0;
	
	this.todayYear = 0;
	this.todayMohth = 0;
	this.todayDay = 0;
	
	this.showYear = 0;
	this.showMohth = 0;
	
	this.minYear = 2000;
	// HTML-elements
	this.nextMonth = null;
	this.prevMonth = null;
	this.curDateBlock = null;
	this.curYearBlock = null;
	this.calendarTable = null;
	this.container = null;
	// Flags
	this.isTodayMonth = true;
	this.isCurMonth = true;
	this.isMinMonth = false;
	this.debugMode = true;
	
	this.dates = {}; // Кэш дат, на которые есть новости
}

calendar.create.prototype = {
	MONTHES : [
		"Январь", "Февраль", 
		"Март", "Апрель", "Май", 
		"Июнь", "Июль", "Август", 
		"Сентябрь", "Октябрь", "Ноябрь", 
		"Декабрь"
	],
	ERRORS : {
		1 : "Ошибка при инициализации объекта",
		2 : "Контейнер nextMonth не найден",
		3 : "Контейнер prevMonth не найден",
		4 : "Контейнер yearList не найден",
		5 : "Контейнер curDate не найден",
		6 : "Контейнер calendarTable не найден",
		7 : "Контейнер curYear не найден"
	},
	NEXT_MONTH_PREFIX : "nextMonth_",
	CUR_DATE_PREFIX : "curDate_",
	PREV_MONTH_PREFIX : "prevMonth_",
	CALENDAR_PREFIX : "calendar_",
	CUR_YEAR_PREFIX : "curYear_",
	CONTAINER_PREFIX : "calendarDiv_",
// Methods
	// Default
	gebi : function(id) {
		return document.getElementById(id);
	},
	addHandler : function(object, event, handler, useCapture) {
		if (object.addEventListener) {
			object.addEventListener(event, handler, useCapture ? useCapture : false);
		} else if (object.attachEvent) {
			object.attachEvent('on' + event, handler);
		} else alert(this.errorArray[9]);
	},
	inArray : function(el, arr) {
		if (arr) {
			for (var i = 0; i < arr.length; i++) {
				if (arr[i] == el) return true;
			}
			 return false;
		}
	},
	// Init
	debug : function(keys) {
		if (!this.debugMode) return;
		var mes = "";
		for (var i = 0; i < keys.length; i++) mes += this.ERRORS[keys[i]] + " : ";
		mes = mes.substring(0, mes.length - 3);
		alert(mes);
	},
	findElements : function() {
		this.nextMonth = this.gebi(this.NEXT_MONTH_PREFIX + this.id);
		if (this.nextMonth == null) {
			this.debug([1,2]);
				return;
		}
		this.prevMonth = this.gebi(this.PREV_MONTH_PREFIX + this.id);
		if (this.prevMonth == null) {
			this.debug([1,3]);
				return;
		}
		this.curDateBlock = this.gebi(this.CUR_DATE_PREFIX + this.id);
		if (this.curDateBlock == null) {
			this.debug([1,5]);
				return;
		}
		this.curYearBlock = this.gebi(this.CUR_YEAR_PREFIX + this.id);
		if (this.curYearBlock == null) {
			this.debug([1,7]);
				return;
		}
		this.calendarTable = this.gebi(this.CALENDAR_PREFIX + this.id);
		if (this.calendarTable == null) {
			this.debug([1,6]);
				return;
		}
		this.container = this.gebi(this.CONTAINER_PREFIX + this.id);
		if (this.container == null) {
			this.debug([1,6]);
				return;
		}
	},
	init : function(obj) {
		try {
			var _this = this;
			this.findElements();
			var today = new Date();
			if (typeof obj == "undefined") obj = {};
			
			this.todayYear = obj.todayYear || today.getFullYear();
			this.todayMohth = obj.todayMonth || today.getMonth();
			this.todayDay = obj.todayDay || today.getDate();
			
			this.curYear = obj.year || this.todayYear;
			this.curMohth = obj.month || this.todayMohth;
			this.curDay = obj.day || this.todayDay;
			
			this.showYear = this.curYear;
			this.showMohth = this.curMohth;
			
			this.drawHeader();
		} catch(e) {
			this.debug([1]);
		}
	},
	// Functionality
	show : function(evt) {
		if (this.container == null) this.init();
		evt = evt || window.event;
		evt.cancelBubble = true;
		this.container.style.display = "";
		return false;
	},
	hide : function() {
		this.container.style.display = "none";
		return false;
	},
	drawHeader : function() {
		if (!this.dates[this.showYear] || !this.dates[this.showYear][this.showMohth]) {
			var this_ = this;
			this.curDateBlock.innerHTML = 'Загрузка…';
			this.curYearBlock.innerHTML = '';
			this.receiveAvailableDates(this.showYear, this.showMohth, function() { this_.realDrawHeader(); });
			return;
		}
		
		this.realDrawHeader();
	},
	realDrawHeader : function() {
		this.detectMonthState();

		this.curDateBlock.innerHTML = this.MONTHES[this.showMohth];
		this.curYearBlock.innerHTML = this.showYear;
		
		this.prevMonth.className = (this.showYear == 2005 && this.showMohth == 0) ? 'prv-disabled' : 'prv';
		this.nextMonth.className = (this.showYear == this.todayYear && this.showMohth == this.todayMohth) ? 'nxt-disabled' : 'nxt';

		this.drawTable();
	},
	drawTable : function(is) {
		var html = [
			'<table cellspacing="0">\
				<tr>\
					<th>Пн</th>\
					<th>Вт</th>\
					<th>Ср</th>\
					<th>Чт</th>\
					<th>Пт</th>\
					<th class="wend">Сб</th>\
					<th class="wend">Вс</th>\
				</tr>'
		];
		var buferArray = [];
		var cdate = new Date(this.showYear, this.showMohth, 1);
		var ndate = new Date(this.showYear, this.showMohth + 1, 1);
		
		var cdateDay = cdate.getDay();
		cdateDay = cdateDay == 0 ? 7 : cdateDay; // fix for sunday
		for (var i = 1; i < cdateDay; i++) buferArray[i] = false;
		
		var dayInMonth = ndate.getTime() - cdate.getTime();
		dayInMonth = Math.floor(dayInMonth / (1000 * 60 * 60 * 24));
		for (i = 0; i < dayInMonth; i++) buferArray[i + cdateDay] = i + 1;

		var cdate = new Date(this.showYear, this.showMohth, dayInMonth);
		var cdateDay = cdate.getDay();
		cdateDay = cdateDay == 0 ? 7 : cdateDay; // fix for sunday
		for (i = cdateDay + 1; i <= 7; i++) buferArray[buferArray.length] = false;
		
		var dates = this.dates[this.showYear][this.showMohth];		
		
		for (i = 1; i < buferArray.length; i++) {
			if (i % 7 == 1) html.push('<tr>');
			
			if (buferArray[i]) {
				var classes = [];
				if (this.isTodayMonth && buferArray[i] == this.todayDay) classes.push("today");
				if (this.isCurMonth && buferArray[i] == this.curDay) classes.push("on");
				if (i % 7 == 6 || i % 7 == 0) classes.push("wend");
			
				var period = this.showYear + '-' + (this.showMohth + 1 < 10 ? "0" + (this.showMohth + 1) : this.showMohth + 1) + "-" + (buferArray[i] < 10 ? "0" + buferArray[i] : buferArray[i]);
				var day = (buferArray[i] ? buferArray[i].toString() : "");
				var link = dates.hasOwnProperty(period)
					? '<a href="' + this.allUrlBegin + '?' + (this.extraParams ? this.extraParams + '&' : '') + 'date_end=' + period + this.allUrlEnd + '"' + (buferArray[i] < 10 ? ' class="onedig"' : '') + ">" + day + '</a>'
					: day;
			
				html.push('<td', classes.length ? (' class="' + classes.join(' ') + '"') : '', '>', link, '</td>\n');
			}
			else {
				html.push('<td', (i % 7 == 6 || i % 7 == 0 ? ' class="wend"' : ''), '></td>');
			}			
			
			if (i % 7 == 0) html.push('</tr>');
		}
		
		html.push('</table>');
		
		this.calendarTable.innerHTML = html.join('');
	},
	detectMonthState : function() {
		this.isTodayMonth = this.showYear == this.todayYear && this.showMohth == this.todayMohth;
		this.isCurMonth = this.showYear == this.curYear && this.showMohth == this.curMohth;
		this.isMinMonth = this.showYear == this.minYear && this.showMohth == 0;
	},
	showNext : function() {
		if (!this.isLinkActive(this.nextMonth))
			return false;
			
		this.showMohth = (this.showMohth + 1) % 12;
		this.showYear = this.showMohth == 0 ? this.showYear + 1 : this.showYear;
		this.drawHeader();
		return false;
	},
	showPrev : function() {
		if (!this.isLinkActive(this.prevMonth))
			return false;

		this.showMohth = (this.showMohth - 1 + 12) % 12;
		this.showYear = this.showMohth == 11 ? this.showYear - 1 : this.showYear;
	
		this.drawHeader();
		return false;
	},
	showNextYear : function() {
		this.showYear++;
		this.setShowYear();
		return false;
	},
	showPrevYear : function() {
		this.showYear--;
		this.setShowYear();
		return false;
	},
	setShowYear : function(year) {
		if (this.showYear == this.todayYear && this.showMohth > this.todayMohth) {
			this.showMohth = this.todayMohth;
		}
		this.drawHeader();
		return false;
	},
	isLinkActive : function(link) {
		return link.className.indexOf('-disabled') == -1;
	},
	receiveAvailableDates : function(year, month, callback) {
		var xhr = web.getHttpRequest();
		var this_ = this;
		xhr.onreadystatechange = function() {
			if (xhr.readyState == 4) {
				if (xhr.status == 200) {
					var res = xhr.responseText;
					
					if(!res)
						return;
					try {
						eval('dates=' + res);
					}
					catch (e) {
						return;
					}
					
					if (!this_.dates[year]) {
						this_.dates[year] = {};
					}
					this_.dates[year][month] = dates;
					
					callback();
				} else {
					alert('Невозможно отправить запрос. Попробуйте позже.');
				}
			}
		};
		
		var requestMonth = parseInt(month, 10) + 1;
		
		var url = '/mem/main.pl?' + (this.extraParams ? this.extraParams + '&' : '') + 'action=user_content_get_articles_count&type=1&date_start=' + year + '-' + requestMonth + '-01&date_end=' + year + '-' + requestMonth + '-31';
		//var url = 'http://sapegin.boom.corp.mail.ru/test/auto-calendar/data/' + year + requestMonth;

		xhr.open('get', url, true);
		xhr.send(null);
	}
}
3
