/**
 * Bezurk date field selector.
 * Required Prototype (tested with 1.5.0).
 */
var BezurkDateSelector = Class.create();
BezurkDateSelector.prototype = {
  daysOfWeek: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
  months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
  monthsOut: 16,
  showDayOfWeek: true,

  initialize: function(dayElement, monthYearElement, defaultDate, showDayOfWeek) {
    this.dayElement = dayElement;
    this.monthYearElement = monthYearElement;
    this.date = defaultDate;
    this.showDayOfWeek = (showDayOfWeek == null) ? true : showDayOfWeek;

    var today = new Date();
    var dayOptions = this.getDaySelectOptions(this.date.getMonth(), this.date.getFullYear(), this.date.getDate());
    dayOptions.each(function(opt) {
      dayElement.appendChild(opt);
    });

    var monthYearOptions = this.getMonthYearSelectOptions(today, this.monthsOut, this.date.getMonth(), this.date.getFullYear());
    monthYearOptions.each(function(opt) {
      monthYearElement.appendChild(opt);
    });

    // Bind onchange event handler for monthYear element to update the day element.
    Event.observe(monthYearElement, 'change', this.updateDay.bindAsEventListener(this), false);
  },

  getDayOfWeek: function(date) {
    return this.daysOfWeek[date.getDay()];
  },

  getDaySelectOptions: function(month, year, selectedDay) {
    var options = [];

    var endDay = 31;
    for (var day = 1; day <= endDay; day++) {
      var date = new Date();
      date.setFullYear(year, month, day);

      // Check that date is valid by ensuring that JavaScript didn't adjust the date.
      if (date.getDate() != day || date.getMonth() != month || date.getFullYear() != year) {
        break;
      }

      // We build using the DOM because IE doesn't like setting innerHTML on <select>s.
      var option = document.createElement('option');
      var optionText = '';
      if (this.showDayOfWeek) {
        optionText = document.createTextNode(day + ' ' + this.getDayOfWeek(date));
      } else {
          optionText = document.createTextNode(day);
      }
      option.appendChild(optionText);
      option.setAttribute('value', day);
      if (selectedDay && selectedDay == day) {
        option.setAttribute('selected', 'selected');
      }
      options.push(option);
    }
    return options;
  }, // getDaySelectOptions()

  getMonthYearSelectOptions: function(startDate, monthsOut, selectedMonth, selectedYear) {
    var options = [];
    var startMonth = startDate.getMonth();
    var startYear = startDate.getFullYear();

    for (var i = 0; i < monthsOut; i++) {
      var month = (startMonth + i) % 12;
      var year = startYear + ((startMonth + i)/12 | 0);
      var canonicalMonth = this.months[month];

      var option = document.createElement('option');
      var optionText = document.createTextNode(canonicalMonth + ' ' + (''+year).substring(2,4))
      option.appendChild(optionText);
      option.setAttribute('value', month  + ',' + year);
      if (!((typeof(selectedMonth)=='undefined') || (typeof(selectedYear)=='undefined'))) {
        if (selectedMonth == month && selectedYear == year) {
          option.setAttribute('selected', 'selected');
        }
      }
      options.push(option);
    }

    return options;
  }, // getMonthYearSelectOptions()

  updateDay: function() {
    var month = this.monthYearElement.value.split(',')[0];
    var year = this.monthYearElement.value.split(',')[1];
    var previousDay = this.dayElement.value;

    // Clear out and re-populate the day field.
    this.dayElement.innerHTML = '';
    var dayOptions = this.getDaySelectOptions(month, year);
    dayOptions.each(function(opt) {
      this.dayElement.appendChild(opt);
    }.bindAsEventListener(this));
    this.dayElement.value = previousDay;
  } // updateDay()
}; // BezurkDateSelector.prototype
