/**
 * Calendar singleton class
 */

/**
 * Constructor
 */
var Calendar = function() {

	this.currEventsCount = null;
	this.selectedDay = null;

	// 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';

	// Day names...
	this.dayNames = {
		lt: ['Pr', 'A', 'T', 'K', 'Pn', 'Š', 'S']
	};

	// Month name
	this.monthNames = {
		lt: ['Sausis', 'Vasaris', 'Kovas', 'Balandis', 'Gegužė', 'Birželis', 'Liepa', 'Rugpjūtis', 'Rugsėjis', 'Spalis', 'Lapkritis', 'Gruodis']
	};

	// Day events...
	this.dayEvents = {};

	// Where to output calendar data
	this.calendarElementId = 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();

};
/**
 * Get render date info by month delta
 */
Calendar.prototype.getDate = function( delta ) {

	var month = (this.renderDate % 100) + delta;
	var year = Math.floor(this.renderDate / 100);

	if ( month > 12 ) {
		month = month % 12;
		year++;
	}
	else if ( month < 1 ) {
		month = 12 + (month);
		year--;
	}
	
	return { 'month': month, 'year': year };
};


/**
 * Set year by delta,
 */
 
Calendar.prototype.setYear = function( delta ) {

	this.renderDate = parseInt(( Math.floor( this.renderDate / 100 ) + delta ) + '' + Math.floor( this.renderDate % 100 ));

	this.render();
};


Calendar.prototype.onDayOver = function( element, count ) {
	element.className += ' day_over';
};

Calendar.prototype.onDayOut = function( element ) {
	
	element.className = element.className.replace( 'day_over', '' );
};

Calendar.prototype.onClick = function( url, date ) {
	
	if ( $( '#events_filter' ).get( 0 ) ) {
		
		date = date.substring( 0, 4 ) + '-' + date.substring( 4, 6 ) + '-' + date.substring( 6, 8 );
		
		$( '#date_from' ).val( date );
		$( '#date_to' ).val( date );
		$( '#events_filter' ).submit();
		
		return false;
	}
	
	window.location = url + '&sel_date=' + date;
};

