//=============================================================================
// Global variables for this file.
//
// gMaxStayLength: the largest number a user can type into the "Other" box on
// the LengthDropDown.
//=============================================================================
var gMaxStayLength = 366;

//=============================================================================
// Function: DateRange_ShowElement
//
// Parameters: xiElt - the html element to show
//=============================================================================
function DateRange_ShowElement(xiElt)
{
  if (xiElt)
  {
    xiElt.style.display = "";
  }
}
  
//=============================================================================
// Function: DateRange_HideElement
//
// Parameters: xiElt - the html element to hide
//=============================================================================
function DateRange_HideElement(xiElt)
{
  if (xiElt)
  {
    xiElt.style.display = "none";
  }
}
  
//=============================================================================
// Function: DateRange_UpdateText
//
//  The main onChange event handler for a DateRange.
//
// Parameters:
//   xiDateRangePtrObj  - an object which provides a handle to the DateRange
//                            control. See DateRange.InitialiseScript()
//=============================================================================
function DateRange_UpdateText(xiDateRangePtrObj)
{
  if (xiDateRangePtrObj == null || typeof(xiDateRangePtrObj) != "object")
  {
    return;
  }

  //===========================================================================
  // Store the current and previous arrival dates in the pointer object for
  // use in DateRange_EndDateFollowStart. (N.B. non-existent fields are null)
  //===========================================================================
  var lArrivalDate = DateRange_GetArrivalDate(xiDateRangePtrObj);
  xiDateRangePtrObj.PreviousArrivalDate = xiDateRangePtrObj.CurrentArrivalDate;
  xiDateRangePtrObj.CurrentArrivalDate  = lArrivalDate;

  //===========================================================================
  // Arrival date text:
  //===========================================================================
  var lStartDayTextElement = xiDateRangePtrObj.getStartDayText();
  if (lStartDayTextElement)
  {
    var lArrivalDateText = lArrivalDate ? DateRange_GetDateText(lArrivalDate, xiDateRangePtrObj.getStartDayFormat()) : false;

    //=========================================================================
    // Show or hide the necessary elements:
    //=========================================================================
    if (lArrivalDate && lArrivalDateText)
    {
      lStartDayTextElement.innerHTML = lArrivalDateText;
      DateRange_ShowElement(lStartDayTextElement);
      DateRange_HideElement(xiDateRangePtrObj.getStartDayErrorText());
    }
    else
    {
      if (lArrivalDate == null) //arrival date is empty
      {
        DateRange_HideElement(lStartDayTextElement);
        DateRange_HideElement(xiDateRangePtrObj.getStartDayErrorText());
      }
      else
      {
        DateRange_HideElement(lStartDayTextElement);
        DateRange_ShowElement(xiDateRangePtrObj.getStartDayErrorText());
      }
    }
  }

  //===========================================================================
  // Store the current and previous departure dates in the pointer object for
  // use in DateRange_EndDateFollowStart. (N.B. non-existent fields are null)
  //===========================================================================
  var lDepartureDate = DateRange_GetDepartureDate(xiDateRangePtrObj);
  xiDateRangePtrObj.PreviousDepartureDate = xiDateRangePtrObj.CurrentDepartureDate;
  xiDateRangePtrObj.CurrentDepartureDate  = lDepartureDate;

  //===========================================================================
  // Departure date text:
  //===========================================================================
  var lEndDayTextElement = xiDateRangePtrObj.getEndDayText();
  if (lEndDayTextElement)
  {
    var lDepartureDateText = lDepartureDate ? DateRange_GetDateText(lDepartureDate, xiDateRangePtrObj.getEndDayFormat()) : false;
    //=========================================================================
    // Show or hide the necessary elements:
    //=========================================================================
    if (lDepartureDate && lDepartureDateText)
    {
      lEndDayTextElement.innerHTML = lDepartureDateText;
      DateRange_ShowElement(lEndDayTextElement);
      DateRange_HideElement(xiDateRangePtrObj.getEndDayErrorText());
    }
    else
    {
      if (lDepartureDate == null) //departure date is empty
      {
        DateRange_HideElement(lEndDayTextElement);
        DateRange_HideElement(xiDateRangePtrObj.getEndDayErrorText());
      }
      else
      {
        DateRange_HideElement(lEndDayTextElement);
        DateRange_ShowElement(xiDateRangePtrObj.getEndDayErrorText());
      }
    }
    
    //===========================================================================
    // The following ugliness is necessary for backwards compatibility with HotelSearch
    // If this is causing problems for you, please rename your html element to
    // something other than "CheckOutDayHeader"
    //===========================================================================
    var lCheckOutDayHeader = GetElementInDocument("CheckOutDayHeader");
    if (lCheckOutDayHeader)
    {
      lCheckOutDayHeader.style.display = 
        (lEndDayTextElement.innerHTML == "" ? "none" : lEndDayTextElement.style.display);
    }
  }    
}

