
var START_YEAR = 2006;
var END_YEAR = 2008;

var FIRST_VALID_DATE = AddDays(new Date(), 1);

var openCalendar = null;

function Calendar(displayMonth, selectedDate, startYear, endYear, element, associatedInput, nextControl)
{
  this.DisplayMonth = displayMonth;
  this.SelectedDate = selectedDate;
  this.StartYear = startYear;
  this.EndYear = endYear;
  this.Element = element;
  this.AssociatedInput = associatedInput;
  this.NextControl = nextControl;
}

function CreateCalendar(date)
{
  date = date.replace("-", "/").replace("-", "/");
  var selectedDate = new Date(date);
  if ((!selectedDate.getTime) || (!IsValidDate(selectedDate)))
  {
    selectedDate = FIRST_VALID_DATE;
  }
  
  var calendar = new Calendar(new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1), 
  selectedDate, START_YEAR, END_YEAR);
  
  calendar.Element = CreateCalendarElement(calendar);
  
  return calendar;
}

function CreateCalendarElement(calendar)
{  
  var month = document.createElement("div");
  month.className = "calendar";  
  var monthHeader = document.createElement("div");
  monthHeader.className = "calendar-heading";
  monthHeader.appendChild(CreateMonthDropDown(calendar.DisplayMonth.getMonth()));
  monthHeader.appendChild(CreateYearDropDown(calendar.DisplayMonth.getFullYear(),
    calendar.StartYear, calendar.EndYear));
  month.appendChild(monthHeader);
  
  AppendMonthDays(calendar, month);
  
  return month;
}

function AppendMonthDays(calendar, element)
{
  var topClear = document.createElement("div");
  topClear.style.clear = "both";
  element.appendChild(topClear);
  
  AppendDayOfWeek(element);

  var writeDate = calendar.DisplayMonth;
  for (var d=0; d<writeDate.getDay(); d++) 
  {
    var blank = document.createElement("div");
    blank.className = "calendar-blank";
    blank.innerHTML = "&nbsp;";
    element.appendChild(blank);
  }

  while (writeDate.getMonth() == calendar.DisplayMonth.getMonth())
  {
    var day = document.createElement("a");
    day.className = "calendar-day";
    if (IsSameDate(writeDate, calendar.SelectedDate))
    {
      day.className += " calendar-day-selected";
    }
    var dayText = document.createTextNode(writeDate.getDate().toString());
    day.appendChild(dayText);
    if (IsValidDate(writeDate))
    {
      day.href = "javascript:SelectDate(" + writeDate.getTime().toString() + ");";
    }
    else
    {
      day.className = "calendar-day-invalid";
    }
    day.onclick = CancelEventBubble;
    element.appendChild(day);
  
    writeDate = AddDays(writeDate, 1);
  }
  
  for (var d=writeDate.getDay(); d<7; d++) 
  {
    var blank = document.createElement("div");
    blank.className = "calendar-blank";
    blank.innerHTML = "&nbsp;";
    element.appendChild(blank);
  }
  
  var bottomClear = document.createElement("div");
  bottomClear.style.clear = "both";
  element.appendChild(bottomClear);
}

function AppendDayOfWeek(element)
{
  var dayLetters = new Array("S", "M", "T", "W", "T", "F", "S");
  for (var i=0; i<dayLetters.length; i++)
  {
    var day = document.createElement("div");
    day.className = "calendar-day-heading";
    day.appendChild(document.createTextNode(dayLetters[i]));
    element.appendChild(day);
  }
  
  var bottomClear = document.createElement("div");
  bottomClear.style.clear = "both";
  element.appendChild(bottomClear);
}

function UpdateCalendar(calendar)
{
  var i = openCalendar.Element.childNodes.length - 1;
  while (openCalendar.Element.childNodes.length > 1)
  {
    var child = openCalendar.Element.childNodes[i];
    if ((!child.className) || child.className != "calendar-heading")
    {
      openCalendar.Element.removeChild(child);
    }
    
    i = openCalendar.Element.childNodes.length - 1;
  }
   
  AppendMonthDays(openCalendar, openCalendar.Element);
}

function UpdateMonth(e)
{
  if (!e)
  {
    e = window.event ? window.event : window.Event;
  }
  
  if (openCalendar)
  {
    var select = !e.srcElement ? e.target : e.srcElement;
    openCalendar.DisplayMonth = new Date(openCalendar.DisplayMonth.getFullYear(),
      select.selectedIndex, 1);
    UpdateCalendar(openCalendar);
  }
  
  CancelEventBubble(e);
}

function UpdateYear(e)
{
  if (!e)
  {
    e = window.event ? window.event : window.Event;
  }
  
  if (openCalendar)
  {
    var select = !e.srcElement ? e.target : e.srcElement;
    openCalendar.DisplayMonth = new Date(parseInt(select.options[select.selectedIndex].value, 10),
      openCalendar.DisplayMonth.getMonth(), 1);
    UpdateCalendar(openCalendar);
  }
  
  CancelEventBubble(e);
}