Calendar.prototype.setSelectedDate = function( date ) {
	this.selectedDate = date;
};

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 );
	}

	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 );
	var prevDayCount 		= Calendar.getMonthDayCount( renderYear, renderMonth - 1 );
	
	// Get begin empty count, fixate for 0 = Sunday
	var beginEmptyCount 	= ( tempDate.getDay() + 6 ) % 7;
	var beginEmptyStart 	= prevDayCount - (beginEmptyCount - 1);
	
	// Cell htmls
	var cellHhtmls = [];

	// Render top row...
	for( var i = 0; i < this.dayNames[this.lang].length; i++ ) {
		if (( i == 5) || ( i == 6 )) {
			cellHhtmls.push( '<td class="cal_day_hdr_free"><div class="free_'+i+'">' + this.dayNames[this.lang][i] + '</div></td>' );
		} else {
			cellHhtmls.push( '<td class="cal_day_hdr"><div>' + this.dayNames[this.lang][i] + '</div></td>' );
		}
	}
	
	var free = 1;
	for( i = beginEmptyStart; i <= prevDayCount; i++ ) {

		var dayHasEvent = null;
		
		var monthDate	= this.renderDate - 1;
		var dayDate 	= monthDate * 100 + i;
		
		if ( this.dayEvents[dayDate] && this.dayEvents[dayDate] > 0 ) {
			dayHasEvent = 1;
			dayEventCount = this.dayEvents[dayDate];
			dayActionsHtml = ' onmouseover="Calendar.getInstance().onDayOver(this, '+dayEventCount+' );" onmouseout="Calendar.getInstance().onDayOut(this);" onclick="Calendar.getInstance().onClick( \''+this.eventsURL+'\',\''+dayDate+'\' );return false;"';
		} else {
			dayEventCount = 0;
			dayActionsHtml = ' onmouseover="Calendar.getInstance().onDayOver(this, '+dayEventCount+' );" onmouseout="Calendar.getInstance().onDayOut(this);"';
		}
		
		cellHhtmls.push( '<td class="cal_day_empty' + ( free == 6 ? '_free' : '' ) + ( dayHasEvent ? ' cal_day_marked' : '' ) + '"' + dayActionsHtml + '><div rel="' + ( monthDate % 100 ) + '">' + i + '</div></td>' );
		free++;
	}

	// Render days
	for (i = 1; i <= dayCount; i++) {
			
		var currDate = new Date();
		currDate.setYear(renderYear);
		currDate.setMonth(renderMonth - 1);
		currDate.setDate(i);
			
		var currWeekDay = currDate.getDay();
		dayDate = this.renderDate * 100 + i;

		dayLink = '';

		if (dayDate == this.selectedDate) {
			
			if ( this.dayEvents[dayDate] && this.dayEvents[dayDate] > 0 ) {
				dayHasEvent = 1;
				dayEventCount = this.dayEvents[dayDate];
				dayActionsHtml = ' onmouseover="Calendar.getInstance().onDayOver(this, '+dayEventCount+' );" onmouseout="Calendar.getInstance().onDayOut(this);" onclick="Calendar.getInstance().onClick( \''+this.eventsURL+'\',\''+dayDate+'\' );return false;"';
			} else {
				dayHasEvent = 0;
				dayEventCount = 0;
				dayActionsHtml = ' onmouseover="Calendar.getInstance().onDayOver(this, '+dayEventCount+' );" onmouseout="Calendar.getInstance().onDayOut(this);"';
			}
			cellHhtmls.push('<td ' + dayActionsHtml + ' class="' + ( ( dayDate == this.selectedDay ) ? 'day_active' : 'cal_day_current' ) + ( dayHasEvent ? ' cal_day_marked' : '' ) + ( currWeekDay == 6 ? ' cal_day_free' : ( currWeekDay === 0 ? ' cal_day_free' : '' ) ) + '"><div rel="' + renderMonth + '">' + i + '</div></td>');
			
		} else {
			
			if ( this.dayEvents[dayDate] && this.dayEvents[dayDate] > 0 ) {
				dayHasEvent = 1;
				dayEventCount = this.dayEvents[dayDate];
				dayActionsHtml = ' onmouseover="Calendar.getInstance().onDayOver(this, '+dayEventCount+' );" onmouseout="Calendar.getInstance().onDayOut(this);" onclick="Calendar.getInstance().onClick( \''+this.eventsURL+'\',\''+dayDate+'\' );return false;"';
			} else {
				dayHasEvent = 0;
				dayEventCount = 0;
				dayActionsHtml = ' onmouseover="Calendar.getInstance().onDayOver(this, '+dayEventCount+' );" onmouseout="Calendar.getInstance().onDayOut(this);"';
			}
			
			cellHhtmls.push('<td ' + dayActionsHtml + ' class="' + ( ( dayDate == this.selectedDay ) ? 'day_active' : '' ) + ( dayHasEvent ? ' cal_day_marked' : '' ) + ( currWeekDay == 6 ? ' cal_day_free' : ( currWeekDay === 0 ? ' cal_day_free' : '' ) ) + '"><div rel="' + renderMonth + '">' + i + '</div></td>');
			
		}
		
	}

	// Render end empty
	var cellsLeft = 49 - cellHhtmls.length;
	
	if ( 49 - cellHhtmls.length >= 7 ) {
		cellsLeft -= 7;
	}
	
	cLeft = cellsLeft;
	for( i = 1; i <= cellsLeft; i++ ) {

		dayHasEvent = null;
		
		monthDate	= this.renderDate + 1;
		dayDate 	= monthDate * 100 + i;
		
		if ( this.dayEvents[dayDate] && this.dayEvents[dayDate] > 0 ) {
			dayHasEvent = 1;
			dayEventCount = this.dayEvents[dayDate];
			dayActionsHtml = ' onmouseover="Calendar.getInstance().onDayOver(this, '+dayEventCount+' );" onmouseout="Calendar.getInstance().onDayOut(this);" onclick="Calendar.getInstance().onClick( \''+this.eventsURL+'\',\''+dayDate+'\' );return false;"';
		} else {
			dayEventCount = 0;
			dayActionsHtml = ' onmouseover="Calendar.getInstance().onDayOver(this, '+dayEventCount+' );" onmouseout="Calendar.getInstance().onDayOut(this);"';
		}
		
		cellHhtmls.push( '<td class="cal_day_empty' + ( cLeft <= 2 ? '_free' : '' ) + ( dayHasEvent ? ' cal_day_marked' : '' ) + '"' + dayActionsHtml + '><div rel="' + ( monthDate % 100 ) + '">' + i + '</div></td>' );
		cLeft--;
	}



	var html = '<table class="calendar_container"><tr><td class="calendar_bg"><div class="calendar_top"></div><div class="calendar">';
	
	html += '<table class="cal_nav"><tr>';
	html += '<td class="cal_arrow cal_arrow_left"><a href="#" onclick="' + "filterEventsByEnterprise( Calendar.getInstance().enterpriseId, Calendar.getInstance().getDate( -1 ).year + '-' + Calendar.getInstance().getDate( -1 ).month, Calendar.getInstance().selectedDay); return false;" + '"></a></td>';
	html += '<td class="wf">' + this.monthNames[this.lang][renderMonth - 1] + ' ' + renderYear + '</td>';
	html += '<td class="cal_arrow cal_arrow_right"><a href="#" onclick="' + "filterEventsByEnterprise( Calendar.getInstance().enterpriseId, Calendar.getInstance().getDate( 1 ).year + '-' + Calendar.getInstance().getDate( 1 ).month, Calendar.getInstance().selectedDay); return false;" + '"></a></td>';
	html += '</tr></table>';

	html += '<table class="cal_days">';
	var row = 0;
	
	html += '<tr class="row_'+row+'">';

	// 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++;
		
		if ( cellHhtmls.length > 0 ) {
			html += '<tr class="row_'+row+'">';
		}
		
	}

	html += '</div></table></td></tr></table>';
	
	try { 
		$( '#' + this.calendarElementId ).get(0).innerHTML = html;
		
		if ( sel_days ) {
		
			var tds = $( '.calendar .cal_days td div' ).get();
			
			for ( var i=0; i < tds.length; i++ ) {
		
				if ( typeof( $( tds[i] ).attr( 'rel' ) ) == 'undefined' ) {
					
					continue;
				} 
				
				var month = $( tds[i] ).attr( 'rel' );
				
				if ( typeof( sel_days[month] ) == 'undefined' ) {
					
					continue;
				}
				
				for ( var n=0; n < sel_days[month].length; n++ ) {
				
					if( tds[i].innerHTML == sel_days[month][n] ) {
						
						var parent = $( tds[i] ).parent();
						
						if ( parent.hasClass( 'cal_day_empty' ) ) {
							
							parent.addClass( 'day_active_empty' );
						} else if ( parent.hasClass( 'cal_day_empty_free' ) ) {
							
							parent.addClass( 'day_active_empty' );
						} else {
						
							parent.addClass( 'day_active' );
						}
					}
				}
			}
		}
	} catch( error ) {
		// Failed to render
	}
	
};