//=============================================================================
// Function: DateRange_EndDateFollowStart
//
//  If we're using two date pickers and they modify the arrival date, 
//  then the departure date should automagically follow it...
//
// Parameters:
//   xiDateRangePtrObj  - an object which provides a handle to the DateRange
//                            control. See DateRange.InitialiseScript()
//=============================================================================
function DateRange_EndDateFollowStart(xiDateRangePtrObj)
{
  if (xiDateRangePtrObj == null || typeof(xiDateRangePtrObj) != "object")
  {
    return;
  }
  if (xiDateRangePtrObj.getStartDatePickerPointerObj() && 
      xiDateRangePtrObj.getEndDatePickerPointerObj())
  {
    //===========================================================================
    // We only make a change if the arrival date's just been changed and the
    // departure date has not.
    // N.B. date comparisons are safest done as integer comparisons using getTime()
    //===========================================================================
    var lArrivalDateJustBeenSet = xiDateRangePtrObj.CurrentArrivalDate 
                              && !xiDateRangePtrObj.PreviousArrivalDate;
                              
    var lArrivalDateJustChanged = xiDateRangePtrObj.PreviousArrivalDate
                               && xiDateRangePtrObj.CurrentArrivalDate
                               && (xiDateRangePtrObj.PreviousArrivalDate.getTime() 
                                    != xiDateRangePtrObj.CurrentArrivalDate.getTime());
                                    
    var lDepartureDateNotSet = !xiDateRangePtrObj.PreviousDepartureDate
                            && !xiDateRangePtrObj.CurrentDepartureDate;
                            
    var lDepartureDateUnchanged = xiDateRangePtrObj.PreviousDepartureDate
                               && xiDateRangePtrObj.CurrentDepartureDate
                               && (xiDateRangePtrObj.PreviousDepartureDate.getTime() 
                                    == xiDateRangePtrObj.CurrentDepartureDate.getTime()); 

    if ((lArrivalDateJustBeenSet || lArrivalDateJustChanged)
     && (lDepartureDateNotSet || lDepartureDateUnchanged))
    {      
      var lNewDepartureDate = false;
 
      if (lDepartureDateNotSet)
      {
        //========================================================================
        // No previous end-date; default to startDate + 1 day
        //========================================================================
        lNewDepartureDate = new Date(xiDateRangePtrObj.CurrentArrivalDate.getTime() 
                                     + 1 * 26 * 60 * 60 * 1000);
      }
      else if (lDepartureDateUnchanged && lArrivalDateJustChanged)
      {
        //========================================================================
        // There was an end-date specified: update it to preserve the stay-length
        //========================================================================
        var lPreviousStayLengthMillis = xiDateRangePtrObj.PreviousDepartureDate.getTime()
          - xiDateRangePtrObj.PreviousArrivalDate.getTime();
        
        if (lPreviousStayLengthMillis <= 0)
        {
          return;
        }
        
        lNewDepartureDate = new Date(xiDateRangePtrObj.CurrentArrivalDate.getTime() 
                                     + lPreviousStayLengthMillis
                                     + 2 * 60 * 60 * 1000);
      }
      //========================================================================
      // If lDepartureDateUnchanged && lArrivalDateJustBeenSet then we do nothing.
      //========================================================================
      
      if (lNewDepartureDate)
      {
        DatePicker_SetSelectedDate(lNewDepartureDate, xiDateRangePtrObj.getEndDatePickerPointerObj());
        DateRange_UpdateText(xiDateRangePtrObj);
      }
    }
  }
}

//=============================================================================
// Function: DateRange_GetArrivalDate
//
// Parameters:
//   xiDateRangePtrObj  - an object which provides a handle to the DateRange
//                            control. See DateRange.InitialiseScript()
//
// Returns: a new Date object, 
//       or false if an error has ocurred,
//       or null if no date is selected
//=============================================================================
function DateRange_GetArrivalDate(xiDateRangePtrObj)
{
  if (xiDateRangePtrObj == null || typeof(xiDateRangePtrObj) != "object")
  {
    return false;
  }
  if (!DatePicker_GetSelectedDate)
  {
    //=========================================================================
    // For some reason the DatePicker javascript isn't visible...
    //=========================================================================
    return false;
  }
  
  return DatePicker_GetSelectedDate(xiDateRangePtrObj.getStartDatePickerPointerObj());
}

