var Calendar = Class.create();

Calendar.prototype = {
   calendar: null,
   container: null,
   input: null,
   name: null,
   options: null,
   day: null,
   month: null,
   year: null,
   updateCallback: null,
   loaded: null,
   calendarHasChanged: null,

   initialize: function (name, input, container, options)
   {
      this.name = name;
      this.input = $(input);
      this.container = $(container);
      this.options = options;

      this.calendar = new YAHOO.widget.Calendar(this.name, this.container.id, this.options);
      this.calendar.selectEvent.subscribe(this.handleSelect.bind(this), this.calendar, true);
      this.calendar.render();

      this.loaded = false;
      this.calendarHasChanged = false;

      Event.observe(this.input, "focus", this.onfocus.bind(this));
      Event.observe(this.input, "change", this.onchange.bind(this));

      this.reset();
   },

   handleSelect: function (type, parameters, object)
   {
      var dates = parameters[0];
      var date = dates[0];

      // update the date values
      this.updateDate(date);

      // hide the calendar
      this.container.hide();

      if (this.loaded)
      {
         this.calendarHasChanged = true;
      }

      if (!this.loaded)
      {
         this.loaded = true;
      }
   },

   updateCalendar: function () {
      var date;
      var monthAndYear;

      if ($F(this.input)) {
         // update the date values
         this.updateDate();

         // get the value from the date input
         this.calendar.select($F(this.input));
         date = this.calendar.getSelectedDates()[0];
         monthAndYear = (date.getMonth() + 1) + "/" + date.getFullYear();

         // set the calendar view to the earliest selected date
         this.calendar.cfg.setProperty("pagedate", monthAndYear);
         this.calendar.render();
      }
   },

   // updates the date values - takes an optional argument of [yyyy, mm, dd]
   updateDate: function ()
   {
      var date = arguments.length == 1 ? $A(arguments[0]).reverse() : $F(this.input).split('/');
      var dateOrder = arguments.length; // 0 - mm/dd/yyyy, 1 - dd/mm/yyyy
      var month = date[dateOrder], day = date[(1 + dateOrder) % 2], year = date[2];

      if(isNaN(month) || isNaN(day) || isNaN(year))
      {
         this.reset();
      }
      else
      {
         this.day = day;
         this.month = month;
         this.year = year;

         // make sure the selected date is valid
         this.validateDate();

         if (this.options.dayInput && this.options.monthInput && this.options.yearInput)
         {
            $(this.options.dayInput).value = this.day;
            $(this.options.monthInput).value = this.month;
            $(this.options.yearInput).value = this.year;
         }

         this.input.value = this.month + "/" + this.day + "/" + this.year;

         if (this.updateCallback)
         {
            this.updateCallback();
         }
      }
   },

   onfocus: function ()
   {
      this.container.show();
   },

   onchange: function ()
   {
      this.container.hide();
      this.updateCalendar();
   },

   toggle: function ()
   {
      Toggle.display(this.container);
   },

   validateDate: function ()
   {
      var date = new Date(this.year, this.month - 1, this.day);

      this.day = date.getDate();
      this.month = date.getMonth() + 1;
      this.year = date.getYear();

      if (this.year < 1900)
      {
         this.year += 1900;
      }
   },
   
   setUpdateCallback: function (callback)
   {
      this.updateCallback = callback;
   },

   setDate: function (date)
   {
      var year = date.getYear();

      if (year < 1900)
      {
         year += 1900;
      }

      var dateArray = [year, date.getMonth() + 1, date.getDate()];

      this.updateDate(dateArray);
      this.updateCalendar();
      this.calendarHasChanged = false;
   },

   getDate: function ()
   {
      return new Date(this.year, this.month - 1, this.day);
   },

   hasCalendarChanged: function ()
   {
      return this.calendarHasChanged;
   },
   
   reset: function () 
   {
      if (this.options.selected)
      {
         this.input.value = this.options.selected;
         this.updateCalendar();
      }
   }
};
