// The single active calendar. This must be hidden
// before any other calendar is displayed.
var activeCalendar = null;

//
// Add a Calendar popup to the given input field and trigger node.
//

function Calendar(fieldId, triggerId, divId)
{
  this.field = document.getElementById(fieldId);
  this.trigger = document.getElementById(triggerId);
  this.calendarDiv = document.getElementById(divId);
  this.backgroundFrame = document.getElementById(this.backgroundFrameId);
  this.calendarDiv.style.display = "none";

  this.highlightDate = CalendarHighlightDate;
  this.getNextMonth = CalendarGetNextMonth;
  this.getPreviousMonth = CalendarGetPreviousMonth;
  this.getMonthRow = CalendarGetMonthRow;
  this.show = CalendarShow;
  this.hide = CalendarHide;
  this.toggle = CalendarToggle;
  this.visible = false;
  this.getTable = CalendarGetTable;
  this.selectDate = CalendarSelectDate;
  this.setDate = CalendarSetDate;
  
  this.backgroundFrame = document.createElement("iframe");
  this.backgroundFrame.className = "calendarFrame";
  this.calendarDiv.parentNode.insertBefore(this.backgroundFrame, this.calendarDiv);

  this.trigger.calendar = this;
  this.trigger.onclick = function(event) { this.calendar.toggle(event) }; // "calendar" is relative to the trigger

  // These properties are set up the first time the calendar is viewed.
  this.date = undefined;
  this.table = undefined;
  
  var ms = this.field.getAttribute("ms");
  if (ms != null)
    this.setDate(new Date(Number(ms)));
}

function CalendarHideActiveCalendar()
{
  if (activeCalendar != null)
    activeCalendar.hide();
}
addBodyHandler(CalendarHideActiveCalendar);

function CalendarToggle(event)
{
  if (event != undefined)
    event.cancelBubble = true;
  else
    window.event.cancelBubble = true;

  if (this.visible)
    this.hide();
  else
    this.show();
}

function CalendarSetDate(date)
{
  if (this.table != null)
    this.calendarDiv.removeChild(this.table);
  
  this.date = date;
  this.table = this.getTable(this.date);
  this.calendarDiv.appendChild(this.table);
}

function CalendarShow()
{
  CalendarHideActiveCalendar();

  if (this.date === undefined)
    this.setDate(new Date());

  this.visible = true;
  this.calendarDiv.style.display = "block";
  
  var left = this.field.offsetLeft + "px";
  this.calendarDiv.style.left = left;
  this.backgroundFrame.style.left = left;
  
  this.backgroundFrame.style.width = this.calendarDiv.offsetWidth + "px";
  this.backgroundFrame.style.height = this.calendarDiv.offsetHeight + "px";
  this.backgroundFrame.style.display = "block";
  
  activeCalendar = this;
}

function CalendarHide()
{
  this.visible = false;
  this.backgroundFrame.style.display = "none";
  this.calendarDiv.style.display = "none";
  if (this.highlightedCell != null)
  {
    this.highlightedCell.className = this.highlightedCell.savedClassName;
    this.highlightedCell = null;
  }

  if (this == activeCalendar)
    activeCalendar = null;
}

function CalendarSelectDate(event, date)
{
  BrowserCancelBubble(event);
  this.field.value = date.getDate() + "/" + (date.getMonth() + 1) + "/" + date.getFullYear();
  this.hide();
  this.setDate(date);
  if (this.field.onchange)
    this.field.onchange();
}

function CalendarHighlightDate(cell)
{
  if (this.highlightedCell == cell)
    return;
  if (this.highlightedCell != null)
    this.highlightedCell.className = this.highlightedCell.savedClassName;
  cell.className = "date hover";
  this.highlightedCell = cell;
}

function CalendarCompareDates(d1, d2)
{
  if (d1 == d2)
    return true;

  var result = ((d1.getDate() == d2.getDate()) &&
    (d1.getMonth() == d2.getMonth()) &&
    (d1.getYear() == d2.getYear()));
  return result;
}

function CalendarGetTable(date)
{
  var today = new Date();
  var table = document.createElement("table");
  table.className = "calendar";
  var date = new Date(this.date.getTime());
  var tbody = document.createElement("tbody");
  table.appendChild(tbody);

  tbody.appendChild(this.getMonthRow(date));
  tbody.appendChild(CalendarGetDayRow());

  var currentRow = document.createElement("tr");
  currentRow.className = "calendar";

  // Get a new Date object, and set it to the 1st.
  date.setDate(1);

  var month = date.getMonth();
  var day = 1;

  var firstDay = date.getDay();
  while (firstDay > 0)
  {
    currentRow.appendChild(CalendarGetCell(null));
    firstDay--;
  }

  while (date.getMonth() == month)
  {
    var dayCell = CalendarGetCell(date.getDate());
    dayCell.onmouseover = function() { this.calendar.highlightDate(this); };
    
    // See if this calendar matches any date.
    if (CalendarCompareDates(date, this.date))
      dayCell.className = "date selectedDate";
    else if (CalendarCompareDates(date, today))
      dayCell.className = "date today";
    else
      dayCell.className = "date";

    dayCell.savedClassName = dayCell.className;

    dayCell.calendar = this;
    dayCell.date = new Date(date.getTime());
    dayCell.onclick = function(event) { this.calendar.selectDate(event, this.date) };

    currentRow.appendChild(dayCell);
    day++;
    date.setDate(day);

    if (date.getDay() == 0)
    {
      tbody.appendChild(currentRow);
      currentRow = document.createElement("tr");
      currentRow.className = "calendar";
    }
  }

  if (date.getDay() != 0)
    tbody.appendChild(currentRow);

  return table;
}

function CalendarGetPreviousMonth(event)
{
  BrowserCancelBubble(event);
  var month = this.date.getMonth();
  if (month == 0)
  {
    this.date.setFullYear(this.date.getFullYear() - 1);
    this.date.setMonth(11);
  }
  else
    this.date.setMonth(month - 1);

  this.setDate(this.date);
}

function CalendarGetNextMonth(event)
{
  BrowserCancelBubble(event);
  this.date.setMonth(this.date.getMonth() + 1);
  this.setDate(this.date);
}

function CalendarGetCell(text)
{
  var td = document.createElement("td");
  if (text != null)
  {
    var textNode = document.createTextNode(text);
    td.appendChild(textNode)
  }

  return td;
}

function CalendarGetMonthRow(date)
{
  var months = [
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
  ];

  var tr = document.createElement("tr");
  var leftArrow = CalendarGetCell(String.fromCharCode(160, 160, 160, 160, 160));
  tr.appendChild(leftArrow);
  leftArrow.className = "calendarLeft arrow";
  leftArrow.calendar = this;
  leftArrow.onclick = function(event) { this.calendar.getPreviousMonth(event) };

  var td = CalendarGetCell(months[date.getMonth()] + " " + date.getFullYear());
  td.colSpan = 5;
  td.className = "month";
  tr.appendChild(td);

  var rightArrow = CalendarGetCell(String.fromCharCode(160, 160, 160, 160, 160));
  rightArrow.className = "calendarRight arrow";
  rightArrow.calendar = this;
  rightArrow.onclick = function(event) { this.calendar.getNextMonth(event) };
  tr.appendChild(rightArrow);

  return tr;
}

function CalendarGetDayRow()
{
  var tr = document.createElement("tr");
  tr.className = "days";
  var days = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ];
  for (var count = 0; count < 7; count++)
  {
    var td = document.createElement("td");
    td.appendChild(document.createTextNode(days[count]));
    td.className = "day";
    tr.appendChild(td);
  }

  return tr;
}
