var MS_PER_DAY = 86400000;
var MONTHS = {
  0: "January",
  1: "February",
  2: "March",
  3: "April",
  4: "May",
  5: "June",
  6: "July",
  7: "August",
  8: "September",
  9: "October",
  10: "November",
  11: "December"
}

// Gets the number of the day at the beginning of the month.
//
// This should be passed a month and a year in the form "Aug 1990"
// or "August 1990".
function getStart(month, year) {
  var date = new Date(year, month, 1);
  return date.getDay();
}

// Gets the number of the day at the end of the month. This
// day is almost always in the fifth week of the month, but
// there are some cases when it's the Saturday of the fourth
// week. In those cases, this returns -1. There are also cases
// when it's Sunday or Monday of the sixth week, in which case
// this returns -2 or -3, respectively.
//
// This should be passed a month and a year in the form "Aug 1990"
// or "August 1990".
function getEnd(month, year) {
  var date = new Date(year, month, 28);
  var days_in_month = 28;
  
  // If the month is February and it starts on a Sunday,
  // it's the odd case.
  if (date.getMonth() == 1 && getStart(month, year) == 0) {
    return -1;
  }
  
  while (date.getMonth() == month) {
    days_in_month += 1;
    date.setTime(date.getTime() + MS_PER_DAY);
  }
  
  days_in_month -= 1;
  date.setTime(date.getTime() - MS_PER_DAY);
  var day = date.getDay();
  
  if ((days_in_month == 30 || days_in_month == 31) && day == 0) return -3;
  else if (days_in_month == 31 && day == 1) return -2;
  return day;
}

// Gets the td element corresponding to the given week and day.
function getDayTD(element, week, day) {
  return $$("#" + element.id + " .week" + week + " .day" + day)[0];
}

function getCalendarInfo(day, month, year) {
  var current = calendar[year];
  if (!current) return "";
  current = current[month + 1];
  if (!current) return "";
  current = current[day];
  if (!current) return "";
  return current;
}

// Fills the given element with dates
function fillCalendar(element, month, year) {
  var start = getStart(month, year);
  var end = getEnd(month, year);
  var dayInMonth = 0;
  var weeks = 5;
  
  if (end == -1) {
    weeks = 4;
    end = 6;
  }
  
  if (end == -2 || end == -3) {
    weeks = 6;
    end += 3;
  }
  
  for (var week = 0; week < weeks; week++) {
  
    var startWeek = (week == 0 ? start : 0);
    var endWeek = (week == weeks - 1 ? end + 1 : 7);
    
    for (var day = startWeek; day < endWeek; day++) {
      dayInMonth++;
      var top = document.createElement("p");
      Element.addClassName(top, "top");
      top.appendChild(document.createTextNode(dayInMonth));
      var td = getDayTD(element, week, day);
      var thisWeek = td.parentNode;
      if (!Element.visible(thisWeek))
        Element.show(thisWeek);
      
      while (td.hasChildNodes())
        td.removeChild(td.lastChild)
      td.appendChild(top);
      var info = getCalendarInfo(dayInMonth, month, year);
      
      if (typeof(info) == "string") {
        info = [ info ];
      }
      
      for (var i = 0; i < info.length; i++) {
        var p = document.createElement("p");
        p.innerHTML = info[i];
        td.appendChild(p);
      }
    }
      
    // Adds filler spaces to cells with no content, so IE will display them.
    var emptyCells = [];
    for (var day = 0; day < startWeek; day++)
      emptyCells.push(getDayTD(element, week, day));
    for (var day = endWeek; day < 7; day++)
      emptyCells.push(getDayTD(element, week, day));
    
    for (var i = 0; i < emptyCells.length; i++) {
      var td = emptyCells[i];
      
      while (td.hasChildNodes())
        td.removeChild(td.lastChild);
      
//      if (BrowserDetect.browser == 'Explorer')
        td.innerHTML = "&nbsp;";
    }
  }
  while (weeks < 6) {
    var killWeek = $$("#" + element.id + " .week" + weeks)[0];
    Element.hide(killWeek);
    weeks++;
  }
}

var currentMonth;
var currentYear;
var currentElement;

function setForm() {
  var form = $('calendar_month');
  var children = form.childNodes;
  var monthSelect;
  var yearSelect;
  
  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    if (child.nodeName == "SELECT") {
      if (Element.hasClassName(child, "month"))
        monthSelect = child;
      else if (Element.hasClassName(child, "year"))
        yearSelect = child;
    }
  }
  
  children = monthSelect.childNodes;
  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    if (child.nodeName != "#text" && child.getAttribute('value') == currentMonth.toString())
      child.selected = true;
  }
  
  children = yearSelect.childNodes;
  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    if (child.nodeName != "#text" && child.getAttribute('value') == currentYear.toString())
      child.selected = true;
  }
}

function observeHead(element) {
  var leftRight = $$("#" + element.id + " .head a");
  
  leftRight[0].onclick = function() {
    var newMonth = currentMonth;
    var newYear = currentYear;
    newMonth--;
    if (newMonth < 0) {
      newMonth = 11;
      newYear--;
    }
    
    revCalendar(currentElement, newMonth, newYear);
  };
  
  leftRight[1].onclick = function() {
    var newMonth = currentMonth;
    var newYear = currentYear;
    newMonth++;
    if (newMonth > 11) {
      newMonth = 0;
      newYear++;
    }
    
    revCalendar(currentElement, newMonth, newYear);
  };
  
  var title = $$("#" + element.id + " .head p")[0];
  while (title.hasChildNodes())
    title.removeChild(title.lastChild)
  title.appendChild(document.createTextNode(MONTHS[currentMonth] + " " + currentYear));
}

// Initializes the calendar to the given month.
//
// This should be passed a month and a year in the form "Aug 1990"
// or "August 1990".
function revCalendar(element, month, year) {
  element = $(element);
  currentElement = element;
  currentMonth = month;
  currentYear = year;
  fillCalendar(element, month, year);
  
  observeHead(element);
  setForm();
	// This next statement is here to force Firefox to redraw the footer
	// after the calendar is drawn.  If this is not here, the calendar will overlay
	// the footer.  --Jack Lee
	document.getElementById("footer").style.borderBottom = "1px solid #FFFFFF";
}
