/*********************************************************
 *	File:		  staycalendar.js
 *	Author:		MetaDesign
 *	Created:	March 7, 2007
 *
 *	Description:
 *	Javascript class for hotel stay calendar control
 ********************************************************/

/*--------------------------------------------------------------
 * Class: StayCalendar
 *
 * Javascript class for managing a hotel calendar for arrivals
 * and departures.
 *------------------------------------------------------------*/
var StayCalendar = Class.create();
StayCalendar.prototype = {

  /*--------------------------------------------------------------
   * Method: initialize
   *
   * Establishes the arrival and departure calendar objects,
   * minimum and maximum dates.  Assigns event handlers for the
   * calendars.
   *
   * Parameters:
   * pArrivalCalendar     object    The arrival calendar object
   * pDepartureCalendar   object    The departure calendar object
   * pMinDateStr          string    String representation of minimum date
   * pMaxDateStr          string    String representation of maximum date
   * pMinStay             int       Integer representing the minimum stay duration
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  initialize: function(pArrivalCalendar, pDepartureCalendar, pMinDateStr, pMaxDateStr, pMinStay) {
    if (!pArrivalCalendar.valid || ! pDepartureCalendar.valid) {
      this.valid = false;
      return;
    }
    
    this.valid = true;
      
    // Save the calendars
    this.arrivalCalendar = pArrivalCalendar;
    this.departureCalendar = pDepartureCalendar;

    // Attach event handlers
    this.arrivalCalendar.ondatechange = this.arrivalDateChangeHandler.bind(this);
    this.departureCalendar.ondatechange = this.departureDateChangeHandler.bind(this);
    
    // Save the dates for the calendars
    this.arrivalDate = this.arrivalCalendar.date;
    this.departureDate = this.departureCalendar.date;

    // Set the minimum and maximum dates.
    this.minDate = new Date(pMinDateStr);
    this.maxDate = new Date(pMaxDateStr);
    
    // Set the minimum stay duration
    this.minStay = pMinStay;
  },
  
  /*--------------------------------------------------------------
   * Method: getElement
   *
   * Returns a reference to the DOM element containing the
   * StayCalendar.
   *
   * Parameters:
   * None
   *
   * Return:
   * object   The DOM element containing the calendar
   *------------------------------------------------------------*/
  getElement: function() {
    return this.arrivalCalendar.getElement().parentNode;
  },
  
  /*--------------------------------------------------------------
   * Method: setArrivalDate
   *
   * Sets the arrival date to pDate and validates it.
   *
   * Parameters:
   * pDate    date    The date to set
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  setArrivalDate: function(pDate) {
    this.arrivalDate = pDate;
    this.validateArrivalDate();
  },
  
  /*--------------------------------------------------------------
   * Method: setDepartureDate
   *
   * Sets the departure date to pDate and validates it.
   *
   * Parameters:
   * pDate    date    The date to set
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  setDepartureDate: function(pDate){
    this.departureDate = pDate;
    this.validateDepartureDate();
  },
  
  /*--------------------------------------------------------------
   * Method: validateArrivalDate
   *
   * Validates the arrival date.
   *
   * Parameters:
   * None
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  validateArrivalDate: function() {
    // Make sure we arrive on or after the minimum date
    if (this.arrivalDate - this.minDate < 0) {
      this.arrivalDate = this.minDate;
      this.arrivalCalendar.setDate(this.arrivalDate);
    }
    
    // Make sure we arrive before the maximum date
    var latestArrivalDate = this.maxDate.getPrevDate();
    if (latestArrivalDate - this.arrivalDate < 0) {
      this.arrivalDate = latestArrivalDate;
      this.arrivalCalendar.setDate(this.arrivalDate);
    }
    
    // Make sure departure date is after arrival date
    // 20070717: Set departure date = arrival date + 1
    //if (this.departureDate - this.arrivalDate <= 0) {
      if (this.minStay == 0) {
        this.departureDate = this.arrivalDate;
        this.departureCalendar.setDate(this.departureDate);
      } else {
        var currDate = this.arrivalDate;
        for (var i=0; i<this.minStay; i++) {
          currDate = currDate.getNextDate();
        }
        //this.departureDate = this.arrivalDate.getNextDate();
        this.departureDate = currDate;
        this.departureCalendar.setDate(this.departureDate);
      }
    //}
  },
  
  /*--------------------------------------------------------------
   * Method: validateDepartureDate
   *
   * Validates the departure date.
   *
   * Parameters:
   * None
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  validateDepartureDate: function() {
    // Make sure we depart after the minimum date
    var earliestDepartureDate = this.minDate.getNextDate();
    if (this.departureDate - earliestDepartureDate < 0) {
      this.departureDate = earliestDepartureDate;
      this.departureCalendar.setDate(this.departureDate);
    }
    
    // Make sure we depart on or before the maximum date
    if (this.maxDate - this.departureDate < 0) {
      this.departureDate = this.maxDate;
      this.departureCalendar.setDate(this.departureDate);
    }
    
    // Make sure departure date is after arrival date
    if (this.departureDate - this.arrivalDate <= 0) {
      if (this.minStay == 0) {
        this.arrivalDate = this.departureDate;
        this.arrivalCalendar.setDate(this.arrivalDate);
      } else {
        var currDate = this.departureDate;
        for (var i=0; i<this.minStay; i++) {
          currDate = currDate.getPrevDate();
        }
        //this.arrivalDate = this.departureDate.getPrevDate();
        this.arrivalDate = currDate;
        this.arrivalCalendar.setDate(this.arrivalDate);
      }
    }
  },
  
  /*--------------------------------------------------------------
   * Method: arrivalDateChangeHandler
   *
   * Event handler for a change in the arrival date.
   *
   * Parameters:
   * pEvt                 event     The ondatechange event
   * pArrivalCalendar     object    The arrival calendar object
   * pArrivalDate         date      The new arrival date
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  arrivalDateChangeHandler: function(pEvt, pArrivalCalendar, pArrivalDate) {
    // Set the arrival date and validate it
    this.arrivalDate = pArrivalDate;
    this.validateArrivalDate();
    
    // Propagate the event
    if (this.onarrivaldatechange) {
      this.onarrivaldatechange(pEvt, this, this.arrivalDate, this.departureDate);
    }
  },
  
  /*--------------------------------------------------------------
   * Method: departureDateChangeHandler
   *
   * Event handler for a change in the departure date.
   *
   * Parameters:
   * pEvt                 event     The ondatechange event
   * pDepartureCalendar   object    The departure calendar object
   * pDepartureDate       date      The new departure date
   *
   * Return:
   * None
   *------------------------------------------------------------*/
  departureDateChangeHandler: function(pEvt, pDepartureCalendar, pDepartureDate) {
    // Set the departure date and validate it
    this.departureDate = pDepartureDate;
    this.validateDepartureDate();
    
    // Propagate the event
    if (this.ondeparturedatechange) {
      this.ondeparturedatechange(pEvt, this, this.arrivalDate, this.departureDate);
    }
  }
}