/**
 * Calendar singleton class
 */

/**
 * Constructor
 */
var Calendar = function() {

	// Display date ( this will be detected at first render, contains only year and month, 200601 )
	this.renderDate 	= null;

	// Selected date ( this will be detected at first render, 20061201 )
	this.selectedDate   = null;

	// Language (two letters, in lowercase, defaults to lt)
	this.lang = 'lt';

	// Image url
	this.imageUrl = '';
	
	// Day names...
	this.dayNames = {
		lt : ['P', 'A', 'T', 'K', 'P', 'Š', 'S'],
		en : ['M', 'T', 'W', 'T', 'F', 'S', 'S']
	};

	// Month name
	this.monthNames = {
		lt :  ['Sausis', 'Vasaris', 'Kovas', 'Balandis', 'Gegužė', 'Birželis', 'Liepa', 'Rugpjūtis', 'Rugsėjis', 'Spalis', 'Lapkritis', 'Gruodis'],
		en : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']

	};

	// Day events...
	this.dayEvents = {};
	
	
	// Where to output calendar data
	this.calendarElementId = false;
	// Where to put selected date
	this.selectedDateElementId = false;
	// Select event handler 
	this.onSelected = null;
	

}

/**
 * Static - instance
 */
Calendar.instance = null;

/**
 * Static - get instance
 */
Calendar.getInstance = function() {
	return Calendar.instance ? Calendar.instance : ( Calendar.instance = new Calendar() );
}

/**
 * Static - get specific year month's day count
 */
