/******************************************************************************
 *
 *  Copyright 2008-2009 David D. Emory 
 *  [additional contributors append names above]
 *  
 *  This file is part of Five Points. See <http://www.fpdev.org> for
 *  additional project information and documentation.
 *  
 *  Five Points is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  Five Points is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with Five Points.  If not, see <http://www.gnu.org/licenses/>.
 *  
 ******************************************************************************/  

/**
 *  fp_trp.js
 *
 *  Primary javascript file for the Trip Planner (abbreviated "TRP") module.
 *  See fp_trp.php for full documentation for the trp module.
 */
 
// FIELD DEFINITIONS

var fp_tCurTripType_; // string, current trip type, value is either "tt" (travel time) or "nt" (number of transfers)
var fp_encodedStartLoc_, fp_encodedEndLoc_;

var fp_tTripTimeTT_, fp_tTripTimeNT_, fp_tTripTimeSP_; // integer values of current trip times in minutes
var fp_tNumTransfersTT_, fp_tNumTransfersNT_, fp_tNumTransfersSP_; // integer values for num of transfers

var fp_tServerName_, fp_tQueryTime_, fp_tQueryLength_; // server name/time/length for most recent trip query

// numeric constants representing the different output panel tabs:
var FP_OUTPUT_WELCOME = 1; // the static "welcome" display; active by default 
var FP_OUTPUT_LOCATIONS = 2; // area for dynamic display of locations, e.g., after a map click
var FP_OUTPUT_RESULTS = 3; // area for dynamic display of 

var fp_outputDivs_; // array of div objects representing the content areas of the output panel tabs
var fp_trpSelOutputTab_; // integer index of the currently active tab 

var fp_tItinDivTT_, fp_tItinDivNT_, fp_tItinDivNM_, fp_tItinDivSP_; // divs to contain the rendered trip results (Travel time, Number of transfers, & Non-motorized)


// FUNCTION DEFINITIONS

/**
 * fp_initTrp()
 * 
 * Initialization function for the trip planner module.
 * 
 */
function fp_initTrp() {
  fp_initEntry();
  fp_tCurTripType_ = "tt"; // temp

  fp_outputDivs_ = new Array();

  fp_outputDivs_[FP_OUTPUT_WELCOME] = document.createElement("div");
  fp_ajaxLoadAsText("content/welcome.html", fp_trpHandleWelcomeContent);

  fp_outputDivs_[FP_OUTPUT_LOCATIONS] = document.createElement("div");
  fp_outputDivs_[FP_OUTPUT_LOCATIONS].innerHTML = "(This panel is used for resolving location queries)";

  fp_outputDivs_[FP_OUTPUT_RESULTS] = document.createElement("div");
  fp_outputDivs_[FP_OUTPUT_RESULTS].innerHTML = "(Trip planner query results will be displayed here)";

  fp_tItinDivTT_ = document.createElement("div");
  fp_tItinDivNT_ = document.createElement("div");
  fp_tItinDivNM_ = document.createElement("div");
  fp_tItinDivSP_ = document.createElement("div");
  
  fp_oTabSelected(FP_OUTPUT_WELCOME);
}

function fp_trpHandleWelcomeContent(content) {
  fp_outputDivs_[FP_OUTPUT_WELCOME].innerHTML = content;
}

/**
 * fp_oTabSelected()
 * 
 * This function is called when one of the output area tabs is selected.
 * 
 * -- parameters --
 * index: the numeric index for the activated tab
 */
function fp_oTabSelected(index) {
  var otab = document.getElementById("fp_otab"+index);
  otab.style.borderBottom = "2px solid white";
  otab.style.background = "#fff";
  for(i=1; i<=3; i++) {
    if(index != i) {
      otab = document.getElementById("fp_otab"+i);
      otab.style.background = "#ddd";
      otab.style.borderBottom = "2px solid black";
    }
  }
  
  // activate the appropriate content div
  var oMain = document.getElementById("fp_outputMain");
  while(oMain.hasChildNodes()) oMain.removeChild(oMain.lastChild);  
  oMain.appendChild(fp_outputDivs_[index]);
  fp_trpSelOutputTab_ = index;
}


/**
 * fp_trpProcessingMsg()
 * 
 * Displays a temporary status message in the main output content area.
 * 
 * -- parameters --
 * msg: the text of the message
 */
function fp_trpProcessingMsg(msg) {
  var activeDiv = fp_outputDivs_[fp_trpSelOutputTab_];
  activeDiv.innerHTML = msg;
}


/**
 * fp_oShowLocResults()
 * 
 * Displays the results of a nearby-locations query in the output area.
 */
