/* CONFIG/ GLOBALS */

var dayNames = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
var dayAbbrevs = new Array("S", "M", "T", "W", "T", "F", "S");
var monthNames = new Array ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
var monthLength = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

var firstDayOfWeek = 0;
var DEBUG = 1;
var globalDateHash = new Object();

/************************************** helper functions ************************/
function debug(message) {
  if (DEBUG)
    alert(message);
}

/* Trims the starting zero off of a number to ensure JS gets a regular int, not an octal */
function trimStartingZero(number) {
	number = (number + '');
	if (number.substring(0,1) == "0") {
		number = number.substring(1,number.length)
	}
	return parseInt(number);
}
/* parses datetime */
function parseDT(dt) {
	var dtText;
	var result;
	if ($(dt).attr('title')) {
		dtText = $(dt).attr('title');
	} else {
		dtText = $(dt).children([0]).html();
	}
  	if (dtText != null) {
		result = dtText.match( /^(\d{4})(\d{2})(\d{2})/ );
	}
	if (result == null) {
    	//	debug("didn't recognize DT: " + dtText);
		return
  	}
  	return [result[1], result[2], result[3]];
}

// TODO deal with leap year
getMonthLength = function(year, month) {
  return monthLength[month - 1];
}
/*********************************************************************
**	First: check for abilities and readiness 
**	Second: find events (.vevent), process and add to globalDateHash
**	Third: make month tables and append to page 
**********************************************************************/
function findHCalendarEvents () {
  if (!(document.getElementById && document.createElement)) {
    debug("No DOM!");
    return;
  }
  if ($('#jhCalendar') == null) {  
    debug("jhCalendar not found!")
    return;
  }
 
  $('.vcalendar .vevent').each(function() {
    	var eventHash = {};
  	var startDateInfo;
  	var endDateInfo;
  	eventHash.summary = $(this).find(".summary, :first").html();
 	eventHash.description = $(this).find(".description").html();
 	eventHash.time = $(this).find(".time, :first").html();
	eventHash.location = $(this).find(".location").html();
	startDateInfo = parseDT($(this).children(".dtstart")); 
	
	endDateInfo = parseDT($(this).children(".dtend"));
	if (endDateInfo == null) {
		endDateInfo = [[startDateInfo[0]],[startDateInfo[1]],[startDateInfo[2]]];
 	}
 	var startDate = startDateInfo[2];
 	var endDate = endDateInfo[2];

	// handle events that span months:
	// If event goes into next month, grab end of this month and add event until then.
	// If event starts in previous month, grab start of month and add event till end date.
	if ((startDateInfo[0] < endDateInfo[0]) || 	// if start year < end year
		(startDateInfo[1] < endDateInfo[1]) )	 // if start month < end month
		 {
			
		endDate = getMonthLength(startDateInfo[0], startDateInfo[1]);
		addEventHashToGlobalDateHash(eventHash, startDateInfo, startDate, endDate);
		
		carryOverStartDate = 1;
		endDate = parseInt(endDateInfo[2]);
		addEventHashToGlobalDateHash(eventHash, endDateInfo, carryOverStartDate, endDate);
	} 
	//For events that are within a single month, just populate the event days normally.
	else {
		addEventHashToGlobalDateHash(eventHash, startDateInfo, startDate, endDate);
	}
	return;  
  });
  i =0;
  for (year in globalDateHash) {
   	for (month in globalDateHash[year]) {
   	  var mt = makeMonthTable(globalDateHash[year][month], year, month);
      $('#jhCalendar').append(mt);
       i++;
    }
  }
  if (i%3 > i/3) {
  	$('#jhCalendar').css('height', (i%3)*140);
  	} else {
  		$('#jhCalendar').css('height', ((i/3)+.6)*148);
  	}
//  $('#jhCalendar').append('<hr />');

}


/**
 * Adds EventHash Object representing Event Data on a specific Day to the GlobalDateHash Object. 
 * If the startDateDay and endDateDay are not equal, the event will be added to all Days in between.
 */
function addEventHashToGlobalDateHash(eventHash, dateInfo, startDate, endDate) {
	// ParseDT returns an Array with three parts:
	// First [0] is the Year, Second [1] is the Month, Third [2] is the Day. 
	//  If the startDate is not equal to endDate, it's a multi-day event and we must loop through 
	// and add the event for each day in the span globalDateHash.
	for (var i = trimStartingZero(startDate); i <= trimStartingZero(endDate); i++) {
		// If the Year doesn't exist in the globalDateHash, add Object for it.
		if (globalDateHash[ dateInfo[0] ] == null) {
			globalDateHash[ dateInfo[0] ] = new Object();
		}
		// If the Month doesn't exist in the globalDateHash, add Object to represent it.
		if (globalDateHash[ dateInfo[0] ][ dateInfo[1] ] == null) {
			globalDateHash[ dateInfo[0] ][ dateInfo[1] ] = new Object();
		}
		// If the Day doesn't exist in the globaDateHash, add Array to store Events on this day.
		if (globalDateHash[ dateInfo[0] ][ dateInfo[1] ][ i ] == null) {
			globalDateHash[ dateInfo[0] ][ dateInfo[1] ][ i ] = new Array();
		}
		// Add this Event to the Array List of Events for this Day.
		globalDateHash[ dateInfo[0] ][ dateInfo[1] ][ i ].push(eventHash);
	}
}