function CreateMonthDropDown(selectedMonth)
{
  var select = document.createElement("select");
  
  select.options[0] = new Option("January");
  select.options[1] = new Option("February");
  select.options[2] = new Option("March");
  select.options[3] = new Option("April");
  select.options[4] = new Option("May");
  select.options[5] = new Option("June");
  select.options[6] = new Option("July");
  select.options[7] = new Option("August");
  select.options[8] = new Option("September");
  select.options[9] = new Option("October");
  select.options[10] = new Option("November");
  select.options[11] = new Option("December");
	
  select.options[selectedMonth].selected = true;

  select.onchange = UpdateMonth;
  select.onkeyup = UpdateMonth;
  select.onclick = CancelEventBubble;

  return select;
  
}

function CreateYearDropDown(selectedYear, beginYear, endYear)
{
  var select = document.createElement("select");
  for (var i=beginYear; i<=endYear; i++)
  {
    select.options[select.options.length] = 
      new Option(i.toString(), i.toString());
  }
  
  select.options[(beginYear - selectedYear) * -1].selected = true;

  select.onchange = UpdateYear;
  select.onkeyup = UpdateYear;
  select.onclick = CancelEventBubble;

  return select;
  
}

function ShowCalendar(control)
{
    openCalendar = CreateCalendar(control.value);
    openCalendar.AssociatedInput = control;
    openCalendar.NextControl = FindNextField(control);
    
    var position = GetCalendarPosition(control);
    openCalendar.Element.style.left = position.x.toString() + 'px';
    openCalendar.Element.style.top = position.y.toString() + 'px';
    document.body.appendChild(openCalendar.Element);
    
    if (!window.XMLHttpRequest)
    {
      openCalendar.Element.style.width = (openCalendar.Element.offsetWidth - 14).toString() + "px";
    }
    
    control.onclick = CancelEventBubble;
    
    
    if (openCalendar.NextControl)
    {
      openCalendar.NextControl.onfocus = CloseCalendar;
    }
    
    if (control.className)
    {
      control.className += " calendar-associated";
    }
    else
    {
      control.className = "calendar-associated";
    }
    
    if (document.addEventListener)
	{
		document.addEventListener('click', CloseCalendar, false);
	}
	else
	{
		document.body.attachEvent('onclick', CloseCalendar);
	}
	
}

function FindNextField(element)
{
    var nextControl = element.nextSibling;
    while ((nextControl) && (nextControl.tagName != "SELECT" && nextControl.tagName != "INPUT"))
    {
      nextControl = nextControl.nextSibling;
    }
    
    return nextControl;
}

function CloseCalendar()
{
  if (window.event || window.Event)
  {
    if (document.removeEventListener)
	{
	  document.removeEventListener('click', CloseCalendar, false);
	}
	else
	{
	  document.body.detachEvent('onclick', CloseCalendar);
    }
  }
	
  if (openCalendar)
  {
    openCalendar.AssociatedInput.onclick = null;
    if (openCalendar.NextControl)
    {
      openCalendar.NextControl.onfocus = null;
    }
    
    openCalendar.AssociatedInput.className =
      openCalendar.AssociatedInput.className.replace("calendar-associated", "");
    openCalendar.Element.parentNode.removeChild(openCalendar.Element);
    openCalendar = null;
  }
}

function CancelEventBubble(e)
{
	if (!e)
	{
		e = window.event || window.Event;
	}
	
	if (e.stopPropagation)
	{
		e.stopPropagation();
	}
	else
	{
		e.cancelBubble = true;
	}
}

function GetCalendarPosition(originalElement)
{
	var position = new Object();
	position.x = 0;
	position.y = 0;
	
	var obj = originalElement;
	while (obj.offsetParent != null)
	{
		position.x += obj.offsetLeft;
		position.y += obj.offsetTop;
		obj = obj.offsetParent;
	}
	
	position.x -= 6;
	position.y += originalElement.offsetHeight + 4;
	
	return position;
}

function AddDays(date, numberOfDays)
{
  return new Date(date.getTime() + (numberOfDays * 24 * 60 * 60 * 1024));
}

function GetNextMonth(date)
{
  return AddDays(date, GetDaysInMonth(date));
}

function GetPreviousMonth(date)
{
  return AddDays(date, -1 * GetDaysInMonth(date));
}

function GetDaysInMonth(date)
{
  var testNumber = 30;
  while (date.getMonth() != AddDays(date, testNumber).getMonth())
  {
    testNumber--;
  }
  
  return testNumber + 1;
}

function SelectDate(time)
{
  if (openCalendar)
  {
    openCalendar.SelectedDate = new Date(time);
    openCalendar.AssociatedInput.value = 
        openCalendar.SelectedDate.getFullYear().toString() + "/" +
        (openCalendar.SelectedDate.getMonth() + 1).toString() + "/" +
        openCalendar.SelectedDate.getDate().toString();
    
    if (openCalendar.NextControl)
    {
      openCalendar.NextControl.focus();
      openCalendar.NextControl.select();
    }
  }    
}

function IsSameDate(date1, date2)
{
  return (date1.getFullYear() == date2.getFullYear() && 
    date1.getMonth() == date2.getMonth() && 
    date1.getDate() == date2.getDate());
}

function IsValidDate(date)
{
  return (date.getTime() >= FIRST_VALID_DATE.getTime() || IsSameDate(date, FIRST_VALID_DATE));
}