function CruiseEnhancedSearch()
{
  this._model = {};
  this.initialNumberSailings = 0;
  this.numberOfSailingsDiv = 'divNumberOfSailings';
  this.initialCruiseLineId = null;
  this.initialShipId = null;
  this.initialDestinationId = null;

  this.selectedDestinationDiv = 'divSelectedDestination';
  this.unSelectedDestinationHtml = null;

  this.selectedDeparturePortDiv = 'divSelectedDeparturePort';
  this.unSelectedDeparturePortHtml = null;

  this.selectedDateDiv = 'divSelectedDate';
  this.unSelectedDateHtml = null;

  this.selectedDurationDiv = 'divSelectedDuration';
  this.unSelectedDurationHtml = null;

  this.selectedCruiselineDiv = 'divSelectedCruiseline';
  this.unSelectedCruiselineHtml = null;

  this.selectedShipDiv = 'divSelectedShip';
  this.unSelectedShiphtml = null;
}

// static reference to version.
CruiseEnhancedSearch.VERSION = '0.5.0b';

CruiseEnhancedSearch.prototype = {

  /**
   * Initial request to fill our html with initial search results.
   *
   */
  fetchAvailableSailings: function()
  {
    // Get the div that stores the number of sailings found.
    var divNumberOfSailingsEl = YAHOO.util.Dom.get(this.numberOfSailingsDiv);
    if (divNumberOfSailingsEl) {

      // If we have this element set it with the loading html while we send off our request.
      divNumberOfSailingsEl.innerHTML = this.loadingHtml;
    }

    var initialRequestVars = [];
    if (this.initialCruiseLineId) {
      initialRequestVars.push('cruiseline[]=' + encodeURIComponent(this.initialCruiseLineId));
    }

    if (this.initialShipId) {
      initialRequestVars.push('ship[]=' + encodeURIComponent(this.initialShipId));
    }

    if (this.initialDestinationId) {
      initialRequestVars.push('destination[]=' + encodeURIComponent(this.initialDestinationId));
    }

    // Send request to server.
    YAHOO.util.Connect.asyncRequest('GET',
      this.url + ((initialRequestVars.length > 0) ? '?' + initialRequestVars.join('&') : ''),
      {success: this.onServerResponse, error: this.onServerResponse, scope: this}
    );
  },

  /**
   * Handle response to initial request for search results.
   *
   */
  onServerResponse: function(xhttpRequest)
  {
    // Clear loading html since we got a response to our http request.
    var divNumberOfSailingsEl = YAHOO.util.Dom.get(this.numberOfSailingsDiv);
    if (divNumberOfSailingsEl) {
      divNumberOfSailingsEl.innerHTML = '';
    }

    // If request was not successful then exit.
    if (xhttpRequest.status != 200) {
      return;
    }

    // Initialize our model.
    try {
      var response = eval('(' + xhttpRequest.responseText + ')');
      this._model = response;
    }
    catch (ex) {

      /* Probably had some sort of parse error, just throw it along
       * and hope it gets caught.
       */
      throw ex;
    }

    /* if we have a number of sailings element then store this
     * we use it if we have to reset our object without sending another
     * http request.
     */
    if (this._model.numberSailings) {
      this.initialNumberSailings = this._model.numberSailings;
    }

    if (this.initialCruiseLineId && this._model.availableShips) {
      for (i in this._model.availableShips) {
        if (this._model.availableShips[i].id == this.initialCruiseLineId) {

          this._model.availableShips[i].status = 'selected';
        }
      }
    }

    if (this.initialShipId && this._model.availableShips) {
      for (i in this._model.availableShips) {
        for (j in this._model.availableShips[i].ships) {
          if (this._model.availableShips[i].ships[j].id == this.initialShipId) {

            this._model.availableShips[i].ships[j].status = 'selected';
          }
        }
      }
    }

    if (this.initialDestinationId && this._model.availableDestinations) {
      for (i in this._model.availableDestinations) {
        if (this._model.availableDestinations[i].id == this.initialDestinationId) {

          this._model.availableDestinations[i].status = 'selected';
        }
      }
    }

    // Render our model.
    this.renderModel();
  },

  /**
   * Clear all selected search criteria.
   *
   */
  clearSelections: function()
  {
    // Reset number of sailings to what we had originally.
    this._model.numberSailings = this.initialNumberSailings;

    // Reset all destinations in our list to available.
    for (i in this._model.availableDestinations) {
      if (this._model.availableDestinations[i].status) {
        this._model.availableDestinations[i].status = 'available';
      }
    }

    // Reset all ports in our list to available.
    for (i in this._model.availableDeparturePorts) {
      if (this._model.availableDeparturePorts[i].status) {
        this._model.availableDeparturePorts[i].status = 'available';
      }
    }

    // Reset all months to available.
    for (i in this._model.availableMonths) {
      for (j in this._model.availableMonths[i].months) {
        if (this._model.availableMonths[i].months[j].status) {
          this._model.availableMonths[i].months[j].status = 'available';
        }
      }
    }

    // Reset all lengths.
    for (i in this._model.availableLengths) {
      if (this._model.availableLengths[i].status) {
        this._model.availableLengths[i].status = 'available';
      }
    }

    // Reset all cruise lines and ships.
    for (i in this._model.availableShips) {
      if (this._model.availableShips[i].status) {
        this._model.availableShips[i].status = 'available';
      }

      for (j in this._model.availableShips[i].ships) {
        if (this._model.availableShips[i].ships[j].status) {
          this._model.availableShips[i].ships[j].status = 'available';
        }
      }
    }

    if (this.initialCruiseLineId && this._model.availableShips) {
      for (i in this._model.availableShips) {
        if (this._model.availableShips[i].id == this.initialCruiseLineId) {

          this._model.availableShips[i].status = 'selected';
        }
      }
    }

    if (this.initialShipId && this._model.availableShips) {
      for (i in this._model.availableShips) {
        for (j in this._model.availableShips[i].ships) {
          if (this._model.availableShips[i].ships[j].id == this.initialShipId) {

            this._model.availableShips[i].ships[j].status = 'selected';
          }
        }
      }
    }

    if (this.initialCruiseLineId && this._model.availableDestinations) {
      for (i in this._model.availableDestinations) {
        if (this._model.availableDestinations[i].id == this.initialDestinationId) {

          this._model.availableDestinations[i].status = 'selected';
        }
      }
    }

    this.renderModel();
  },

  /**
   *
   * View search results by passing parameters representing the enhanced search's configuration to search page.
   */
  viewResults: function()
  {
    // initialize request variables.
    var requestVars = [];

    // Add all selected destinations to our variables.
    for (i in this._model.availableDestinations) {
      if (this._model.availableDestinations[i].status == 'selected') {
        requestVars.push('destination_list[]=' + encodeURIComponent(this._model.availableDestinations[i].id));
      }
    }

    // Add all selected departure ports to our variables.
    for (i in this._model.availableDeparturePorts) {
      if (this._model.availableDeparturePorts[i].status == 'selected') {
        requestVars.push('portid=' + encodeURIComponent(this._model.availableDeparturePorts[i].id));
      }
    }

    /* Complex logic to determine what our
     * date parameters should be, if no date was selected
     * the default is one year of search.
     */

    // flag to determine if we could create a date range based on date selection.
    var haveDateRange = false;

    // Default start and end date to now.
    var startDate = new Date();
    var endDate   = new Date();

    // Loop over available months to see which one is selected if any.
    for (i in this._model.availableMonths) {
      for (j in this._model.availableMonths[i].months) {

        /* create date using current month in our iteration. Months in javascript
         * are passed to date contructor as its 0-indexed value, hence passing the month
         * unaltered like this is interpreted by the object as next month. Since day is 0
         * this gives me the last day of the current month since 0 day of next month gets corrected
         * to last day of current month.
         */
        var dd = new Date(this._model.availableMonths[i].year, this._model.availableMonths[i].months[j].month, 0);
        var daysInMonth = dd.getDate();

        // create date to represent start of current month in iteration.
        var startMonth = new Date(this._model.availableMonths[i].year, this._model.availableMonths[i].months[j].month - 1, 1);
        if (startMonth < startDate) {

          // If start of this month is before start date then set new start date.
          startDate = startMonth;
        }

        // create date to represent end of current month in iteration.
        var endMonth = new Date(this._model.availableMonths[i].year, this._model.availableMonths[i].months[j].month - 1, 1);
        if (endMonth > endDate) {

          // if end of month is creater than end date then set en date to end of moneth.
          endDate = endMonth;
        }

        // If month is selected.
        if (this._model.availableMonths[i].months[j].status == 'selected') {

          // Set parameters to search this month.
          requestVars.push('cruise_year=' + encodeURIComponent(this._model.availableMonths[i].year));
          requestVars.push('cruise_month=' + encodeURIComponent(this._model.availableMonths[i].months[j].month));
          requestVars.push('cruise_day=1');
          requestVars.push('cruise_year2=' + encodeURIComponent(this._model.availableMonths[i].year));
          requestVars.push('cruise_month2=' + encodeURIComponent(this._model.availableMonths[i].months[j].month));
          requestVars.push('cruise_day2=' + daysInMonth);

          // Set flag to indicate that we have a date range and break out of loop
          haveDateRange = true;
          break;
        }
      }
    }

    /* If we do not have a date range, which means we have no selected months
     * then create date parameters which should encompass the entire search result set
     * represented by the enhanced search object.
     */
    if (!haveDateRange) {
      requestVars.push('cruise_year=' + startDate.getFullYear());
      requestVars.push('cruise_month=' + (startDate.getMonth() + 1));
      requestVars.push('cruise_day=' + startDate.getDate());
      requestVars.push('cruise_year2=' + endDate.getFullYear());
      requestVars.push('cruise_month2=' + (endDate.getMonth() + 1));
      requestVars.push('cruise_day2=' + (endDate.getDate()));
    }

    // Add selected lengths.
    for (i in this._model.availableLengths) {
      if (this._model.availableLengths[i].status == 'selected') {
        requestVars.push('cruise_duration=' + encodeURIComponent(this._model.availableLengths[i].range));
        break;
      }
    }

    // Add selected cruise line and/or ship.
    for (i in this._model.availableShips) {
      if (this._model.availableShips[i].status == 'selected') {
        requestVars.push('VendorID[]=' + encodeURIComponent(this._model.availableShips[i].id));
      }

      for (j in this._model.availableShips[i].ships) {
        if (this._model.availableShips[i].ships[j].status == 'selected') {
          requestVars.push('ship_list[]=' + encodeURIComponent(this._model.availableShips[i].ships[j].id));
        }
      }
    }

    if (window.loadSplash) {

      // if there is a splash, then show it before redirecting.
      window.loadSplash();
    }

    // Redirect to search page..  Only include the WebsiteSelection if provided
    if (document.getElementById('WebsiteSelection')){
      document.location.href = this.resultsUrl + '?' + requestVars.join('&') + '&' +'WebsiteSelection='+ document.getElementById('WebsiteSelection').value;
    }
    else {
      document.location.href = this.resultsUrl + '?' + requestVars.join('&');
    }
  },

  /**
   * Based on search selections update items in model to reflect their new statuses
   *
   */
  fetchUpdate: function ()
  {
    var requestVars = [];

    for (i in this._model.availableDestinations) {
      if (this._model.availableDestinations[i].status == 'selected') {
        requestVars.push('destination[]=' + encodeURIComponent(this._model.availableDestinations[i].id));
      }
    }

    for (i in this._model.availableDeparturePorts) {
      if (this._model.availableDeparturePorts[i].status == 'selected') {
        requestVars.push('departure_port=' + encodeURIComponent(this._model.availableDeparturePorts[i].id));
        break;
      }
    }

    for (i in this._model.availableMonths) {
      for (j in this._model.availableMonths[i].months) {
        if (this._model.availableMonths[i].months[j].status == 'selected') {
          requestVars.push('year=' + encodeURIComponent(this._model.availableMonths[i].year));
          requestVars.push('month=' + encodeURIComponent(this._model.availableMonths[i].months[j].month));
          break;
        }
      }
    }

    for (i in this._model.availableLengths) {
      if (this._model.availableLengths[i].status == 'selected') {
        var range = this._model.availableLengths[i].range.split('-');
        requestVars.push('minLength=' + encodeURIComponent(range[0]));
        requestVars.push('maxLength=' + encodeURIComponent(range[1]));
        break;
      }
    }

    for (i in this._model.availableShips) {
      if (this._model.availableShips[i].status == 'selected') {
        requestVars.push('cruiseline[]=' + encodeURIComponent(this._model.availableShips[i].id));
      }

      for (j in this._model.availableShips[i].ships) {
        if (this._model.availableShips[i].ships[j].status == 'selected') {
          requestVars.push('ship[]=' + encodeURIComponent(this._model.availableShips[i].ships[j].id));
        }
      }
    }

    // Setup request and send.
    var divNumberOfSailingsEl = YAHOO.util.Dom.get(this.numberOfSailingsDiv);
    if (divNumberOfSailingsEl) {
      divNumberOfSailingsEl.innerHTML = this.loadingHtml;
    }

    YAHOO.util.Connect.asyncRequest('GET', this.url + '?' + requestVars.join('&'), {success: this.onUpdateResponse, error: this.onUpdateResponse, scope: this});
  },

  /**
   *
   * Triggers on response from request to get update.
   */
  onUpdateResponse: function(xhttpRequest)
  {
    // Clear loading html since we got a response to our http request.
    var divNumberOfSailingsEl = YAHOO.util.Dom.get(this.numberOfSailingsDiv);
    if (divNumberOfSailingsEl) {
      divNumberOfSailingsEl.innerHTML = '';
    }

    // If request was not successful then exit.
    if (xhttpRequest.status != 200) {
      return;
    }

    // Initialize our model.
    try {
      var response = eval('(' + xhttpRequest.responseText + ')');
    }
    catch (ex) {

      /* Probably had some sort of parse error, just throw it along
       * and hope it gets caught.
       */
      throw ex;
    }

    // Update the number of available sailings.
    if (this._model.numberSailings && response.numberSailings) {
      this._model.numberSailings = response.numberSailings;
    }

    if (this._model.availableDestinations) {
      for (i in this._model.availableDestinations) {
        // Assume anything that is not selected is unavailable.
        if (this._model.availableDestinations[i].status != 'selected') {
          this._model.availableDestinations[i].status = 'unavailable';
        }

        var destination = this._model.availableDestinations[i];

        if (response.availableDestinations) {
          for (j in response.availableDestinations) {
            var destinationResponse = response.availableDestinations[j];

            /* For each destination we got in the response, the corresponding item in our model is not selected
             * then change it to available.
             */
            if (destinationResponse.id == destination.id && destination.status != 'selected') {
              this._model.availableDestinations[i].status = 'available';
            }
          }
        }
      }
    }

    if (this._model.availableDeparturePorts) {
      for (i in this._model.availableDeparturePorts) {
        // Assume anything that is not selected is unavailable.
        if (this._model.availableDeparturePorts[i].status != 'selected') {
          this._model.availableDeparturePorts[i].status = 'unavailable';
        }

        var departurePort = this._model.availableDeparturePorts[i];

        if (response.availableDeparturePorts) {
          for (j in response.availableDeparturePorts) {
            var departurePortResponse = response.availableDeparturePorts[j];

            /* For each departure port we got in the response, the corresponding item in our model is not selected
             * then change it to available.
             */
            if (departurePortResponse.id == departurePort.id && departurePort.status != 'selected') {
              this._model.availableDeparturePorts[i].status = 'available';
            }
          }
        }
      }
    }

    if (this._model.availableMonths) {
      var unAvailableMonths = [];

      for (i in this._model.availableMonths) {
        for (j in this._model.availableMonths[i].months) {
          if (this._model.availableMonths[i].months[j].status != 'selected') {

            // Add this month to a list of unselected months.
            var tmp = [this._model.availableMonths[i].year, this._model.availableMonths[i].months[j].month, i, j];
            unAvailableMonths.push(tmp);
            this._model.availableMonths[i].months[j].status = 'unavailable';
          }
        }
      }

      if (response.availableMonths) {
        for (k in response.availableMonths) {

          // For every year we got in our response, we need to update the months in our model.
          var yearObjResponse = response.availableMonths[k];
          for (l in response.availableMonths[k].months) {
            var monthObjResponse = response.availableMonths[k].months[l];
            for (m in unAvailableMonths) {

              // For all the months that we marked unavailable, if we have a month in our response
              // mark it as available.
              if (unAvailableMonths[m][0] == yearObjResponse.year && unAvailableMonths[m][1] == monthObjResponse.month) {
                this._model.availableMonths[unAvailableMonths[m][2]].months[unAvailableMonths[m][3]].status = 'available';
              }
            }
          }
        }
      }
    }

    if (this._model.availableLengths) {

      // For all the lengths in our model that are not selected should be marked unavailable.
      for (i in this._model.availableLengths) {
        if (this._model.availableLengths[i].status != 'selected') {
          this._model.availableLengths[i].status = 'unavailable';
        }

        var length = this._model.availableLengths[i];

        if (response.availableLengths) {

          // For the lengths we have in our response, mark as available if not selected.
          for (j in response.availableLengths) {
            var lengthObjResponse = response.availableLengths[j];
            if (lengthObjResponse.range == length.range && length.status != 'selected') {
              this._model.availableLengths[i].status = 'available';
            }
          }
        }
      }
    }

    if (this._model.availableShips) {
      var unAvailableVendors = [];
      var unAvailableShips = [];

      for (i in this._model.availableShips) {
        if (this._model.availableShips[i].ships && this._model.availableShips[i].ships.length) {

          // For all the vendors in our model who have ships and not selected mark as unavailable.
          if (this._model.availableShips[i].status != 'selected') {
            var tmp = [this._model.availableShips[i].id, i];
            unAvailableVendors.push(tmp);
            this._model.availableShips[i].status = 'unavailable';
          }

          for (j in this._model.availableShips[i].ships) {

            // For all the ships that are not selected mark as unavailable.
            if (this._model.availableShips[i].ships[j].status != 'selected') {
              var tmp2 = [this._model.availableShips[i].ships[j].id, i, j];
              unAvailableShips.push(tmp2);
              this._model.availableShips[i].ships[j].status = 'unavailable';
            }
          }
        }
      }


      if (response.availableShips) {
        for (k in response.availableShips) {
          var vendorObjResponse = response.availableShips[k];
          // for all the vendors we have in our response, update their status if not selected to available.
          for (l in unAvailableVendors) {
            if (unAvailableVendors[l][0] == vendorObjResponse.id) {
              this._model.availableShips[unAvailableVendors[l][1]].status = 'available';
            }
          }

          for (m in response.availableShips[k].ships) {
            var shipObjResponse = response.availableShips[k].ships[m];
            for (n in unAvailableShips) {

              // for our unavailable ships if any of them came back in our response then flag available.
              if (unAvailableShips[n][0] == shipObjResponse.id) {
                this._model.availableShips[unAvailableShips[n][1]].ships[unAvailableShips[n][2]].status = 'available';
              }
            }
          }
        }
      }
    }

    this.renderModel();
  },

  /**
   * Fill in all cruise elements based on our current search state.
   */
  renderModel: function ()
  {
    var oThis = this;

    if (this._model.numberSailings) {
      var divNumberOfSailingsEl = YAHOO.util.Dom.get(this.numberOfSailingsDiv);

      if (divNumberOfSailingsEl) {

        // Erase old number of sailings count.
        divNumberOfSailingsEl.innerHTML = '';

        // Display current number of sailings available.
        divNumberOfSailingsEl.appendChild(document.createTextNode(this._model.numberSailings + ' Cruise Options Available'));
      }
    }

    if (this._model.availableDestinations) {
      var divDestinationsEl = YAHOO.util.Dom.get('divDestinations');

      if (divDestinationsEl) {

        // Erase old available destinations.
        divDestinationsEl.innerHTML = '';
        var isDestinationSelected = false;


        for (i in this._model.availableDestinations) {
          if (!this._model.availableDestinations[i].status) {

            // All items need a status, if no status assume it is available.
            this._model.availableDestinations[i].status = 'available';
          }

          var destination = this._model.availableDestinations[i];

          if (destination.status == 'unavailable') {

            // filter out unavailable destinations.
            continue;
          }

          // Create div for destination element.
          var divDestinationEl = document.createElement('div');
          divDestinationsEl.appendChild(divDestinationEl);

          // Set Name in div el.
          divDestinationEl.appendChild(document.createTextNode(destination.name));

          divDestinationEl.id = 'destination_' + destination.id;
          divDestinationEl.className = 'enhanced_search_content';
          if (destination.status == 'available') {
            divDestinationEl.className += ' enhanced_search_options';
          }
          else if (destination.status == 'selected') {
            divDestinationEl.className += ' enhanced_search_selected';

            isDestinationSelected = true;

            // See if we have a destination label that we have to update with the selected destination.
            var divSelectedDestinationEl = YAHOO.util.Dom.get(this.selectedDestinationDiv);
            if (divSelectedDestinationEl) {

              if (null == this.unSelectedDestinationHtml) {

                // Save the html in the destination label.
                this.unSelectedDestinationHtml = divSelectedDestinationEl.innerHTML;
              }

              // Update the destination label with the selected destination.
              divSelectedDestinationEl.innerHTML = destination.name;
            }
          }
          else {
            divDestinationEl.className += ' enhanced_search_eliminated';
          }

          divDestinationEl.onclick = function() {
            var destinationId = (this.id.split('_')[1]);
            for (i in oThis._model.availableDestinations) {
              if (oThis._model.availableDestinations[i].id == destinationId) {
                if (oThis._model.availableDestinations[i].status == 'available') {
                  // Clear all other available destinations.
                  for (m in oThis._model.availableDestinations) {
                    if (oThis._model.availableDestinations[m].status == 'selected') {
                      oThis._model.availableDestinations[m].status = 'available';
                    }
                  }

                  // If available and clicked then status becomes selected.
                  oThis._model.availableDestinations[i].status = 'selected';
                  oThis.fetchUpdate();
                }
                else if (oThis._model.availableDestinations[i].status == 'selected') {

                  // If selected and clicked then status becomes available.
                  oThis._model.availableDestinations[i].status = 'available';
                  oThis.fetchUpdate();
                }
              }
            }
          }
        }

        // Get destination label.
        var divSelectedDestinationEl = YAHOO.util.Dom.get(this.selectedDestinationDiv);

        /* if no destination is selected and we have a destination label and we have
         * html stored to show when nothing is selected then but that into the destination label.
         */
        if (!isDestinationSelected && divSelectedDestinationEl && null != this.unSelectedDestinationHtml) {

          divSelectedDestinationEl.innerHTML = this.unSelectedDestinationHtml;
        }
      }
    }

    if (this._model.availableDeparturePorts) {
      var divDeparturePortsEl = YAHOO.util.Dom.get('divDeparturePorts');

      if (divDeparturePortsEl) {

        // Erase old available destinations.
        divDeparturePortsEl.innerHTML = '';
        var isDeparturePortSelected = false;

        for (i in this._model.availableDeparturePorts) {
          if (!this._model.availableDeparturePorts[i].status) {

            // All items need a status, if no status assume it is available.
            this._model.availableDeparturePorts[i].status = 'available';
          }

          var departurePort = this._model.availableDeparturePorts[i];

          if (departurePort.status == 'unavailable') {

            // filter out unavailable destinations.
            continue;
          }

          // Create div for destination element.
          var divDeparturePortEl = document.createElement('div');
          divDeparturePortsEl.appendChild(divDeparturePortEl);

          // Set Name in div el.
          divDeparturePortEl.appendChild(document.createTextNode(departurePort.name));

          divDeparturePortEl.id = 'departurePort_' + departurePort.id;
          divDeparturePortEl.className = 'enhanced_search_content';
          if (departurePort.status == 'available') {
            divDeparturePortEl.className += ' enhanced_search_options';
          }
          else if (departurePort.status == 'selected') {
            divDeparturePortEl.className += ' enhanced_search_selected';

            isDeparturePortSelected = true;

            // See if we have a destination label that we have to update with the selected destination.
            var divSelectedDeparturePortEl = YAHOO.util.Dom.get(this.selectedDeparturePortDiv);
            if (divSelectedDeparturePortEl) {

              if (null == this.unSelectedDeparturePortHtml) {

                // Save the html in the label.
                this.unSelectedDeparturePortHtml = divSelectedDeparturePortEl.innerHTML;
              }

              // Update the label with the selected item.
              divSelectedDeparturePortEl.innerHTML = departurePort.name;
            }
          }
          else {
            divDeparturePortEl.className += ' enhanced_search_eliminated';
          }

          divDeparturePortEl.onclick = function() {
            var departurePortId = (this.id.split('_')[1]);
            for (i in oThis._model.availableDeparturePorts) {
              if (oThis._model.availableDeparturePorts[i].id == departurePortId) {
                if (oThis._model.availableDeparturePorts[i].status == 'available') {
                  // Clear all other available departure ports.
                  for (m in oThis._model.availableDeparturePorts) {
                    if (oThis._model.availableDeparturePorts[m].status == 'selected') {
                      oThis._model.availableDeparturePorts[m].status = 'available';
                    }
                  }

                  // If available and clicked then status becomes selected.
                  oThis._model.availableDeparturePorts[i].status = 'selected';
                  oThis.fetchUpdate();
                }
                else if (oThis._model.availableDeparturePorts[i].status == 'selected') {

                  // If selected and clicked then status becomes available.
                  oThis._model.availableDeparturePorts[i].status = 'available';
                  oThis.fetchUpdate();
                }

                break;
              }
            }
          }
        }

        // Get departure port label.
        var divSelectedDeparturePortEl = YAHOO.util.Dom.get(this.selectedDeparturePortDiv);

        /* if no item is selected and we have a label and we have
         * html stored to show when nothing is selected then but that into the label.
         */
        if (!isDeparturePortSelected && divSelectedDeparturePortEl && null != this.unSelectedDeparturePortHtml) {

          divSelectedDeparturePortEl.innerHTML = this.unSelectedDeparturePortHtml;
        }
      }
    }

    /*
    <div class="enhanced_search_content"><b>2007</b></div>
    <div class="enhanced_search_month">OCT</div>
    <div class="enhanced_search_month">NOV</div>
    <div class="enhanced_search_month">DEC</div>
    <br>
    <br>*/
    if (this._model.availableMonths) {
      var divMonthsEl = YAHOO.util.Dom.get('divMonths');

      // Make sure we have a div to host our month content.
      if (divMonthsEl) {
        divMonthsEl.innerHTML = '';

        var isDateSelected = false;

        for (i in this._model.availableMonths) {

          // months are grouped by year
          var yearObj = this._model.availableMonths[i];
          if (yearObj.months && yearObj.months.length) {

            // If the year has months, then create a div element for it.
            var divYearEl = document.createElement('div');
            divYearEl.className = "enhanced_search_content";
            divYearEl.innerHTML = yearObj.year;
            divMonthsEl.appendChild(divYearEl);

            for (j in yearObj.months) {
              if (!this._model.availableMonths[i].months[j].status) {

                // All items need a status, if no status assume it is available.
                this._model.availableMonths[i].months[j].status = 'available';
              }

              var monthObj = yearObj.months[j];

              // Create div elements for all the months of the particular year.
              var divMonthEl = document.createElement('div');
              divMonthsEl.appendChild(divMonthEl);
              divMonthEl.innerHTML = monthObj.name;

              divMonthEl.id = 'month_' + yearObj.year + '_' + monthObj.month;
              divMonthEl.className = 'enhanced_search_month';
              if (monthObj.status == 'available') {
                divMonthEl.className += ' enhanced_search_options';
              }
              else if (monthObj.status == 'selected') {
                divMonthEl.className += ' enhanced_search_selected';

                isDateSelected = true;

                // See if we have a destination label that we have to update with the selected destination.
                var divSelectedDateEl = YAHOO.util.Dom.get(this.selectedDateDiv);
                if (divSelectedDateEl) {

                  if (null == this.unSelectedDateHtml) {

                    // Save the html in the label.
                    this.unSelectedDateHtml = divSelectedDateEl.innerHTML;
                  }

                  // Update the label with the selected item.
                  divSelectedDateEl.innerHTML = monthObj.name + ' ' + yearObj.year;
                }
              }
              else {
                divMonthEl.className += ' enhanced_search_eliminated';
              }

              divMonthEl.onclick = function() {
                var yearId = (this.id.split('_')[1]);
                var monthId = (this.id.split('_')[2]);

                for (i in oThis._model.availableMonths) {
                  for (j in oThis._model.availableMonths[i].months) {
                    if (oThis._model.availableMonths[i] &&
                        oThis._model.availableMonths[i].year == yearId &&
                        oThis._model.availableMonths[i].months[j].month == monthId) {
                      if (oThis._model.availableMonths[i].months[j].status == 'available') {

                        // If available and clicked then status becomes selected.
                        oThis._model.availableMonths[i].months[j].status = 'selected';
                        oThis.fetchUpdate();
                      }
                      else if (oThis._model.availableMonths[i].months[j].status == 'selected') {

                        // If selected and clicked then status becomes available.
                        oThis._model.availableMonths[i].months[j].status = 'available';
                        oThis.fetchUpdate();
                      }
                    }
                  }
                }
              }
            }

            // Add two line breaks at the end for structure.
            divMonthsEl.appendChild(document.createElement('br'));
            divMonthsEl.appendChild(document.createElement('br'));
          }
        }

        // Get departure port label.
        var divSelectedDateEl = YAHOO.util.Dom.get(this.selectedDateDiv);

        /* if no item is selected and we have a label and we have
         * html stored to show when nothing is selected then but that into the label.
         */
        if (!isDateSelected && divSelectedDateEl && null != this.unSelectedDateHtml) {

          divSelectedDateEl.innerHTML = this.unSelectedDateHtml;
        }
      }
    }

    if (this._model.availableLengths) {
      var divLengthsEl = YAHOO.util.Dom.get('divLengths');
      if (divLengthsEl) {
        divLengthsEl.innerHTML = '';
        var isDurationSelected = false;

        for (i in this._model.availableLengths) {
          if (!this._model.availableLengths[i].status) {

            // All items need a status, if no status assume it is available.
            this._model.availableLengths[i].status = 'available';
          }

          var lengthObj = this._model.availableLengths[i];

          // Create div element for the range.
          // <div class="enhanced_search_content">1 - 3 Days</div>
          var divLengthEl = document.createElement('div');
          divLengthsEl.appendChild(divLengthEl);

          divLengthEl.innerHTML = lengthObj.description;
          divLengthEl.id = 'length_' + lengthObj.range;
          divLengthEl.className = 'enhanced_search_content';

          if (lengthObj.status == 'available') {
            divLengthEl.className += ' enhanced_search_options';
          }
          else if (lengthObj.status == 'selected') {
            divLengthEl.className += ' enhanced_search_selected';

            isDurationSelected = true;

            // See if we have a destination label that we have to update with the selected destination.
            var divSelectedDurationEl = YAHOO.util.Dom.get(this.selectedDurationDiv);
            if (divSelectedDurationEl) {

              if (null == this.unSelectedDurationHtml) {

                // Save the html in the label.
                this.unSelectedDurationHtml = divSelectedDurationEl.innerHTML;
              }

              // Update the label with the selected item.
              divSelectedDurationEl.innerHTML = lengthObj.description;
            }
          }
          else {
            divLengthEl.className += ' enhanced_search_eliminated';
          }

          divLengthEl.onclick = function() {
            var rangeId = (this.id.split('_')[1]);

            for (i in oThis._model.availableLengths) {
              if (oThis._model.availableLengths[i].range == rangeId) {
                if (oThis._model.availableLengths[i].status == 'available') {

                  // If available and clicked then status becomes selected.
                  oThis._model.availableLengths[i].status = 'selected';
                  oThis.fetchUpdate();
                }
                else if (oThis._model.availableLengths[i].status == 'selected') {

                  // If selected and clicked then status becomes available.
                  oThis._model.availableLengths[i].status = 'available';
                  oThis.fetchUpdate();
                }
              }
            }
          }
        }

         // Get label.
        var divSelectedDurationEl = YAHOO.util.Dom.get(this.selectedDurationDiv);

        /* if no item is selected and we have a label and we have
         * html stored to show when nothing is selected then but that into the label.
         */
        if (!isDurationSelected && divSelectedDurationEl && null != this.unSelectedDurationHtml) {

          divSelectedDurationEl.innerHTML = this.unSelectedDurationHtml;
        }
      }
    }

    if (this._model.availableShips) {
      var divVendorsEl = YAHOO.util.Dom.get('divVendors');
      var divShipsEl = YAHOO.util.Dom.get('divShips');

      if (divVendorsEl) {
        divVendorsEl.innerHTML = '';
        var isVendorSelected = false;
      }


      if (divShipsEl) {
        divShipsEl.innerHTML = '';
        var isShipSelected = false;
      }

      var showUnselectedVendorShips = true;
      for (i in this._model.availableShips) {
        if (!this._model.availableShips[i].status) {

          // All items need a status, if no status assume it is available.
          this._model.availableShips[i].status = 'available';
        }

        if (this._model.availableShips[i].status == 'selected') {

          // Atleast one of our vendors is selected so only show their ships.
          showUnselectedVendorShips = false;
        }
      }

      for (i in this._model.availableShips) {
        // Ships are grouped by vendor.
        var vendorObj = this._model.availableShips[i];

        if (vendorObj.status == 'unavailable') {

          // filter out unavailable vendors.
          continue;
        }

        if (vendorObj.ships && vendorObj.ships.length) {

          // If the vendor has ships then create div for vendor.
          // <div class="enhanced_search_content enhanced_search_options">Carnival Cruise Line</div>
          if (divVendorsEl) {
            var divVendorEl = document.createElement('div');
            divVendorsEl.appendChild(divVendorEl);
            divVendorEl.innerHTML = vendorObj.name;
            divVendorEl.className = 'enhanced_search_content';
            divVendorEl.id = 'vendor_' + vendorObj.id;

            if (vendorObj.status == 'available') {
              divVendorEl.className += ' enhanced_search_options';
            }
            else if (vendorObj.status == 'selected') {
              divVendorEl.className += ' enhanced_search_selected';

              isVendorSelected = true;

              // See if we have a destination label that we have to update with the selected destination.
              var divSelectedCruiselineEl = YAHOO.util.Dom.get(this.selectedCruiselineDiv);
              if (divSelectedCruiselineEl) {

                if (null == this.unSelectedCruiselineHtml) {

                  // Save the html in the label.
                  this.unSelectedCruiselineHtml = divSelectedCruiselineEl.innerHTML;
                }

                // Update the label with the selected item.
                divSelectedCruiselineEl.innerHTML = vendorObj.name;
              }
            }
            else {
              divVendorEl.className += ' enhanced_search_eliminated';
            }


            divVendorEl.onclick = function() {
              var vendorId = (this.id.split('_')[1]);

              for (i in oThis._model.availableShips) {
                if (oThis._model.availableShips[i].id == vendorId) {
                  if (oThis._model.availableShips[i].status == 'available') {

                    // If available and clicked then status becomes selected.
                    oThis._model.availableShips[i].status = 'selected';
                    oThis.fetchUpdate();
                  }
                  else if (oThis._model.availableShips[i].status == 'selected') {

                    // If selected and clicked then status becomes available.
                    oThis._model.availableShips[i].status = 'available';
                    oThis.fetchUpdate();
                  }
                }
              }
            }
          }

          if (divShipsEl) {
            for (j in vendorObj.ships) {

              if (!showUnselectedVendorShips && vendorObj.status !='selected') {
                continue;
              }

              if (!this._model.availableShips[i].ships[j].status) {

                // All items need a status, if no status assume it is available.
                this._model.availableShips[i].ships[j].status = 'available';
              }

              var shipObj = this._model.availableShips[i].ships[j];

              if (shipObj.status == 'unavailable') {

                // filter out unavailable ships.
                continue;
              }

              // Create div for ship element.
              // <div class="enhanced_search_content">Carnival Conquest</div>
              var divShipEl = document.createElement('div');
              divShipsEl.appendChild(divShipEl);
              divShipEl.innerHTML = shipObj.name;
              divShipEl.className = 'enhanced_search_content';
              divShipEl.id = 'ship_' + shipObj.id;

              if (shipObj.status == 'available') {
                divShipEl.className += ' enhanced_search_options';
              }
              else if (shipObj.status == 'selected') {
                divShipEl.className += ' enhanced_search_selected';

                isShipSelected = true;

                // See if we have a destination label that we have to update with the selected destination.
                var divSelectedShipEl = YAHOO.util.Dom.get(this.selectedShipDiv);
                if (divSelectedShipEl) {

                  if (null == this.unSelectedShipHtml) {

                    // Save the html in the label.
                    this.unSelectedShipHtml = divSelectedShipEl.innerHTML;
                  }

                  // Update the label with the selected item.
                  divSelectedShipEl.innerHTML = shipObj.name;
                }
              }
              else {
                divShipEl.className += ' enhanced_search_eliminated';
              }

              divShipEl.onclick = function() {
                var shipId = (this.id.split('_')[1]);

                for (i in oThis._model.availableShips) {
                  for (j in oThis._model.availableShips[i].ships) {
                    if (oThis._model.availableShips[i].ships[j] && oThis._model.availableShips[i].ships[j].id == shipId) {
                      if (oThis._model.availableShips[i].ships[j].status == 'available') {

                        // If available and clicked then status becomes selected.
                        oThis._model.availableShips[i].ships[j].status = 'selected';
                        oThis.fetchUpdate();
                      }
                      else if (oThis._model.availableShips[i].ships[j].status == 'selected') {

                        // If selected and clicked then status becomes available.
                        oThis._model.availableShips[i].ships[j].status = 'available';
                        oThis.fetchUpdate();
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }


      if (divVendorsEl) {
        // Get label.
        var divSelectedCruiselineEl = YAHOO.util.Dom.get(this.selectedCruiselineDiv);

        /* if no item is selected and we have a label and we have
         * html stored to show when nothing is selected then but that into the label.
         */
        if (!isVendorSelected && divSelectedCruiselineEl && null != this.unSelectedCruiselineHtml) {

          divSelectedCruiselineEl.innerHTML = this.unSelectedCruiselineHtml;
        }
      }

      if (divShipsEl) {

        // Get label.
        var divSelectedShipEl = YAHOO.util.Dom.get(this.selectedShipDiv);

        /* if no item is selected and we have a label and we have
         * html stored to show when nothing is selected then but that into the label.
         */
        if (!isShipSelected && divSelectedShipEl && null != this.unSelectedShipHtml) {

          divSelectedShipEl.innerHTML = this.unSelectedShipHtml;
        }
      }
    }
  }
}