//Create Table of the specified Month for the specified Year, with events. 
function makeMonthTable (monthHash, year, month) {
  currentMonthLength = getMonthLength(year, month);
  previousMonthLength = getMonthLength(year, month-1);
  if (month == 1) { // for January to know previous month
  	previousMonthLength = 31;
  }
  var today = new Date;
  var todayYear = today.getFullYear();
  var todayMonth = today.getMonth() + 1;
  var todayDay = today.getDate();    
  var days = new Array(currentMonthLength+1); // We are going to index this array starting at 1.  Because I said so.
  
  // Create an HTML Table to Represent the Month and set necessary Attributes.
  var monthTable =  document.createElement('table');
  $(monthTable).addClass('calTable');
  
 // Create thead with rows for month/year, full day names and abbreviated day names
    var thead = document.createElement("thead");
    $(monthTable).append(thead);

  var titleRow = document.createElement('tr');
  $(thead).append(titleRow)
  $(titleRow).html('<th class="calHeader" colspan="7">' + monthNames[trimStartingZero(month)-1] + ' ' + year + '</th>');

  //var titleTH = document.createElement('th')
  //$(titleRow).append($(titleTH).addClass('calHeader'));
  //$(titleTH).attr("colspan", 7);  
  //$(titleTH).html(monthNames[trimStartingZero(month)-1] + " " + year);
  
  var headerRow = document.createElement('tr');
	for (var i = 0; i < dayNames.length; i++) {
		$(headerRow).append('<th>' + dayNames[i] + '</th>');
	}
  $(thead).append($(headerRow).addClass('longDays'));

  var abbrevHeaderRow = document.createElement('tr');
	for (var i = 0; i < dayAbbrevs.length; i++) {
	//	abbrevHeaderRow.innerHTML() +=  '<th>' + dayAbbrevs[i] + '</th>';	
		$(abbrevHeaderRow).append('<th>' + dayAbbrevs[i] + '</th>');
	}
  $(thead).append($(abbrevHeaderRow).addClass('abbrevDays'));
  	
  // create tbody and fill with days
  var tbody = document.createElement("tbody");
  $(monthTable).append(tbody);

  for (var i = 1; i <= currentMonthLength; i++) {
    days[i] = document.createElement('td');
    if (todayYear == year && todayMonth == month && todayDay == i) {
      days[i].className += ' calDayToday';
    }
    $(days[i]).append('<div class="calDayLabel">' + i + '</div>');
  }
  
  // populate days here
  for (var day in monthHash) {
    var eventString = '';
    for (var i = 0; i < monthHash[day].length; i++) {
      dayTD = days[day-0];
	$(dayTD).addClass('calEventDay');
	eventString += '<p><strong>' + monthHash[day][i].summary + '</strong> ';
	if (monthHash[day][i].location) {   
                eventString += monthHash[day][i].location + ' ';
        }

	if (monthHash[day][i].description) {
		eventString += monthHash[day][i].description;
	}
	eventString += '</p>';
	$(dayTD).append('<div class="event">' + eventString + '</div>');
    }
  }    
  var dateToCheck = new Date();
  dateToCheck.setYear(year);
  dateToCheck.setDate(1);
  dateToCheck.setMonth(month-1);
  var dayOfFirstOfMonth = dateToCheck.getDay();

  var row = tbody.appendChild(document.createElement("tr"));
  // Loop through empty Days before first Day of Month and fill with 'outOfRange' Cells.
	for (var i = 0; i < dayOfFirstOfMonth; i++) {
		$(row).append('<td class="outOfRange"><div class="calDayLabel"> ' + (previousMonthLength - (dayOfFirstOfMonth - i-1)) + '</div></td>');
	}
  rowcount = 0;	
  for (var i = 1; i <= currentMonthLength; i++) {
  	
    if (row.childNodes.length == 7) {
      row = tbody.appendChild(document.createElement("tr"));
      rowcount++;
    }
    if(row.childNodes.length == 0 ||row.childNodes.length == 6){
	$(days[i]).addClass('weekend');
	}	
    row.appendChild(days[i]);
  }
  // fill in next month's days to end
  newmonth = 1;
  while (row.childNodes.length < 7) {
      $(row).append('<td class="outOfRange"><div class="calDayLabel">' + newmonth + '</div></td>');
	newmonth++;
  }
  if (rowcount<5) {
  	monthTable.className += ' shortTable' 
  	//tbody.innerHTML += '<tr><td colspan="7">&nbsp;</td></tr>';
  }
  return monthTable;
}

$(document).ready(findHCalendarEvents);