//=============================================================================
// Function: DateRange_GetDepartureDate
//
// Parameters:
//   xiDateRangePtrObj  - an object which provides a handle to the DateRange
//                            control. See DateRange.InitialiseScript()
// Returns: a new Date object, 
//       or false if an error has ocurred,
//       or null if no date is selected
//=============================================================================
function DateRange_GetDepartureDate(xiDateRangePtrObj)
{
  if (xiDateRangePtrObj == null || typeof(xiDateRangePtrObj) != "object")
  {
    return false;
  }
  
  if (xiDateRangePtrObj.getLengthDropDown())
  {
    var lStartDate = DateRange_GetArrivalDate(xiDateRangePtrObj);
    var lCountNights = DateRange_GetLengthFromDropdown(xiDateRangePtrObj);

    if (!lStartDate)
    {
      return lCountNights == -1 ? false : lStartDate;
    }
    if (lCountNights == -1)
    {
      return false;
    }

    var lMsInDay        = (1000 * 60 * 60 * 24);
    var lMsInTwoHours   = (1000 * 60 * 60 * 2);
    
    return new Date(lStartDate.getTime() + lMsInDay * lCountNights + lMsInTwoHours);
  }
  else
  {
    return DatePicker_GetSelectedDate(xiDateRangePtrObj.getEndDatePickerPointerObj());
  }
}

//=============================================================================
// Function: DateRange_GetLengthFromDropdown
//
// Parameters:
//   xiDateRangePtrObj  - an object which provides a handle to the DateRange
//                            control. See DateRange.InitialiseScript()
//
// Returns: an integer indicating the length in days, 
//       or -1 if an error has ocurred
//=============================================================================
function DateRange_GetLengthFromDropdown(xiDateRangePtrObj)
{
  var lLengthDropDown = xiDateRangePtrObj.getLengthDropDown();
  var lValue          = -1;

  if (lLengthDropDown != null && lLengthDropDown.value != -1)
  {
    lValue = parseInt(lLengthDropDown.value);
  }
  if (isNaN(lValue))
  {
    return -1;
  }
  else
  {
    return lValue;
  }  
}    

//=============================================================================
// Function: DateRange_GetDateText
//
// Parameters:
//   xiDateRangePtrObj  - an object which provides a handle to the DateRange
//                            control. See DateRange.InitialiseScript()
//=============================================================================
function DateRange_GetDateText(xiDate, xiFormat)
{
  var lRet = xiFormat;

  lRet = lRet.replace("{ddd}", DateRange_DayNames[xiDate.getDay()]);
  lRet = lRet.replace("{d}", xiDate.getDate());
  lRet = lRet.replace("{MMM}", DateRange_MonthNames[xiDate.getMonth()]);
  lRet = lRet.replace("{M}", xiDate.getMonth());
  lRet = lRet.replace("{yyyy}", xiDate.getFullYear());
  lRet = lRet.replace("{yy}", String(xiDate.getFullYear()).substring(2, 4));
    
  return lRet;
}

var gStayLengthLastIndex = 0;

function DateRange_ShowLengthPopUp(xiDateRangePtrObj)
{
  if (xiDateRangePtrObj == null || typeof(xiDateRangePtrObj) != "object")
  {
    return false;
  }
  DateRange_ShowDropDownPopUp(xiDateRangePtrObj.getLengthDropDown(), gStayLengthLastIndex, "Please enter the number of nights:");
}

function DateRange_ShowDropDownPopUp(xiControl, xiLastValue, xiPrompt)
{
  var lDropDown = xiControl;
  if (lDropDown.value == "-1")
  {
    var lValue = prompt(xiPrompt, "");
    if (!isNaN(parseInt(lValue)) && lValue != null && lValue > 0 && lValue < gMaxStayLength && parseInt(lValue) == lValue)
    {
      var lIsNewItem = true;
      for (var i = 0; i < lDropDown.options.length; i++)
      {
        if (lValue == lDropDown.options[i].value)
        {
          lIsNewItem = false;
        }
      }
      if (lIsNewItem)
      {
        var lOther = lDropDown.options[lDropDown.options.length - 1];
        lDropDown.options.length = lDropDown.options.length + 1;
        lDropDown.options[lDropDown.options.length - 1] = new Option(lOther.text, lOther.value);
        lDropDown.options[lDropDown.options.length - 2] = new Option(lValue, lValue);
      }
      for (var i = 0; i < lDropDown.options.length; i++)
      {
        if (lValue == lDropDown.options[i].value)
        {
          lDropDown.selectedIndex = i;
        }
      }
    }
    else
    {
      lDropDown.selectedIndex = xiLastValue;
    }
  } 
  gStayLengthLastIndex = lDropDown.selectedIndex;
}