function fp_oShowLocResults() {
  var results = fp_outputDivs_[FP_OUTPUT_LOCATIONS];

  var html = "The following nearby locations were found:<br/>";
  for(i=0; i<fp_proxLocArr_.length; i++) {
    html += "<div style=\"margin-top:3px;\">&bull; <b>"+fp_proxLocArr_[i]+"</b> - Set as: [<a href=\"javascript:fp_startLocSelFromMap("+i+")\">START</a> | <a href=\"javascript:fp_endLocSelFromMap("+i+")\">END</a>]</div>";
  }	
  if(i == 0) html = "<i>(No locations found within a 250' radius)</i>";  
	
  results.innerHTML = html;
}


/**
 * fp_startLocSelFromMap()
 *
 * Sets the encoded start location based on the user's choice of a map-click
 * location cadidate.
 *
 * -- parameters --
 * index: the selected index of the clicked location candidate array
 */
function fp_startLocSelFromMap(index) {
  fp_externalSetStart(fp_proxLocArr_[index]);
  fp_encodedStartLoc_ = fp_proxLocEncArr_[index];
  fp_tmCreateStartMarker(new GLatLng(fp_proxLocYArr_[index], fp_proxLocXArr_[index]), "start location");
}

/**
 * fp_endLocSelFromMap()
 *
 * Sets the encoded end location based on the user's choice of a map-click
 * location cadidate.
 *
 * -- parameters --
 * index: the selected index of the clicked location candidate array
 */
function fp_endLocSelFromMap(index) {
  fp_externalSetEnd(fp_proxLocArr_[index]);
  fp_encodedEndLoc_ = fp_proxLocEncArr_[index];
  fp_tmCreateEndMarker(new GLatLng(fp_proxLocYArr_[index], fp_proxLocXArr_[index]), "end location");
}


/**
 * fp_startLocSelFromGeocode()
 *
 * Sets the encoded start location based on the user's choice of a geocoded
 * location cadidate.
 *
 * -- parameters --
 * index: the selected index of the geocoded start-location candidate array
 */
function fp_startLocSelFromGeocode(index) {
  fp_externalSetStart(fp_tgGeocodeStartAddrs_[index]);
  fp_encodedStartLoc_ = fp_tgGeocodeStartEncodings_[index];
  fp_tmCreateStartMarker(fp_tgGeocodeStartLatLngs_[index], "start location");
}

/**
 * fp_endLocSelFromGeocode()
 *
 * Sets the encoded start location based on the user's choice of a geocoded
 * location cadidate.
 *
 * -- parameters --
 * index: the selected index of the geocoded start-location candidate array
 */
function fp_endLocSelFromGeocode(index) {
  fp_externalSetEnd(fp_tgGeocodeEndAddrs_[index]);
  fp_encodedEndLoc_ = fp_tgGeocodeEndEncodings_[index];
  fp_tmCreateEndMarker(fp_tgGeocodeEndLatLngs_[index], "end location");
}

/**
 * fp_tripRequest()
 *
 * Initiates a trip planner request. If both locations have been encoded, then
 * the request is sent immediately. Otherwise, an attempt to resolved the
 * locations must be made first.
 */
function fp_tripRequest() {

  if(fp_getStartFieldValue().length  == 0 || fp_getEndFieldValue().length == 0) {
    alert("Please specify both start and end locations");
    return;
  }
	
  if(fp_encodedStartLoc_ != null && fp_encodedEndLoc_ != null) {
    fp_dbg("trip req");
    fp_makeTripRequest(1);
  }
  else { // one or both endpoints not resolved
    fp_dbg("resolve req");
    if(fp_encodedStartLoc_ == null && fp_encodedEndLoc_ != null) fp_tgGeocodeStart();
    else if(fp_encodedStartLoc_ != null && fp_encodedEndLoc_ == null) fp_tgGeocodeEnd();
    else fp_tgGeocodeBoth();
  }
}

function fp_tPrepareResultsOutput() {
  var resultsDiv = fp_outputDivs_[FP_OUTPUT_RESULTS];

  var resultsRowDiv = document.createElement("div");
  resultsRowDiv.id="fp_tResultsRow";

  var specialResultsRowDiv = document.createElement("div");
  specialResultsRowDiv.id="fp_tSpecialResultsRow";

  var itinDiv = document.createElement("div");
  itinDiv.id = "fp_tItinArea";
	
  resultsDiv.appendChild(resultsRowDiv);
  resultsDiv.appendChild(specialResultsRowDiv);
  resultsDiv.appendChild(itinDiv);
	
}

