// Handles an entry in the list of flight search results displayed to the user.
var TripDisplay = Class.create(hasUniqueID, hasCallback('mouseoverChange'), {
  // Creates a new list entry for the specified trip within parentElt.
  initialize: function(parentElt, trip) {
    this._placeholder = this._appendPlaceholder(parentElt);
    this._trip = trip;
  },
  // Makes this list entry visible to the user.
  show: function() {
    if(this._placeholder) {
      this._replacePlaceholderWithDisplay();
    }
    this._display.show();
  },
  // Makes this list entry invisible to the user.
  hide: function() {
    if(!this._placeholder) {
      this._display.hide();
    }
  },
  // true iff this TripDisplay is visible to the user.
  visible: function() {
    return !this._placeholder && this._display.visible();
  },
  // If this TripDisplay is removed from its original parent element, it can be reused by attaching it to a new parent with appendTo.
  appendTo: function(parent) {
    if(this._placeholder) {
      parent.appendChild(this._placeholder);
    } else {
      parent.insert(this._display);
  	}
  },
  // Changes the highlight state of this display.
  setHighlight: function(turnOn) {
    // Only works if this display isn't just a placeholder
    if(!this._placeholder) {
      // TODO - highlight
     this._display.className = "trip_display" + (turnOn ? " highlighted" : "");

      this._setButtonVisibility(turnOn);
    }
  },
  _maxIconWidth: 40,
  _placeholder: null,
  _display: null,
  _trip: null,
  _buttons: null, 
  _details: null,
  _details_link: null,
  _setButtonVisibility: function(visible) {
    var visibility = visible ? 'visible' : 'hidden';
    this._buttons.setStyle({ 'visibility': visibility });
  },
  _replacePlaceholderWithDisplay: function() {
    this._display = new Element('div', { "class": "trip_display" });
    this._replacePlaceholderWithElement(this._display);
    update_no_scan(this._display, this._displayContent());
    
    // TODO: get rid of $ usage here
    this._buttons = $(this._getTripID() + "_buttons");
    this._details = { top: $(this._getTripID() + '_details_row_top_row_bg'), bottom: $(this._getTripID() + '_details_row_bottom_row_bg') };
    this._details_link = $(this._getTripID() + '_detail_link');

  	this._addEventListenersToDisplay();

  },
  _getTripID: function() {
    return "trip" + this._getUniqueID();
  },
  _appendPlaceholder: function(parentElt) {
    var tn = document.createTextNode(" ");
    parentElt.appendChild(tn);
    return tn;
  },
  _addEventListenersToDisplay: function() {
    var d = this._display;
    d.observe('mouseover', this._fireMouseoverChange.bind(this, true));
    // d.observe('mouseout', this._fireMouseoverChange.bind(this, false));
    this._details_link.observe('click', this._detailToggle.bind(this));
  },
  _replacePlaceholderWithElement: function(element) {
    var placeholder = this._placeholder;
    placeholder.parentNode.insertBefore(element, placeholder);
  	Element.remove(placeholder);
  	this._placeholder = null;
  },
  _displayContent: function() {
    return "<div class='main_display_content'>" +
      this._priceHTML() + this._summaryHTML() +
      this._buttonsHTML() + "</div>" +
      this._detailHTML();
  },
  _priceHTML: function() {
    var trip = this._trip;
    return "<div class='price price_cell'>" +
      "<p class='price_text'>" + formatPrice(trip.price) + "</p>" +
      "<p class='carrier'>" + friendlyName(trip.carrier) + "</p></div>";
  },
  _buttonsHTML: function() {
    var trip = this._trip;
    var tripID = this._getTripID();
    var sb = new Array();
    var BASE_PURCHASE_URL = "http://www.expedia.com/daily/exl/postredir.asp";
    
    sb.push("<div id='" + tripID);
    sb.push("_buttons_cell' class='buttons_cell'><span id='");
    sb.push(tripID);
    sb.push("_buttons' style='visibility: hidden' class='buttons'>");
    
    sb.push("<form method='POST' action='" + BASE_PURCHASE_URL);
    sb.push("?qscr=afwp&flag=p");
    sb.push("&rfrr=" + REFERRER_ID);
    sb.push("&eapid=" + EXPEDIA_AFFILIATED_PRODUCT_ID);
    sb.push("&eapi=" + EAPID);
    sb.push("' target='_buyflight' >");
    sb.push("<input type='hidden' name='wsds' value='" + trip.purchaseParams.wizardSearchDataSet + "'>");
    sb.push("<input type='hidden' name='tovr' value='" + trip.purchaseParams.travelObjectVersion + "'>");
    sb.push("<input type='hidden' name='FltI1' value='" + trip.outbound.blob + "'>");
    sb.push("<input type='hidden' name='FltI2' value='" + trip.inbound.blob + "'>");
    sb.push("<input type='hidden' name='iflt1' value='" + trip.outbound.id + "'>");
    sb.push("<input type='hidden' name='iflt2' value='" + trip.inbound.id + "'>");
    sb.push("<input type='submit' class='book_button' value='Book' border='0' alt='Book'></form><br />");

//    sb.push("<a id='" + tripID);
//    sb.push("_detail_link' class='buy_link'>show details</a><a id='" + tripID + "'_detail_link_image' class="link"</span></div>");
    
    sb.push("<a id='" + tripID);
    sb.push("_detail_link' class='details_link_nounder'>")
    sb.push(this._getDetailsLink(false));
    sb.push("</a></span></div>");
    
    return sb.join("");
  },
  _summaryHTML: function() {
    return "<div class='summary_cell'>" + this._topRowHTML() + this._bottomRowHTML() + "</div>";
  },
  _topRowHTML: function() {
    var tripID = this._getTripID();
    var trip = this._trip;
    var outboundFlight = trip.outbound;
    var sb = new Array();

    sb.push("<div class='top_row_bg'>");
    sb.push("<div class='top_row tla first_column'>" + outboundFlight.departure.airport);
    sb.push("</div><div class='top_row time'>" + formatTimeFromDate(outboundFlight.departure.time));
    sb.push("</div><div class='top_row gutter'>&nbsp;</div><div class='top_row tla'>" + outboundFlight.arrival.airport);
    sb.push("</div><div class='top_row time'>" + formatTimeFromDate(outboundFlight.arrival.time));
    sb.push("</div><div class='top_row right_gutter'>&nbsp;</div><div class='top_row result_duration_text duration'>");
    sb.push(formatDuration(outboundFlight.duration, true));
    sb.push("</div><div class='top_row result_stops_text'>");
    sb.push(this._getStopText(outboundFlight.totalStops));
    sb.push("</div>");
    sb.push("</div>");

    return sb.join("");
  },
  _bottomRowHTML: function() {
    var tripID = this._getTripID();
    var inboundFlight = this._trip.inbound;
    var sb = new Array();
    
    sb.push("<div class='bottom_row_bg'>");
    sb.push("<div class='bottom_row tla first_column'>");
    sb.push(inboundFlight.departure.airport); 
	  sb.push("</div><div class='bottom_row time'>");
	  sb.push(formatTimeFromDate(inboundFlight.departure.time));
	  sb.push("</div><div class='bottom_row gutter'>&nbsp;</div><div class='bottom_row tla'>");
	  sb.push(inboundFlight.arrival.airport);
	  sb.push("</div><div class='bottom_row time'>");
	  sb.push(formatTimeFromDate(inboundFlight.arrival.time));
	  sb.push("</div><div class='bottom_row right_gutter'>&nbsp;</div><div class='bottom_row result_duration_text duration' align='right'>");
	  sb.push(formatDuration(inboundFlight.duration, true));
	  sb.push("</div><div class='bottom_row result_stops_text'>");
	  sb.push(this._getStopText(inboundFlight.totalStops) + "</div>");
    sb.push("</div>");
	  
	  return sb.join("");
  },
  _detailHTML: function() {
    var trip = this._trip;
    var tripID = this._getTripID();
    var bgClass = "top_row_bg"
    var sb = new Array();

    sb.push("<div id='" + tripID + "_details_div' " +
      "class='result_detail_pane' style='display:none'>"); 
      
      sb.push("<div class='price_details_container'><div class='price_details'>(per-person price, includes all flight taxes and fees)</div></div><div class='details_container first_column'>")

	  var label = "Departure";

    $A([trip.outbound, trip.inbound]).each(function(flight) {
       
       var div = "<div class='details_flight_row'>";
       sb.push(div);  // outer wrapper
	     div = "";
	     
	     sb.push("<div class='details_label'>" + label + "</div>");
	     
       
      for( var j=0; j<=flight.legs.length-1; j++ )
      {
        var leg = flight.legs[j];
        
      
        // add possible layover info
					if( j > 0 && (leg.flightNumber != flight.legs[j-1].flightNumber) )		// ignore stopover, shortcircuit && important here
					{
  						sb.push("<div valign='middle' class='layover'><p>Layover in " + friendlyCityName(leg.departure.airport) + " (" + leg.departure.airport + "): ");
  						sb.push(formatDuration((leg.departure.time.getTime() - flight.legs[j-1].arrival.time.getTime()) / 60000));
  						sb.push("</p></div>");
					}
                   
            // add detail date
            sb.push("<div class='details_date'>" + formatDate(leg.departure.time, false, true) + "</div>");

            // everything else
            sb.push("<div class='details_wrapper'>");
            sb.push("<div class='details_main_row'>");
                 
            // flight time info
            sb.push("<div class='details_leg_times'>");
            
            sb.push("<div class='detail_tla'>");
            sb.push("<div class='detail_city'>" + friendlyCityName(leg.departure.airport) + "</div>");
            sb.push("<div class='detail_time'>" + formatTimeFromDate(leg.departure.time) + "</div>");
            sb.push("</div>");

            sb.push("<div class='details_leg_times'>");
            sb.push("<div class='detail_tla'>");
            sb.push("<div class='detail_city'>" + friendlyCityName(leg.arrival.airport) + "</div>");
            sb.push("<div class='detail_time'>" + formatTimeFromDate(leg.arrival.time) + "</div>");
            sb.push("</div>");

            sb.push("</div>");

            sb.push("</div>"); // end details_main_row 



            // Carrier & Flight #
            sb.push("<div class='details_carrier'>");
            sb.push("<div class='details_flight_info'><div class='details_flight_num'>" + friendlyName(leg.marketingCarrier) + "<br />Flight #" + leg.flightNumber + "</div>");
            
            if (leg.equipment)
            {
              sb.push("<div class='details_equip'>" + friendlyEquipmentName(leg.equipment) + "</div>");
            }
            
            
            sb.push("</div>");   // end details_flight_info          
            sb.push("</div>");// end details_carrier  

            // carrier icon
            // constrain the icon to a maximum width
            sb.push("<div class='details_icon'><img src='" + airlineIconURL(leg.marketingCarrier) + "'");
            sb.push("></img></div>");


            if( leg.operatingCarrier )
            {
              sb.push("<div class='details_operating_carrier'>Operated by " + friendlyCarrierLongName(leg.operatingCarrier) + "</div>");
            }
            sb.push("</div>"); // end details_wrapper

            // stops, if necessary
            sb.push("<div class='detail_duration'>"); 
            
            if( leg.stops > 0 )
            {
              var text = (leg.stops == 1)? "stop": "stops";
              sb.push(leg.stops + "&nbsp;" + text);
            }
            else
              sb.push("&nbsp;");
            
            sb.push("</div></div>");	// end stops, flight details row	 


					// if this is the last leg in a flight, add a vertical space
          if( j == flight.legs.length-1)
          {
           sb.push("<div class='flight_spacer'></div>");
          
           bgClass = "bottom_row_bg";
           rowID = tripID + "_details_row_" + bgClass;
           label = "Return";
          }
  
      }      
      sb.push("</div>");  // end outer wrapper
    }.bind(this));

    sb.push("</div></div>")
    
    return sb.join("");
  },
  _detailToggle: function() {
    var detailDivID = this._getTripID() + '_details_div';
    var areDetailsVisible = Element.visible(detailDivID);    
//    var effect = closing ? 'SlideUp' : 'SlideDown';
    var effect = areDetailsVisible ? 'BlindUp': 'BlindDown';
 
		Effect[effect](detailDivID, { duration: .05 },
		  { queue: { scope: 'details', limit: 1 }});
		this._updateDetailsLink(!areDetailsVisible); // have to NOT it, because the Scriptaculous effect will reverse the state
  },
  _updateDetailsLink: function(areDetailsVisible){
     $(this._getTripID() + '_detail_link').update(this._getDetailsLink(areDetailsVisible));
  },
  _getDetailsLink_test: function(areDetailsVisible){
    return "The_details";
  },
  _getDetailsLink: function(areDetailsVisible){
    var text =  areDetailsVisible ? 'hide' : 'show';
    var image = areDetailsVisible ? 'down' : 'left';
    
    return this._getDetailsLinkText(text) + this._getDetailsChevronImage(image);  
  },
  _getDetailsLinkText: function(which){
    return "<span style='text-decoration: underline;'>" + which + " details</span>";
  },
  _getDetailsChevronImage: function(which){
    var url;
    
    if(which == "down")
      url = collapseButtonImgURL;
    else
      url = uncollapseButtonImgURL;

    return "<img class='details_chevron' border=0 src='" + url + "'/>";
  },
  _getStopText: function(num_stops)
  {
  	if( num_stops >= 0)
  		return "(" + num_stops + " " + pluralize(num_stops, "stop") + ")";
  	else
  		return "No stop info.";
  }
});
