/*
**   Calendar.js
**
**   Script for generating HTML representation of a calendar and
**   displaying events attached to days in the calendar
**
**   Prepared By T. Biskupic
**
**   Copyright Abotsfor 12ft Flying Squadron 2006
*/

/*
**  This string is the top line of the calendar with the days of the week
**  as cells. 
*/
var CalTopLine = "<tr><td>SU</td><td>MO</td><td>TU</td><td>WE</td><td>TH</td><td>FR</td><td>SA</td></tr>\n";

/*
**  This array defines the number of days in the month. The value for
**  February needs to be then fixed depending on whether it is a leap
**  year. There must be a better way to do this!
*/
var DaysPerMonth = [31,28,31,30,31,30,31,31,30,31,30,31];

/*
**  This array defines the english names of each month. 
**	It's too hard parsing this out of the locale formatted value.
*/
var MonthNames = ["January","February","March","April","May","June","July","August","September","October","November","December"];

/*
**  These constants define buttons for advancing to the next/previous
**  month
*/
var PreviousButton = "<input type=\"button\" value=\"&lt;\" onClick=\"monthPrev()\"/>";
var NextButton = "<input type=\"button\" value=\"&gt;\" onClick=\"monthNext()\"/>";

/*
**	These define the current year/month being displayed
*/
var MonthToDisplay=0;
var YearToDisplay=0;

/*
**	These are a copy of the event array and event type array we are 
**	currently working with
*/
var Events;
var EventTitles;
var EventTypes;

/*
**	The name of the div that contains the list of things on
*/
var stuffOnDiv = "stuffOn";

/*
**  Finds an event on a certain day or returns NULL if no
**  events are present
*/
function findEvents(day,month,year)
{
	var eventsOnDay = new Array();
	
    for(i=0;i<Events.length;i++)
    {
        if (    Events[i].day == day 
                && 
                Events[i].month == month 
                && 
                Events[i].year == year )
        {
            eventsOnDay.push(Events[i]);
        }
    }

    return eventsOnDay;
}

/*
**	Find the next event in the calendar from todays date
*/
function findNextUpcoming()
{
	var now = new Date();
	var nextEvent = null;
	var nextEventDate = null;
	
    for(i=0;i<Events.length;i++)
    {
		var eventDate = new Date(Events[i].year,Events[i].month-1,Events[i].day,23,59,0,0);

		//
		//	First check is this event in the past
		//
		if ( eventDate.getTime() > now.getTime() )
		{
			//
			//	Now Is this event sooner than the current soonest event?
			//
			if (	nextEvent == null 
					|| 
					( nextEventDate.getTime() > eventDate.getTime() ) )
			{
				nextEvent = Events[i];
				nextEventDate = eventDate;
			}
		}		
    }
    
    return nextEvent;
}

/*
**	Choose event class based on the events scheduled for a given day
**	The event types are ordered in terms of importance so we take the biggest
**	event type
*/
function getEventClassFromEvents(events)
{
	var eventType = 0;
	
	for( var i=0;i<events.length;i++)
	{
		if ( events[i].type >= eventType )
		{
			eventType = events[i].type;
		}
	}
	
	return EventTypes[eventType].eventClass;
}

/*
**	Returns the event type ID if there are events on the day specified in the array.
**	and null if there are none.
*/
function isEventOnDay(day,month,year)
{    
	var foundEvents = findEvents(day,month,year);
	
	if ( foundEvents.length != 0 )
	{
		return getEventClassFromEvents(foundEvents);
	}
	else
	{
		return null;
	}
}

/*
**  Generates the HTML for the events on a particular day
**
**	Takes the day, month and year of the day we are displaying the
**	events for and the event array and event type array
*/
function getEvents(day,month,year)
{
    var foundEvents = findEvents(day,month,year);
    
    var date = new Date(year,month-1,day,0,0,0,0);
    
    var returnVal = "<center><h2>"+date.toLocaleDateString()+"</h2></center><br />";
	
	if ( foundEvents.length == 0 )
	{
		returnVal += "<p>No events to display for this date</p>";
		return returnVal;
	}
	
	//
	//	Go through each time of event one by one, display the event
	//	title and then each of the events
	//
	for(eventTitle=0;eventTitle<EventTitles.length;eventTitle++)
	{
		var displayedEventTitle=false;
		
		for(i=0;i<foundEvents.length;i++)
		{
			if ( foundEvents[i].title == eventTitle )
			{
				//
				//	This stops the event type title being displayed
				//	unless there are events on this day for that event
				//	type
				//
				if ( ! displayedEventTitle )
				{
					returnVal += "<h3>"+EventTitles[eventTitle]+"</h3>";
					displayedEventTitle=true;
				}
				
				eventClass = EventTypes[foundEvents[i].type].eventClass;
				returnVal += "<table border=\"0\"><tr><td>&nbsp;&nbsp;&nbsp;</td><td class=\""+eventClass+"\" >&nbsp;</td>";
				returnVal += "<td>"+foundEvents[i].desc+"</td></tr></table></li>";
			}
		}
		if ( displayedEventTitle )
		{
			returnVal += "</ul>";
		}
	}

	return  returnVal;
}