/**
 * fp_tInitResultsRow(selTripType)
 *
 * Initializes the results row displayed at the top of any successful transit-
 * based trip search display, summarizing the best trip found in each of the
 * two categories (fastest time and fewest transfers), and gives the user the
 * ability to toggle between the two. The single parameter, selTripTime (a
 * String, either "tt" or "nt") indicates which type is currently selected.
 */  
function fp_tInitResultsRow(selTripType) { 
  fp_tInitResultsRow(selTripType, true);
}

function fp_tInitResultsRow(selTripType, showCurrent) {

  if(showCurrent) {
    var resultsRowDiv = document.getElementById("fp_tResultsRow");
    resultsRowDiv.style.marginBottom = "4px";
    resultsRowDiv.style.padding = "3px";
    resultsRowDiv.style.background = "#dddddd";
    var html = "";
    html += (selTripType=="tt" ? "<b>" : "<a href='javascript:fp_tShowTravelTimeTrip()'>")+"Trip with Shortest Travel Time"+(selTripType=="tt" ? " (shown)</b>" : "</a>")+": "+fp_elapsedTimeStr(fp_tTripTimeTT_)+" w/ "+fp_tNumTransfersTT_+" transfer"+(fp_tNumTransfersTT_==1 ? "" : "s")+"<br>";
    html += (selTripType=="nt" ? "<b>" : "<a href='javascript:fp_tShowNumTransfersTrip()'>")+"Trip with Fewest Transfers"+(selTripType=="nt" ? " (shown)</b>" : "</a>")+": "+fp_elapsedTimeStr(fp_tTripTimeNT_)+" w/ "+fp_tNumTransfersNT_+" transfer"+(fp_tNumTransfersNT_==1 ? "" : "s");
    resultsRowDiv.innerHTML = html;
  }

  /*var spResultsRowDiv = document.getElementById("fp_tSpecialResultsRow");
  spResultsRowDiv.style.marginBottom = "10px";
  spResultsRowDiv.style.padding = "3px";
  spResultsRowDiv.style.background = "#FFA07A";
  if(selTripType=="sp") {
    spResultsRowDiv.innerHTML = "<b>This is a hypothetical trip only.</b> The following illustrative itinerary approximates how your trip might be completed <i>if</i> portions of the Concept 3 vision were built out.";
  }
  else {
    spResultsRowDiv.innerHTML = "Performing your search on Concept 3...";
    // start special search
    fp_makeTripRequest(3);

  }*/
}

/**
 * fp_tShowTravelTimeTrip()
 * 
 * Displays the current best travel time trip, updating both the itinerary
 * output area and the map.
 */
function fp_tShowTravelTimeTrip() {
  fp_tInitResultsRow("tt", true);
  var itinArea = document.getElementById("fp_tItinArea"); 
  while (itinArea.firstChild) itinArea.removeChild(itinArea.firstChild);
  itinArea.appendChild(fp_tItinDivTT_);
  fp_tCurTripType_ = "tt";
  fp_tShowTripMap(fp_tMapIdTT_);
}

/**
 * fp_tShowTravelTimeTrip()
 * 
 * Displays the current best number-of-transfers trip, updating both the 
 * itinerary output area and the map.
 */
function fp_tShowNumTransfersTrip() {
  fp_tInitResultsRow("nt", true);
  var itinArea = document.getElementById("fp_tItinArea"); 
  while (itinArea.firstChild) itinArea.removeChild(itinArea.firstChild);
  itinArea.appendChild(fp_tItinDivNT_);
  fp_tCurTripType_ = "nt";
  fp_tShowTripMap(fp_tMapIdNT_);
}

function fp_showSpecialTrip(showCurrentResults) {
  if(!showCurrentResults) {
    var output = fp_outputDivs_[FP_OUTPUT_RESULTS];
    output.removeChild(document.getElementById("fp_tNoTripFoundMsg"));
  }
  fp_tInitResultsRow("sp", showCurrentResults);
  var itinArea = document.getElementById("fp_tItinArea");
  while (itinArea.firstChild) itinArea.removeChild(itinArea.firstChild);
  itinArea.appendChild(fp_tItinDivSP_);
  fp_tCurTripType_ = "sp";
  fp_tShowTripMap(fp_tMapIdSP_);
}

function fp_tShowNonMotorizedTrip() {
  var itinArea = document.getElementById("fp_tItinArea"); 
  while (itinArea.firstChild) itinArea.removeChild(itinArea.firstChild);
  itinArea.appendChild(fp_tItinDivNM_);
  //prompt("", mapLinksNM_);
  fp_tShowTripMap(fp_tMapIdNM_);
}

function fp_tSwapEndpoints() {
  var temp = fp_encodedStartLoc_;
  fp_encodedStartLoc_ = fp_encodedEndLoc_;
  fp_encodedEndLoc_ = temp; 
}