﻿// Event Calendar Functions
var infoFrame = null;
var calendarTable = null;
var viewCalendar = null;
var viewList = null;
var dayCells = null;
var loaderFrame = null;
var calNav = null;
var currMonth;
var currYear;
var monthNames = ['January','February','March','April','May','June','July','August','September','October','November','December'];
var shortMonthNames = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var calEvents = null;
var calDayEvents = null;

var eventTypes = [
	{type:0,name:'None','class':null},
	{type:1,name:'Host Webinars','class':'hostWebinar'},
	{type:2,name:'Supplier Webinars','class':'supplierWebinar'},
	{type:3,name:'Other Webinars','class':'webinar'},
	{type:4,name:'Seminars at Sea or Land Fams','class':'seminarAtSea'},
	{type:5,name:'Regional Meetings','class':'regionalMeeting'},
	{type:6,name:'Annual Conventions','class':'annualConvention'},
	{type:7,name:'Mastermind Webinar','class':'mastermind'},
	{type:8,name:'Special Events','class':'specialEvent'}
];

//Cell classes
// inactive - Not a valid day of the current month
// active - Is a valid day of the current month
// empty - Day has no events
// hasEvent - Day has an event
// today - Day is the current date

//Update the text displayed in the calendar navigation
function updateNav() {
	$('txtCurrYear').set('text',currYear);
	$('txtCurrMonth').set('text',monthNames[currMonth]);
}

//Flip calendar one month backwards
function prevMonth(ev) {
	if (isModal()) { return; }
	if (currMonth == 0) {
		currMonth = 11;
		currYear--;
	} else {
		currMonth--;
	}
	setMonth();
	ev.stop();
	return false;
}

//Flip calendar one month forward
function nextMonth(ev) {
	if (isModal()) { return; }
	if (currMonth == 11) {
		currMonth = 0;
		currYear++;
	} else {
		currMonth++;
	}
	setMonth();
	ev.stop();
	return false;
}

//Flip calendar one year backwards
function prevYear(ev) {
	if (isModal()) { return; }
	currYear--;
	setMonth();
	ev.stop();
	return false;
}

//Flip calendar one year forward
function nextYear(ev) {
	if (isModal()) { return; }
	currYear++;
	setMonth();
	ev.stop();
	return false;
}

// Determine if the given year is a leap year
function isLeapYear(year) {
	if (year % 4 != 0) { return false; }
	if ((year % 100 == 0) && (year % 400 != 0)) { return false; }
	return true;
}

// Handles successful HttpRequests for event information
function processEvents(responseText)
{
	var response = JSON.decode(responseText);
	if (response.stat != 'ok')
	{
		alert('Error('+response.number+'):'+response.message);
		return;
	}
	if (((response.month-1) != currMonth) || (response.year != currYear))	//Month is converted from [1..12] to [0..11]
	{
		//This response is not for the month we currently are viewing, discard the result
		return;
	}
	toggleLoader(false);	//Toggle the loading animation OFF
	calEvents = response.events;	//Our array of calendar events
	calDayEvents = new Array();		//Array of days, each containing an array of events on that day (or undefined)
	viewList.empty();
	if (calEvents.length == 0) {
		viewList.set('html','<div class="noEvents">No events for this month.</div>');
	}
	for (var i = 0; i < calEvents.length; i++)	//Loop through each event
	{
		var thisEvent = calEvents[i];			//Reference to event we're processing
		var startDate = new Date(thisEvent.startDate);	//Parse start date
		thisEvent.startDate = startDate;
		var endDate = new Date(thisEvent.endDate);		//Parse end date
		thisEvent.endDate = endDate;
		
		var eventListEntry = createEventList(thisEvent);
		viewList.grab(eventListEntry);
		
		var startDay;	//First day to display for the event
		var startMonth = startDate.getMonth();			//Get which month the event starts
		if (startMonth != currMonth) {
			//Event started in the previous month, begin display on 1st of this month
			startDay = 0;
		} else {
			//Event started in this month, begin display on day it starts
			startDay = startDate.getDate() - 1;
		}
		var endDay;
		var endMonth = endDate.getMonth();				//Get which month the event ends
		if (endMonth != currMonth) {
			//Event ends next month, end display on last day of this month
			endDay = daysInMonth(currMonth) - 1;
		} else {
			//Event ends this month, end display on day it ends
			endDay = endDate.getDate() - 1;
		}

		//Loop through days to display
		var thisDay = startDay;
		while (thisDay <= endDay)
		{
			var cell = dayCells[thisDay];	//Grab table cell for that day
			cell.addClass('hasEvent');		//Signal that the cell contains an event
			if (!$defined(calDayEvents[thisDay]))		//If we haven't already created an array to store events for this day
			{
				//Create the array to hold events for this day
				calDayEvents[thisDay] = new Array();
				//Add a click handler to this day to display event info
				cell.getElement('.date a').addEvent('click',showDayInfo.bindWithEvent(this,thisDay));
			}
			//Add this event to the end of our array of events for the day
			calDayEvents[thisDay][calDayEvents[thisDay].length] = thisEvent;
			
			thisDay++;	//Loop to next day
		}
	}
	
	for (i = 0; i < calDayEvents.length; i++)
	{
		if ($defined(calDayEvents[i]))
		{
			var str = '';
			var needComma = false;
			for (var j = 0; j < calDayEvents[i].length; j++)
			{
				if (needComma) { str = str + ', '; }
				str = str + calDayEvents[i][j].title;
				needComma = true;
			}
			dayCells[i].getElement('.date a').set('title',str);
			dayCells[i].getElement('.date a').appendText(str);
		}
	}
}

