// these are labels for the days of the week
cal_days_labels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

// these are human-readable month name labels, in order
cal_months_labels = ['January', 'February', 'March', 'April',
                     'May', 'June', 'July', 'August', 'September',
                     'October', 'November', 'December'];

// these are the days of the week for each month, in order
cal_days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

// this is the current date
cal_current_date = new Date(); 

function Calendar(month, year) {
  this.month = (isNaN(month) || month == null) ? cal_current_date.getMonth() : month;
  this.year  = (isNaN(year) || year == null) ? cal_current_date.getFullYear() : year;
  this.html = '';
	
	// extended by asg
  var monthLength = cal_days_in_month[this.month];
  // compensate for leap year
  if (this.month == 1) { // February only!
    if((this.year % 4 == 0 && this.year % 100 != 0) || this.year % 400 == 0){
      monthLength = 29;
    }
  }
	
	this.days = new Array(monthLength);

}

Calendar.prototype.generateHTML = function(){

  // get first day of month
  var firstDay = new Date(this.year, this.month, 1);
  var startingDay = firstDay.getDay();
  
  // find number of days in month
  var monthLength = cal_days_in_month[this.month];
  
  // compensate for leap year
  if (this.month == 1) { // February only!
    if((this.year % 4 == 0 && this.year % 100 != 0) || this.year % 400 == 0){
      monthLength = 29;
    }
  }
  
  // do the header
  var monthName = cal_months_labels[this.month]
  var html = '<table class="calendar-table">';
  html += '<tr><th colspan="7">';

	html += '<div style="float: left; width: 33%; text-align: left;">' + '<a href="#" onclick="prev_month();" id="prev_month_link">Previous Month</a>' + '</div><div style="float: left; width: 33%; text-align: center;">';
	
  html +=  monthName + "&nbsp;" + this.year;

	html += '</div><div style="float: right; width: 33%; text-align: right;">' + '<a href="#" onclick="next_month();" id="next_month_link">Next Month</a>' + '</div>';

  html += '</th></tr>';
  html += '<tr class="calendar-header">';
  for(var i = 0; i <= 6; i++ ){
    html += '<td class="calendar-header-day">';
    html += cal_days_labels[i];
    html += '</td>';
  }
  html += '</tr><tr>';

  // fill in the days
  var day = 1;
  // this loop is for is weeks (rows)
  for (var i = 0; i < 9; i++) {
    // this loop is for weekdays (cells)
    for (var j = 0; j <= 6; j++) { 
			// put events in ul
      if (day <= monthLength && (i > 0 || j >= startingDay)) {
	      html += '<td class="calendar-day" id="day_' + day + '">';
        html += day;
				html += '<ul class="day_events">'; // buggy: I'm not putting the events *inside* the ul -- I'm appending to the bottom!
				html += '</ul>';
        day++;
      }
			else {
	      html += '<td class="calendar-day">';
			}
      html += '</td>';
    }
    // stop making rows if we've run out of days
    if (day > monthLength) {
      break;
    } else {
      html += '</tr><tr>';
    }
  }
  html += '</tr></table>';

  this.html = html;
}

Calendar.prototype.getHTML = function() {
  return this.html;
}


// stuff added by me; almost all could be prototypes of class Calendar:

function update_next_prev_links () {
	// update our next/prev links:
	this_month = cal_current_date.getMonth();
	if (this_month == 11)
		n_month = 0;
	else
		n_month = this_month + 1;
	if (this_month == 0)
		p_month = 11;
	else
		p_month = this_month - 1;
	$('next_month_link').innerHTML = cal_months_labels[n_month];
	$('prev_month_link').innerHTML = cal_months_labels[p_month];
}

function next_month () {
	n_month = cal_current_date.getMonth();
	n_year = cal_current_date.getFullYear();
	if (n_month == 11) {
		n_month = 0;
		n_year = n_year + 1;
	}
	else
		n_month = n_month + 1;
	cal_current_date = new Date(n_year,n_month);
	show_calendar(n_month, n_year, 'calendar_box');
	update_next_prev_links();
}

function prev_month () {
	p_month = cal_current_date.getMonth();
	p_year = cal_current_date.getFullYear();
	if (p_month == 0) {
		p_month = 11;
		p_year = p_year - 1;
	}
	else
		p_month = p_month - 1;
	cal_current_date = new Date(p_year,p_month);
	show_calendar(p_month, p_year, 'calendar_box');
	update_next_prev_links();
}

function show_calendar (m,y,id) {
	cal = new Calendar(m, y);
	cal.generateHTML();
	$(id).innerHTML = cal.getHTML();
	fetch_data('calendar_data.txt');
	update_next_prev_links();
}