Calendar.getMonthDayCount = function( year, month )  {

	var days = [31, ( ( ( year % 4 == 0 ) && ( year % 100 != 0 ) ) || ( year % 400 ) == 0 ) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

	return ( days[month - 1] ) ? days[month - 1] : days[0];

}

/**
 * Set month by delta, suported deltas +1 and -1
 */
Calendar.prototype.setMonth = function( delta ) {

	this.renderDate += delta;

	if( ( this.renderDate % 100 ) > 12 ) {
		this.renderDate = ( Math.floor( this.renderDate / 100 ) + 1 ) * 100 + 1;
	}

	if( ( this.renderDate % 100 ) < 1 ) {
		this.renderDate = ( Math.floor( this.renderDate / 100 ) - 1 ) * 100 + 12;
	}

	this.render();

}

Calendar.prototype.onDayOver = function( element ) {
	element.className += ' day_over';
}

Calendar.prototype.onDayOut = function( element ) {
	element.className = element.className.replace( ' day_over', '' );
}

Calendar.prototype.setSelectedDate = function( date ) {
	this.selectedDate = date;
			
	if (this.onSelected != null) {
		this.onSelected(this.toDateString(this.selectedDate));	
	}
	
	this.render();
}

Calendar.prototype.toDateString = function(date) {

	var year = Math.floor( date / 10000 );
	var month = Math.floor((date - year * 10000) / 100);	
	var day = date - year * 10000 - month * 100;

	return year + "-" + month + "-" + day;
}

/**
 * Render calendar
 */
Calendar.prototype.render = function() {
	
	
	// Define render date
	if( this.renderDate == null ) {
		this.renderDate = Math.floor( this.selectedDate / 100 );
	}

	// Set selected date to hidden field, if is
	try {
		$( this.selectedDateElementId ).value = this.selectedDate.toString();
	} catch( error ) {
		// error
	}
	

	var renderYear = Math.floor( this.renderDate / 100 );
	var renderMonth = this.renderDate % 100;

	// Create render date and set to render month and year
	var tempDate = new Date();
	tempDate.setYear( renderYear );
	tempDate.setDate( 1 );
	tempDate.setMonth( renderMonth - 1 );
	// Days count in current month
	var dayCount 			= Calendar.getMonthDayCount( renderYear, renderMonth );
	
	// Get begin empty count, fixate for 0 = Sunday
	var beginEmptyCount 	= ( tempDate.getDay() + 6 ) % 7;
	// Cell htmls
	var cellHhtmls = [];

	// Render top row...
	/*for( var i = 0; i < this.dayNames[this.lang].length; i++ ) {
		cellHhtmls.push( '<td class="day_name_' + ( ( i > 3 ) ? 'special' : 'common' ) + ( ( i == 0 ) ? ' day_name_first' : '' )  + '">' + this.dayNames[this.lang][i] + '</td>' );
	}*/

	// Render begin empty
	for( var i = 0; i < beginEmptyCount; i++ ) {
		cellHhtmls.push( '<td class="day_empty"></td>' );
	}

	// Render days
	for( var i = 1; i <= dayCount; i++ ) {
			
		var currDate = new Date();
			currDate.setYear( renderYear );
			currDate.setMonth( renderMonth - 1 );
			currDate.setDate( i );
			
		var currWeekDay = currDate.getDay();		
		

		
		var dayDate 	= this.renderDate * 100 + i;
		
		dayLink = '';
		
		if( dayDate == this.selectedDate ) {

			
			var dayActionsHtml = null;

			if( this.dayEvents[dayDate] ) {
				dayActionsHtml = ' onmouseover="Calendar.getInstance().onDayOver( this );" onmouseout="Calendar.getInstance().onDayOut( this );"  onclick="Calendar.getInstance().setSelectedDate( ' + dayDate.toString() + ');"';
			}	


			
			cellHhtmls.push( '<td ' + ( dayActionsHtml ? dayActionsHtml : '' ) + ' class="day_curr' + ( dayActionsHtml ? ' day_active' : '' ) + ( currWeekDay == 6 ? ' day_sat' : ( currWeekDay == 0 ? ' day_sun' : '' ) ) + '"><div>' + ( dayLink ? dayLink : i ) + '</div></td>' );

		} else {

			var dayActionsHtml = null;

			if( this.dayEvents[dayDate] ) {
				dayActionsHtml = ' onmouseover="Calendar.getInstance().onDayOver( this );" onmouseout="Calendar.getInstance().onDayOut( this );"  onclick="Calendar.getInstance().setSelectedDate( ' + dayDate.toString() + ');"';
			}	

	

			cellHhtmls.push( '<td ' + ( dayActionsHtml ? dayActionsHtml : '' ) + ' class="day_fill' + ( dayActionsHtml ? ' day_active' : '' ) + ( currWeekDay == 6 ? ' day_sat' : ( currWeekDay == 0 ? ' day_sun' : '' ) ) + '"><div class="' +( currWeekDay == 6 ? ' day_s' : ( currWeekDay == 0 ? ' day_s' : '' ) ) +'">' + ( dayLink ? dayLink : i ) + '</div></td>' );

		}

	}

	// Render end empty ( 49 = 42 days + 7 top )
	while( cellHhtmls.length < 49 ) {
		cellHhtmls.push( '<td class="day_empty"></td>' );
	}

	var html = '<table class="calendar">';
	var row = 0;
	
	html += '<tr>';

	// If first row - we have month selector
	html += '<td class="month_selector" colspan="7">'		
	html += '<table><tr><td><div class="prev_month" onclick="Calendar.getInstance().setMonth( -1 );">&nbsp;</div></td>';
	html += '<td class="wf tac"><div class="month_year"> ' + this.monthNames[this.lang][renderMonth - 1]+' ';
	html += renderYear.toString() + ' </div></td>';
	html += '<td><div class="next_month" onclick="Calendar.getInstance().setMonth( 1 );">&nbsp;</div></td></tr></table>';
	html += '</td>';
	html += '</tr>';

	// Now render all the stuff
	while( cellHhtmls.length > 0 ) {


		// Add all cells
		html += cellHhtmls.slice( 0, 7 ).join( '' ) + '</tr>';

		// Splice up cells
		cellHhtmls = cellHhtmls.slice( 7 );

		// Increase row
		row++;

	}

	html += '</table>';
	try { 
		$( this.calendarElementId ).innerHTML = html;
	} catch( error ) {
		// Failed to render
	}
	
}