//Create an HttpRequest for a list of events for the current calendar month/year
function getEvents()
{
	var request = new Request({url: '/GetEvents.ashx'});
	
	request.addEvent('success',processEvents);
	var data = 'month='+(currMonth+1)+'&year='+currYear;	//Add 1 to month to move from [0..11] to [1..12] for months
	request.send(data);
}

// Toggle the loader frame either on or off
function toggleLoader(turnOn)
{
	if (turnOn) {
		loaderFrame.removeClass('hidden');
		calendarTable.addClass('faded');
		calNav.addClass('faded');
	} else {
		loaderFrame.addClass('hidden');
		calendarTable.removeClass('faded');
		calNav.removeClass('faded');
	}
}

// Toggle the info frame either on or off
function toggleInfo(turnOn)
{
	if (turnOn) {
		infoFrame.removeClass('hidden');
		calendarTable.addClass('faded');
		calNav.addClass('faded');
	} else {
		infoFrame.addClass('hidden');
		calendarTable.removeClass('faded');
		calNav.removeClass('faded');
	}
}

// Determine how many days are in a given month
//	month - The month in a range of 0 (January) to 11 (December)
//  year - optional - Used for leap year determinations, defaults to currYear
// Returns: 30 for April, June, September, November, 28 or 29 for February and 31 for any other month
function daysInMonth(month,year)
{
	year = year || currYear;
	if (month < 0) month = 11;
	if (month > 11) month = 0;
	switch (month) {	//Sept(8) Apr(3) Jun(5) Nov(10) == 30 days
		case 3:
		case 5:
		case 8:
		case 10:
			return 30;
			break;
		case 1:	//February has 28 usually, 29 on leap years
			if (isLeapYear(year))
			{
				return 29;
			} else {
				return 28;
			}
			break;
	}
	return 31;
}

// Modifies the calendar table when the month is changed
function setMonth()
{
	toggleLoader(true);
	getEvents();	//Load events from server
	updateNav();
	var prevDayCount = daysInMonth(currMonth - 1);
	var dayCount = daysInMonth(currMonth);
	$$('#calendarTable .date a').removeEvents('click');
	var date = new Date(currYear,currMonth,1,1,1,1,1);
	var day = date.getDay();
	var row = 0;
	var col = day;
	dayCells = new Array();
	var prevMonthCount = prevDayCount - day + 1;
	for (var pre = 0; pre < day; pre++) {
		var cell = $('day0'+pre);
		cell.className = 'inactive';
		cell.getElement('.date a').set('html','<span class="day"></span>');
		cell.getElement('.date a .day').set('text',prevMonthCount);
		prevMonthCount++;
	}
	for (var i = 0; i < dayCount; i++)
	{
		var cell = $('day'+row+col);
		cell.className = 'active';
		dayCells[i] = cell;
		cell.getElement('.date a').set('html','<span class="day"></span>');
		cell.getElement('.date a .day').set('text',i+1);
		col++;
		col = col % 7;
		if (col == 0) { row++; }
	}
	var nextMonthCount = 1;
	while (row <= 5) {
		while (col <= 6) {
			var cell = $('day'+row+col);
			cell.className = 'inactive';
			cell.getElement('.date a').set('html','<span class="day"></span>');
			cell.getElement('.date a .day').set('text',nextMonthCount);
			nextMonthCount++;
			col++;
		}
		col = 0;
		row++;
	}
	
	//Highlight today's date if we're viewing the current month
	var now = new Date();
	if ((now.getMonth() == currMonth) && (now.getFullYear() == currYear)) {
		var todayCell = dayCells[now.getDate()-1];
		todayCell.addClass('today');
	}
}