// var cached_cal;

function fetch_data (url) {
	new Ajax.Request(url, {
		method: "GET",
		onComplete: function(request) {
			display_data(request.responseText);
			}
		});
}

var tip_classes = [];
function display_data (source) {
	// cached_cal = source;
	var event_dates = [];
	// var tip_classes = [];
	var listing;
	var i,j, tip_text_found;

	lines = source.split(/[\r\n]+/);
	for (i=0; i < lines.length; i++) {
		// mm/dd/yy hh:mm:[ss] AM/PM <tab> description <eol>
		if (lines[i] == '') { continue };
		parts = lines[i].split(/\t/);
		event_date = parts[0].split(/\//);
		event_date = new Date(Date.parse(parts[0]));
		// event_dates[i] = [event_date, parts[1]] // date in [0], description in [1]
		event_dates[i] = [event_date, parts[1], parts[2]] // date in [0], description in [1], tiptext in [2]
		
		if (parts[2] != null) { // ignore blank tooltip directives
			tip_text_found = false;
			for (j=0; j < tip_classes.length; j++) {
				if (tip_classes[j] == parts[2]) {
					tip_text_found = true;
					break;
				}
			}
			if (tip_text_found == false)
				tip_classes.splice(tip_classes.length, 0, parts[2]);
		}
		
	};
	
	event_dates.sort(function(a,b) { return a[0] - b[0]; })
	
	eastern = 300 * 60 * 1000; // eastern timezone offset is 5 hrs
	now = new Date(); // should be able to redefine "now" to be "tomorrow" (i.e., now + 1 day) ??
	tomorrow = new Date();
	tomorrow.setTime(now.getTime() + (3600 * 24 * 1000) + ((now.getTimezoneOffset() * 60 * 100) - eastern) ); // now + 24 hours[in ms] - (this.zone[in ms] - eastern.zone[in ms])
	for (i=0; i < event_dates.length; i++) {
		if ((event_dates[i][0].getMonth() == cal_current_date.getMonth()) && (event_dates[i][0].getFullYear() == cal_current_date.getFullYear())) {
			listing = "";
			if ((0 <= event_dates[i][0].getHours() && event_dates[i][0].getHours() < 10)
					|| (13 <= event_dates[i][0].getHours() && event_dates[i][0].getHours() <= 23))
				listing += '&nbsp;'; // add leading space on single-digit hours (not reliable justification!)
			listing += event_dates[i][0].format('g:i A') + '<br />&nbsp;&nbsp;&nbsp;'; // shelley's suggestion: add a <br>
			// if (now < event_dates[i][0]) {
			if (tomorrow < event_dates[i][0]) {
				// listing += '<a href="visit_form.html?' + event_dates[i][0].format('YmdHi') + escape(event_dates[i][1]) + '">' + event_dates[i][1] + '</a>';
				if (event_dates[i][2] == 'event_full')
					listing += event_dates[i][1];
				else
					listing += '<a href="visit_form.html?' + event_dates[i][0].format('YmdHi') + escape(event_dates[i][1]) + '">' + event_dates[i][1] + '</a>';
			}
			else {
				listing += event_dates[i][1];
				event_dates[i][2] = null; // don't display tooltips on events past
			}
			// update_calendar_cell(event_dates[i][0].getDate(), listing);
			update_calendar_cell(event_dates[i][0].getDate(), listing, event_dates[i][2]);
			// mark this day as having some events
			cal.days[event_dates[i][0].getDate()] = 'duh';
		}
	};
	
	for (i=1; i < cal.days.length; i++) {
		if (cal.days[i] == undefined) {
			// alert("blank day_"+i);
			$("day_"+i).insert({ bottom: '<p style="text-align: center; font-size: 0.8em; color: gray;">No events scheduled</p>' });
		}
	};

	for (i=0; i < tip_classes.length; i++)
		apply_tooltips(tip_classes[i]);

}

// function update_calendar_cell (day_number, content) {
// 	$("day_"+day_number).insert({ bottom: '<li class="event">' + content + '</li>' });
// }

function update_calendar_cell (day_number, content, tiptext) {
	var classname = "event";
	if (tiptext != null)
		classname = classname + " " + tiptext;
	$("day_"+day_number).insert({ bottom: '<li class="' + classname + '">' + content + '</li>' });
}

function apply_tooltips (tipname) {
  $$('li[class~="' + tipname + '"]').each(function(element) {
    	new Tip(element, $(tipname).innerHTML, { style: 'protogrey', width: 'auto' });
	});
}
