/*
 * Khanwars Event Calendar
 * @Author: Alexander Gavazov
 * @Site: http://studio.bg
 */


var KhanCalendar = function(target, eventsServer) {
	// Set globals
	this.target = $(target);
	this.eventsServer = eventsServer;

	// Set private data
	this.setData = {};
	this.currentZIndex = 1;

	// Set behavior
	this.target.observe('click', this.setDateByTargetClick.bind(this));

	// Create calendar
	this.setDate();
	this.writeCalendar();
};


KhanCalendar.prototype.setDateByTargetClick = function(event) {
	var element = event.element();
	this.setData.day = element.innerHTML.stripTags();

	if(element.hasClassName('previous_month')) {
		this.setData.month--;
		this.setDate(this.setData.year, this.setData.month, this.setData.day);
	} else if(element.hasClassName('next_month')) {
		this.setData.month++;
		this.setDate(this.setData.year, this.setData.month, this.setData.day);
	} else {
		return;
	}

	this.writeCalendar();
};


KhanCalendar.prototype.goToMonth = function(isNext) {
	if (isNext) {
		this.setDate(this.setData.year, ++this.setData.month, 1);
	} else {
		this.setDate(this.setData.year, --this.setData.month, 1);
	}
	this.writeCalendar();
};


KhanCalendar.prototype.setDate = function(year, month, day) {
	var date = new Date();
	var testDate = new Date();
	this.setData = {};

	// Year, month, day
	testDate.setFullYear(year, month, day);
	this.setData.year = !isNaN(testDate.getFullYear()) ? testDate.getFullYear() : date.getFullYear();
	this.setData.month = !isNaN(testDate.getMonth()) ? testDate.getMonth() : date.getMonth() + 1;
	this.setData.day = !isNaN(testDate.getDate()) ? testDate.getDate() : date.getDate();

	// Today
	if (this.setData.year == date.getFullYear() && this.setData.month == date.getMonth()) {
		this.setData.today = date.getDate();
	}

	// Offset
	testDate.setFullYear(this.setData.year, this.setData.month, 1);
	this.setData.offset = testDate.getDay() || 7;
	if (this.setData.offset == 1) {
		this.setData.offset += 7;
	}

	// Days in month
	testDate.setFullYear(this.setData.year, this.setData.month + 1, 0);
	this.setData.total = testDate.getDate();

	// Previous month days
	testDate.setFullYear(this.setData.year, this.setData.month, 0);
	this.setData.prevTotal = testDate.getDate();
};


KhanCalendar.prototype.writeCalendar = function() {
	var offset = this.setData.offset;
	var myDay = 1;
	var nextMyDay = 1;

	var daysWrapper = new Element('div', {cellpadding: 0, cellspacing: 0, className: 'khan_calendar_wrapper'});
	for (var week = 1; week <= 6; week++) {
		var daysWeek = new Element('div', {cellpadding: 0, cellspacing: 0, className: 'week'});
		daysWrapper.insert(daysWeek);

		// Previous month
		if (week == 1) {
			for (var prevDay = this.setData.prevTotal - offset + 2; prevDay < this.setData.prevTotal + 1; prevDay++) {
				var dayNode = new Element('span').update(prevDay);
				daysWeek.insert(new Element('div', {className: 'day previous_month'}).update(dayNode));
			}
		}

		// Current month
		for (var day = offset; day <= 7; day++, myDay++) {
			if (myDay <= this.setData.total) {
				var className = 'day current_month';

				if (this.setData.today == myDay) {
					className += ' today';
				}

				if(myDay == this.setData.day) {
					className += ' active';
				}

				var dayNode = new Element('span').update(myDay);
				daysWeek.insert(new Element('div', {className: className, id: 'khan_calendar_day_' + myDay}).update(dayNode));
			} else {
				break;
			}
		}

		// Next month
		if (myDay > this.setData.total) {
			for (var nextDay = 1; nextDay <= 7 - day + 1; nextDay++, nextMyDay++) {
				var dayNode = new Element('span').update(nextMyDay);
				daysWeek.insert(new Element('div', {className: 'day next_month'}).update(dayNode));
			}
		}

		offset = 1;
	}

	this.target.update(daysWrapper);

	// Insert Header: Nex & Prev & current date
	var headerWrapper = new Element('div', {className: 'calendar_header'});
	var next = new Element('div', {className: 'next'}).update('&rsaquo;');
	var prev = new Element('div', {className: 'prev'}).update('&lsaquo;');
	var currentDate = new Element('div', {className: 'current_date'}).update(this.setData.year + '-' + this.setData.month);
	next.observe('click', this.goToMonth.bind(this, true));
	prev.observe('click', this.goToMonth.bind(this, false));
	headerWrapper.insert(next);
	headerWrapper.insert(prev);
	headerWrapper.insert(currentDate);

	this.target.insert(headerWrapper);

	this.getEvents();
};


KhanCalendar.prototype.getEvents = function() {
	new Ajax.Request(this.eventsServer, {
		method: 'post',
		parameters: {year: this.setData.year, month: this.setData.month},
		onComplete: this.setEvents.bind(this)
	});
};


KhanCalendar.prototype.setEvents = function(transport) {
	try {
		var rs = transport.responseText.evalJSON();
	} catch(err) {
		var rs = {};
	}

	rs.each(function(row) {
		var dayElement = $('khan_calendar_day_' + parseInt(row.day));
		if (dayElement) {
			this.writeEvent(dayElement, row.content);
		}
	}.bind(this));
};


KhanCalendar.prototype.writeEvent = function(element, content) {
	var eventTip = new Element('div', {className: 'event_tip'}).hide();
	eventTip.insert(content);
	element.insert(eventTip);

	var eventMask = new Element('div', {className: 'event_mask'}).setOpacity(0);
	element.insert(eventMask);
	eventMask.appear({duration: .3});

	element.addClassName('event_day');

	element.observe('mouseover', this.showEvent.bind(this, element, eventTip));
	element.observe('mouseout', this.hideEvent.bind(this, element, eventTip));
};


KhanCalendar.prototype.showEvent = function(element, eventTip) {
	element.style.zIndex = ++this.currentZIndex;
	eventTip.show();
};


KhanCalendar.prototype.hideEvent = function(element, eventTip) {
	element.style.zIndex = 1;
	eventTip.hide();
};


_d = function(p) { console.log(p); };