// Determine whether to ignore requests for info frame or navigation
//	- Returns true when the info frame is visible
function isModal()
{
	if (infoFrame.getStyle('display') == 'block') return true;
	else return false;
}

// Attempt to display the info frame for a given day
function showDayInfo(ev,day)
{
	if (isModal()) { return; }

	$('dateTitleBar').set('text',monthNames[currMonth] + ' ' + (day + 1) + ', ' + currYear);
	var endStyle = '.infoPopupBig';
	var initStyle = '.infoPopupInit';
	if (Browser.Engine.trident && Browser.Engine.version < 5) {
		initStyle = '.infoPopupInitIE6';
		endStyle = '.infoPopupBigIE6';
	}
	toggleInfo(true);	//Display info
	//Animate the info frame
	var infoContent = $('infoContent');
	infoContent.addClass('hidden');
	var fx = new Fx.Morph(infoFrame,{duration: 200, transition: 'linear'});
	fx.addEvent('complete',function(){
		infoContent.removeClass('hidden');
	});
	fx.set(initStyle).start(endStyle);

	infoContent.empty();
	var eventsArray = calDayEvents[day];
	for (var i = 0; i < eventsArray.length; i++)
	{
		var thisEvent = eventsArray[i];
		var newEl = createEventInfo(thisEvent);
		infoContent.grab(newEl);
	}

	ev.stop();
	return false;
}

function buildWhenString(ev)
{
	var when = "All Day";
	if (!ev.allDay) {
		var sH = ev.startDate.getHours();
		var sM = ev.startDate.getMinutes();
		var sAM = "AM";
		var eH = ev.endDate.getHours();
		var eM = ev.endDate.getMinutes();
		var eAM = "AM";
		if (sH >= 12) sAM = "PM";
		if (eH >= 12) eAM = "PM";
		sH = sH % 12;
		if (sH == 0) sH = 12;	//0 hour -> 12 AM/PM
		eH = eH % 12;
		if (eH == 0) eH = 12;	//0 hour -> 12 AM/PM
		if (sM < 10) sM = '0' + sM;
		if (eM < 10) eM = '0' + eM;
		
		when = sH + ':' + sM + ' ' + sAM + ' - ' + eH + ':' + eM + ' ' + eAM;
	}
	return when;
}

function addEventTypeClass(ev, element)
{
	if ((ev.eventType < 0) || (ev.eventType >= eventTypes.length))
	{
		return;
	}

	var className = eventTypes[ev.eventType]['class'];
	if ($chk(className))
	{
		$(element).addClass(className);
	}
}

// Create a div element to display an event in list view
function createEventList(ev)
{
	var container = new Element('div',{
		'class':'eventEntry listEntry'
	});
	addEventTypeClass(ev, container);
	var content = new Element('div',{
		'class':'catalogContent'
	});
	if (ev.thumbFileName != '') {
		var thumbHolder = new Element('div',{
			'class':'thumbHolder'
		});
		thumbHolder.set('html','<a href="/events/' + ev.id + '/" title="View Details"><img src="/uploads/eventImages/' + ev.thumbFileName + '" alt="" /></a>');
		content.grab(thumbHolder);
	}
	var eventDate = null;
	if ((ev.endDate.getDate() != ev.startDate.getDate()) || (ev.startDate.getMonth() != ev.endDate.getMonth()))
	{
		eventDate = new Element('div',{
			'class':'eventDate isDateSpan',
			'html':'From<div>'+ ev.startDate.getDate()+'</div><span>'+ shortMonthNames[ev.startDate.getMonth()] +'</span>'
		});
		content.grab(eventDate);
		eventDate = new Element('div',{
			'class':'eventDate isDateSpan',
			'html':'until<div>'+ ev.endDate.getDate()+'</div><span>'+ shortMonthNames[ev.endDate.getMonth()] +'</span>'
		});
	} else {
		eventDate = new Element('div',{
			'class':'eventDate',
			'html':'<div>'+ ev.startDate.getDate()+'</div><span>'+ shortMonthNames[ev.startDate.getMonth()] +'</span>'
		});
	}
	content.grab(eventDate);
	var title = new Element('span',{
		'class':'itemTitle',
		'text':ev.title
	});
	content.grab(title);
	var br = new Element('br');
	content.grab(br);
	var lblWhere = new Element('label',{
		'text':'Where:'
	});
	var spanWhere = new Element('span',{
		'class':'eventVenue',
		'text':ev.venueName
	});
	content.grab(lblWhere);
	content.grab(spanWhere);
	content.grab(br.clone());
	var lblWhen = new Element('label',{
		'text':'When:'
	});
	var when = buildWhenString(ev);
	var spanWhen = new Element('span',{
		'class':'eventWhen',
		'text':when
	});
	content.grab(lblWhen);
	content.grab(spanWhen);
	var divClear = new Element('div',{
		'styles':{
			'clear':'both'
		},
		'html':'<!-- -->'
	});
	content.grab(divClear);
	var actionBar = new Element('div',{
		'class':'actionsBar'
	});
	var detailLink = new Element('a',{
		'href':'/events/' + ev.id + '/',
		'text':'More Details...'
	});
	actionBar.grab(detailLink);
	
	container.adopt(content,actionBar);
	return container;
}