function isLeapYear(year)
{
	if ( (year % 4) != 0 )
	{
		return false;
	}
	
	if ( (year % 100) != 0 )
	{
		return true;
	}
	
	if ( (year % 400) == 0 )
	{
		return true;
	}	
	
	return false;
}

function daysInMonth(year,month)
{
	var days = DaysPerMonth[month-1];
	
	if ( month == 2 && isLeapYear(year) )
	{
		days++;
	}
	
	return days;
}

/*
**  Displays a Month as HTML
*/
function displayMonth(year,month)
{
    var returnVal = "";
    
    //
    //  Setup a table of 7 columns
    //
    var day;
    var weekday;
    
    //
    //  Create a date object for the first day of the month
    //  and figure out which day to start on
    //
    var date = new Date(year,month-1,1,0,0,0,0);
    weekday = date.getDay();

    var monthName = MonthNames[month-1];

    //
    //  Print the table line and then the days line
    //
    returnVal += "<table class=\"calendar\">\n";
    returnVal += "<tr>";
    returnVal += "<td id=\"CalNavPrev\">"+PreviousButton+"</td>";
    returnVal += "<td id=\"CalTitle\" colspan=\"5\">"+monthName+" "+year+"</td>";
    returnVal += "<td id=\"CalNavNext\">"+NextButton+"</td>";    
    returnVal += "</tr>";
    returnVal += CalTopLine;
    returnVal += "<tr>";
    
    //
    //  Fill the blanks before the first day of the month
    //
    var i;
    for(i=0;i<weekday;i++)
    {
        returnVal += "<td>&nbsp;</td>";
    }
    
    var daysThisMonth = daysInMonth(year,month);
    
    //
    //  Now print the rest of the table
    //
    for(day=1;day<=daysThisMonth;day++,weekday++)
    {
        if ( (weekday % 7) == 0 )
        {
            returnVal += "</tr><tr>";
        }
        
        var dayString;
        
        eventClass = isEventOnDay(day,month,year);
        
        if ( eventClass != null )
        {
            var displayEventsCall = "\"displayEvents("+String(day)+","+String(month)+","+String(year)+")\"";
            dayString = "<a onClick="+displayEventsCall+" >"+String(day)+"</a>";
        }
        else
        {
            dayString = String(day);
			eventClass = "NoEvent";
        }

        returnVal += "<td class=\""+eventClass+" day\">"+dayString+"</td>";        
    }
    
    if ( ( weekday % 7 ) != 0 )
    {
        var blanks = 7 - (weekday % 7);
    
        for(i=0;i<blanks;i++)
        {
            returnVal += "<td>&nbsp;</td>";
        }        
    }
    
    returnVal += "</tr></table>";
    
    return returnVal;
}

function displayCalendar(events,eventTitles,eventTypes)
{
	Events = events;
	EventTitles = eventTitles;
	EventTypes = eventTypes;
	
	document.write("<table border=\"0\">");
	document.write("<tr valign=\"top\">");
	document.write("<td><div id=\"calendar\">&nbsp;</div></td>");
	document.write("<td rowspan=\"2\"><div id=\""+stuffOnDiv+"\"></div></td>");
	document.write("</tr>");
	
	//
	//	Display the legend
	//
	document.write("<tr valign=\"top\"><td><table border=0>");
	for(i=0;i<eventTypes.length;i++)
	{
		document.write("<tr valign=\"top\" >");
		document.write("<td class=\""+eventTypes[i].eventClass+"\">&nbsp;</td>");
		document.write("<td >"+eventTypes[i].desc+"</td>");
		document.write("<tr>");
	}
	document.write("</table></td></table>");
	
	var nextEvent = findNextUpcoming();
	var dayToDisplay=0;
	
	if ( nextEvent == null )
	{
		var now = new Date();
		MonthToDisplay=now.getMonth()+1;
		YearToDisplay=now.getFullYear();
		dayToDisplay=now.getDay();
	}
	else
	{
		MonthToDisplay=nextEvent.month;
		YearToDisplay=nextEvent.year;
		dayToDisplay=nextEvent.day;
	}

	document.getElementById("calendar").innerHTML = 
		displayMonth(YearToDisplay,MonthToDisplay); 
		
	displayEvents(dayToDisplay,MonthToDisplay,YearToDisplay);
}

function monthNext()
{
	MonthToDisplay += 1;
	if ( MonthToDisplay == 13 )
	{
		MonthToDisplay = 1;
		YearToDisplay += 1;
	}		
	
	document.getElementById("calendar").innerHTML = 
		displayMonth(YearToDisplay,MonthToDisplay); 
}

function monthPrev()
{
	MonthToDisplay -= 1;
	if ( MonthToDisplay == 0 )
	{
		MonthToDisplay = 12;
		YearToDisplay -= 1;
	}
	
	document.getElementById("calendar").innerHTML = 
		displayMonth(YearToDisplay,MonthToDisplay); 
}

function displayEvents(day,month,year)
{
	var htmlText = getEvents(day,month,year);
			
	document.getElementById(stuffOnDiv).innerHTML = htmlText;
}