// Create a div element to display an event in the info frame
function createEventInfo(ev)
{
	var container = new Element('div',{
		'class':'eventEntry infoEntry'
	});
	addEventTypeClass(ev, container);
	var content = new Element('div',{
		'class':'catalogContent'
	});
	if (ev.thumbFileName != '') {
		var thumbHolder = new Element('div',{
			'class':'thumbHolder'
		});
		thumbHolder.set('html','<a href="/events/' + ev.id + '/" title="View Details"><img src="/uploads/eventImages/' + ev.thumbFileName + '" alt="" /></a>');
		content.grab(thumbHolder);
	}
	var title = new Element('span',{
		'class':'itemTitle',
		'text':ev.title
	});
	content.grab(title);
	var br = new Element('br');
	content.grab(br);
	var lblWhere = new Element('label',{
		'text':'Where:'
	});
	var spanWhere = new Element('span',{
		'class':'eventVenue',
		'text':ev.venueName
	});
	content.grab(lblWhere);
	content.grab(spanWhere);
	content.grab(br.clone());
	var lblWhen = new Element('label',{
		'text':'When:'
	});
	var when = buildWhenString(ev);
	var spanWhen = new Element('span',{
		'class':'eventWhen',
		'text':when
	});
	content.grab(lblWhen);
	content.grab(spanWhen);
	var divClear = new Element('div',{
		'styles':{
			'clear':'both'
		},
		'html':'<!-- -->'
	});
	content.grab(divClear);
	var actionBar = new Element('div',{
		'class':'actionsBar'
	});
	var detailLink = new Element('a',{
		'href':'/events/' + ev.id + '/',
		'text':'More Details...'
	});
	actionBar.grab(detailLink);
	
	container.adopt(content,actionBar);
	return container;
}

function setView(view)
{
	if (isModal()) return;
	switch (view) {
		case 1:
			//Calendar View
			viewCalendar.removeClass('hidden');
			viewList.addClass('hidden');
			break;
		case 2:
			//List View
			viewCalendar.addClass('hidden');
			viewList.removeClass('hidden');
			break;
	}
}

// Initialize the calendar
window.addEvent('domready', function() {
	viewCalendar = $('viewCalendar');
	calendarTable = $('calendarTable');
	infoFrame = $('dateInfoFrame');
	loaderFrame = $('loadingFrame');
	calNav = $('calendarNav');
	viewList = $('viewList');

	//Init Navigation
	$('calNavPrev').addEvent('click',prevMonth);
	$('calNavNext').addEvent('click',nextMonth);
	$('calNavPrevYear').addEvent('click',prevYear);
	$('calNavNextYear').addEvent('click',nextYear);
	$('linkCalendarView').addEvent('click',function(ev){
		setView(1);
		ev.stop();
		return false;
	});
	$('linkListView').addEvent('click',function(ev){
		setView(2);
		ev.stop();
		return false;
	});

	//Handle closing the info window
	$('dateInfoClose').addEvent('click',function(ev){
		if (infoFrame.getStyle('display') == 'none') { return; }
		toggleInfo(false);	//Remove info frame
		ev.stop();
		return false;
	});
	
	var queryString = window.location.search.substring(1);
	var tmpParams = queryString.split('&');
	var params = {};
	for (var i = 0; i < tmpParams.length; i++)
	{
		var split = tmpParams[i].split('=');
		if (split.length == 1) { split[1] = split[0]; }
		params[split[0]] = split[1];
	}
	if ($chk(params.month) && !isNaN(parseInt(params.month)) && (params.month > 0) && (params.month < 13)) {
		currMonth = params.month - 1;
		if ($chk(params.year) && !isNaN(parseInt(params.month)) && (params.year > 1753) && (params.year < 10000)) {
			currYear = params.year;
		} else {
			var now = new Date();
			currYear = now.getFullYear();
		}
	} else {
		var now = new Date();
		currMonth = now.getMonth();
		currYear = now.getFullYear();
	}
	setMonth();
});