/******************************************************************************
 *
 *  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_entry.js
 *
 * A supporting javascript file for the Trip Planner ("TRP") module containing
 * fields and functions relating to the user entry, i.e. the DHTML-based
 * onscreen area used for specificing trip parameters. Major components include:
 *  - A row of tabs for selecting the type of trip (walk, bike, etc.)
 *  - The start and end location fields
 *  - The time-of-day fields with adjustment slider widget
 *  - Controls for the walk/bike speed & radius options 
 *  - The "bike triangle" a widget for adjusting the three bike trip
 *    optimization options (distance, topography, & facility type).
 * Note: all fields and functions should begin with the "fp_te" prefix.
 *
 * See fp_trp.php for additional documentation on the Trip Planner module.
 */
  
// FIELD DECLARATIONS

var fp_teMainContainer_;

var fp_eSelectedTab_; // integer, represents the currently-active trip-type tab

// constants for the different trip-type tabs
var FP_ETAB_WALK_ONLY = 1;
var FP_ETAB_BIKE_ONLY = 2;
var FP_ETAB_WALK_TO_TRANSIT = 3;
var FP_ETAB_BIKE_TO_TRANSIT = 4;
 
var fp_clickedStart_;
var fp_clickedEnd_;

var fp_eTime_, fp_eInitTime_;

var fp_teBikeTriangleDiv_; // the <div> element containing the bike triangle
var fp_teBTTopoPct_, fp_teBTDistPct_, fp_teBTFacPct_; // floats; bike triangle factors (0.0 - 1.0)

//var fp_autoMinimize_; // boolean
var fp_teMaximized_;

// FUNCTION DEFINITIONS

/**
 * fp_initEntry()
 *
 * Initializes the trip-planner user entry. Called once upon TRP module load.
 */

function fp_initEntry() {
  fp_teMaximized_ = true;
  fp_eTabSelected(FP_ETAB_WALK_TO_TRANSIT);
  fp_clickedStart_ = fp_clickedEnd_ = false; //fp_autoMinimize_ = false;
  
  fp_eInitTimeSlider();
  fp_eInitTime();
  
  fp_teBikeTriangleDiv_ = null;
  fp_teBTTopoPct_ = fp_teBTDistPct_ = fp_teBTFacPct_ = 1/3;   
}

function fp_teSetParams(tripType, startLoc, endLoc, time, day) {
  if(!fp_teMaximized_) fp_teMaximize();
  
  switch(tripType) {
    case 1:
      fp_eTabSelected(FP_ETAB_WALK_TO_TRANSIT);
      document.getElementById("fp_eRadius").value=.75;
      document.getElementById("fp_depArrInput").selectedIndex = 0;
      document.getElementById("fp_dayInput").selectedIndex = 0;
      break;
    case 2:
      fp_eTabSelected(FP_ETAB_BIKE_TO_TRANSIT);
      document.getElementById("fp_eRadius").value=.75;
      document.getElementById("fp_depArrInput").selectedIndex = 0;
      document.getElementById("fp_dayInput").selectedIndex = 0;
      break;
    case 3:
      fp_eTabSelected(FP_ETAB_WALK_ONLY);
      break;
    case 4:
      fp_eTabSelected(FP_ETAB_BIKE_ONLY);
      break;
  }
  
  if(time.length > 0) document.getElementById("fp_timeInput").value = time;
  
  document.getElementById("fp_startLocInput").value = startLoc;
  document.getElementById("fp_endLocInput").value = endLoc;
  fp_tgGeocodeBoth();
  
  //fp_externalSetStart(startLoc);
  //fp_externalSetEnd(endLoc);
}

function fp_teCheckButtonEnterKey(evt) {
  evt = (evt) ? evt : event;
  var charCode = (evt.charCode) ? evt.charCode : ((evt.which) ? evt.which : evt.keyCode);
  if(charCode == 13) {
    fp_dbg("button enter pressed");
    return false;
  }
}

///////////////////////////// MINIMIZE/MAXIMIZE ////////////////////////////////

/**
 * Minimizes the entry panel to a single-line display. Panel will automatically
 * maximize on mouse-over.
 */
function fp_teMinimize() {
  if(!fp_teMaximized_) return; 
  //fp_dbg("teMin");
	
  fp_teMainContainer_ = document.getElementById("fp_teMainContainer")
  var teMain = document.getElementById("fp_teMain");
  while(teMain.hasChildNodes()) teMain.removeChild(teMain.lastChild);
  teMain.innerHTML = "<div style='font-size:12px; font-style: italic; text-align:center;'>(<a href='javascript:fp_teMaximize()'>Show Trip Options Entry Panel</a>)</div>";
	
  //teMain.onmouseover = fp_teMaximize;
  document.getElementById("fp_trpOutput").style.top = "75px";
  
  fp_teMaximized_ = false;
  document.getElementById("fp_teHideShowEntry").innerHTML = ""; //'<a href="javascript:fp_teMaximize()">SHOW ENTRY PANEL</a>';
}


function fp_teMinimizeEvt(e) {
  //fp_dbg("teMinEvt");
  var autoMinChecked = document.getElementById("fp_teAutoMin").checked;
  //fp_dbg("autoMinChecked="+autoMinChecked);
  if(!autoMinChecked) return;
	
  var x, y;
  if(fp_IE_) {
    x = event.clientX;
    y = event.clientY;
  }
  else {
    x = e.clientX;
    y = e.clientY;
  }
  fp_dbg("x="+x+" y="+y);
  if(y>320) fp_teMinimize();
}


function fp_teMaximize() {
  if(fp_teMaximized_) return; 

  var teMain = document.getElementById("fp_teMain");
  while(teMain.hasChildNodes()) teMain.removeChild(teMain.lastChild);
  teMain.appendChild(fp_teMainContainer_);
  //teMain.onmouseout = fp_teMinimizeEvt;
  document.getElementById("fp_trpOutput").style.top = "232px";

  fp_teMaximized_ = true;
  document.getElementById("fp_teHideShowEntry").innerHTML = '<a href="javascript:fp_teMinimize()">HIDE<br>OPTIONS</a>';
}


//////////////////////////// ENTRY TAB FUNCTIONS ///////////////////////////////

function fp_eTabSelected(index) {
  if(!fp_teMaximized_) fp_teMaximize();
  var etab = document.getElementById("fp_etab"+index);
  etab.style.borderBottom = "2px solid #ddd";
  etab.style.background = "#ddd";
  for(i=1; i<=4; i++) {
    if(index != i) {
      etab = document.getElementById("fp_etab"+i);
      if(etab != null) {
        etab.style.background = "#bbb";
        etab.style.borderBottom = "2px solid black";
      }
    }
  }
  if(index == FP_ETAB_BIKE_ONLY || index == FP_ETAB_BIKE_TO_TRANSIT) fp_showBikeOptions();
  if(index == FP_ETAB_WALK_ONLY || index == FP_ETAB_WALK_TO_TRANSIT) fp_showWalkOptions();
  fp_eSelectedTab_ = index;
}

/**
 * Converts currently selected trip-type tab index to numeric value used by
 * 5P back-end software.
 */
function fp_eGetTripType() {
  switch(fp_eSelectedTab_) {
    case FP_ETAB_WALK_ONLY: return 3;
    case FP_ETAB_BIKE_ONLY: return 4;
    case FP_ETAB_WALK_TO_TRANSIT: return 1;
    case FP_ETAB_BIKE_TO_TRANSIT: return 2;
  }
}


/////////////////////////// START FIELD FUNCTIONS //////////////////////////////

function fp_getStartFieldValue() {
  if(!fp_clickedStart_) return "";
  return document.getElementById("fp_startLocInput").value;
}

function fp_clickStartField() {
  if(fp_clickedStart_) return;
  var field = document.getElementById("fp_startLocInput");
  field.style.color = "#000";
  field.value = "";
  fp_clickedStart_ = true;
}

var fp_startFieldColor;
var fp_fadeStartInterval;

function fp_externalSetStart(text) {
  var field = document.getElementById("fp_startLocInput");
  if(!fp_clickedStart_) {
    field.style.color = "#000";
    fp_clickedStart_ = true;
  }
  field.value = text;
  fp_startFieldColor = 0;
  fp_fadeStartInterval = setInterval("fp_fadeStartField()", 50);
}


function fp_fadeStartField() {
  var hex = fp_startFieldColor.toString(16);
  document.getElementById("fp_startLocInput").style.background = "#"+"ff"+hex;
  fp_startFieldColor++;
  if(fp_startFieldColor >= 16) clearInterval(fp_fadeStartInterval);
}

function fp_teCheckStartEnterKey(evt) {
  evt = (evt) ? evt : event;
  var charCode = (evt.charCode) ? evt.charCode : ((evt.which) ? evt.which : evt.keyCode);
  if(charCode == 13) {
    fp_dbg("start enter pressed");
    fp_tgGeocodeStart();
  }
}

function fp_teSwapEndPoints() {
  var temp = document.getElementById("fp_startLocInput").value;
  document.getElementById("fp_startLocInput").value = document.getElementById("fp_endLocInput").value;
  document.getElementById("fp_endLocInput").value = temp; 
  
  // swap the underlying encoded values
  fp_tSwapEndpoints();
}

//////////////////////////// END FIELD FUNCTIONS ///////////////////////////////

function fp_getEndFieldValue() {
  if(!fp_clickedEnd_) return "";
  return document.getElementById("fp_endLocInput").value;
}

function fp_clickEndField() {
  if(fp_clickedEnd_) return;
  var field = document.getElementById("fp_endLocInput");
  field.style.color = "#000";
  field.value = "";
  fp_clickedEnd_ = true;
}

var fp_endFieldColor;
var fp_fadeEndInterval;

function fp_externalSetEnd(text) {
  var field = document.getElementById("fp_endLocInput");
  if(!fp_clickedEnd_) {
    field.style.color = "#000";
    fp_clickedEnd_ = true;
  }
  field.value = text;
  fp_endFieldColor = 0;
  fp_fadeEndInterval = setInterval("fp_fadeEndField()", 50);
}

function fp_fadeEndField() {
  var hex = fp_endFieldColor.toString(16);
  document.getElementById("fp_endLocInput").style.background = "#"+"ff"+hex;
  fp_endFieldColor++;
  if(fp_endFieldColor >= 16) clearInterval(fp_fadeEndInterval);
}

function fp_teCheckEndEnterKey(evt) {
  evt = (evt) ? evt : event;
  var charCode = (evt.charCode) ? evt.charCode : ((evt.which) ? evt.which : evt.keyCode);
  if(charCode == 13) {
    fp_dbg("end enter pressed");
    fp_tgGeocodeEnd();
  }
}


/////////////////////////// MAIN OPTION FUNCTIONS //////////////////////////////

function fp_showBikeOptions() {
  // bump the main (text-based) options over to the right 
  document.getElementById("fp_eMainOptions").style.left = "108px";

  // change the option labels
  document.getElementById("fp_eSpeedLabel").innerHTML = "Bike Speed (mph)";
  document.getElementById("fp_eRadiusLabel").innerHTML = "Bike Radius (mi)";
  
  // add the bike slider to the left side
  if(fp_teBikeTriangleDiv_ == null) {
    // construct the block if this is the first request
    fp_teBikeTriangleDiv_ = fp_teConstructBikeTriangleBlock(); 
    document.getElementById("trp_eAdvOptBlock").appendChild(fp_teBikeTriangleDiv_);
    fp_eInitBikeTriangle();
  }
  else // otherwise just add the existing reference
    document.getElementById("trp_eAdvOptBlock").appendChild(fp_teBikeTriangleDiv_);
}

function fp_showWalkOptions() {
  document.getElementById("fp_eMainOptions").style.left = "5px";

  //document.getElementById("fp_eBikeBlock").style.height = "113px";
  document.getElementById("fp_eSpeedLabel").innerHTML = "Walk Speed (mph)";
  document.getElementById("fp_eRadiusLabel").innerHTML = "Walk Radius (mi)";
  
  if(fp_teBikeTriangleDiv_ != null && fp_teBikeTriangleDiv_.parentNode == document.getElementById("trp_eAdvOptBlock")) 
    document.getElementById("trp_eAdvOptBlock").removeChild(fp_teBikeTriangleDiv_);
}

function fp_eSetWalkSpeedTips() {
  var select = document.getElementById("fp_eSpeedTips");
  select.options.length = 3;
  select.options[i] = new Option('2.0 MPH','2.0');
  select.options[i] = new Option('2.0 MPH','2.0');
  select.options[i] = new Option('2.0 MPH','2.0');
}

function fp_eSpeedTipSelected() {
  var select = document.getElementById("fp_eSpeedTips");
  document.getElementById("fp_eSpeed").value = select.value;
  select.selectedIndex=0;
}

function fp_eRadiusTipSelected() {
  var select = document.getElementById("fp_eRadiusTips");
  document.getElementById("fp_eRadius").value = select.value;
  select.selectedIndex=0;
}

////////////////////////// TIME SELECTOR FUNCTIONS /////////////////////////////

function fp_eInitTime() {
  var ts = new Date();
  var hour = ts.getHours(), min = ts.getMinutes();
  fp_eTime_ = hour*60 + min;
  fp_eUpdateTimeInput();
  fp_eInitTime_ = fp_eTime_;
}

function fp_eUpdateTimeInput() {
  var hour = Math.floor(fp_eTime_ / 60);
  var min = fp_eTime_ % 60;
  var ampm = 'a';
	
  if(hour == 0) hour = 12;
  else if(hour == 12) ampm = 'p';
  if(hour > 12) {
    hour -= 12;
    ampm = 'p';
  }
		
  document.getElementById("fp_timeInput").value = hour + ":" + (min<10 ? "0" : "") + min +ampm;
}

function fp_eNewTimeInput() {
  var timeStr = document.getElementById("fp_timeInput").value;
  var hour = parseInt(fp_eGetHoursFromInput(timeStr));
  var min = parseInt(fp_eGetMinutesFromInput(timeStr));
  var ampm = fp_eGetAMPMFromInput(timeStr);
 
  if(isNaN(hour) || hour < 1 || hour > 12 || isNaN(min) || min < 0 || min > 59 || isNaN(ampm) || ampm < 0 || ampm > 1) {
    alert("Invalid time input: "+timeStr);
    fp_eUpdateTimeInput();
    return;
  }
  
  if(hour == 12 && ampm == 0) hour = 0;
  if(ampm == 1) hour += 12;
  fp_eTime_ = hour*60 + min;
  fp_eInitTime_ = fp_eTime_;
  fp_eUpdateTimeInput();
}  

function fp_eGetHoursFromInput(str) {
  var cLoc = str.indexOf(':');
  return str.substr(0, cLoc);
}

function fp_eGetMinutesFromInput(str) {
  var cLoc = str.indexOf(':');
  return str.substr(cLoc+1, 2);
}

function fp_eGetAMPMFromInput(str) {
  str = str.toLowerCase();
  if(str.indexOf('a') != -1) return 0;
  if(str.indexOf('p') != -1) return 1;
  return -1;
}

function fp_eInitTimeSlider() {
  var dragger = document.getElementById("fp_eTimeSlider");
  var label = document.getElementById("fp_eTimeSliderLabel");
  var dd = new YAHOO.util.DD(dragger);
  dd.setXConstraint(85,85);
  dd.setYConstraint(0,0);
  dd.on('dragEvent', function(ev) { 
    //out('cx=' + dragger.offsetLeft);
    label.style.left = (dragger.offsetLeft-20) + "px";
    //label.innerHTML = dragger.offsetLeft-85;
    var dmin = Math.floor((dragger.offsetLeft-85)/85 * 60 );
    label.innerHTML = (dmin<0 ? "-" : "+") + Math.abs(dmin)+" min";

    // update time
    fp_eTime_ = fp_eInitTime_ + dmin;
    if(fp_eTime_ < 0) fp_eTime_ += 1440;
    else if(fp_eTime_ >= 1440) fp_eTime_ -= 1440;  
    fp_eUpdateTimeInput();

  }, dd, true);
  dd.on('mouseDownEvent', function(ev) { 
		fp_eInitTime_ = fp_eTime_;
  }, dd, true);
  dd.on('mouseUpEvent', function(ev) { 
    //out('mouse up');
    dragger.style.left = "85px"; 
    label.style.left = "65px"; 
    label.innerHTML = "&lt;&lt; DRAG &gt;&gt;";
  }, dd, true);
}


////////////////////////// BIKE TRIANGLE FUNCTIONS /////////////////////////////

function fp_teConstructBikeTriangleBlock() {
  var block = document.createElement("div");
  block.id = "fp_eBikeTriangleBlock";
  
  var header = document.createElement("div");
  header.id = "fp_eBikeTriangleHeader";
  header.innerHTML = "BIKE TRIANGLE";
  
  var triangle = document.createElement("div");
  triangle.id = "fp_eBikeTriangle";
  var slider = document.createElement("div");
  slider.id = "fp_eBikeSlider";
  triangle.appendChild(slider);
  
  var footer = document.createElement("div");
  footer.id = "fp_eBikeTriangleFooter";
  footer.innerHTML = '(<a href="">What is this?</a>)';
  
  block.appendChild(header);
  block.appendChild(triangle);
  block.appendChild(footer);
  
  return block;  
}

function fp_eInitBikeTriangle() {
  var dragger = document.getElementById("fp_eBikeSlider");
  var dd = new YAHOO.util.DD(dragger);
  dd.setXConstraint(50,50);
  dd.setYConstraint(58,29);
  dd.on('dragEvent', function(ev) {
    var x = dragger.offsetLeft + 10, y = dragger.offsetTop + 10;
		var minx = 50-50*y/87, maxx = 100-minx;
  	if(x < minx) {
  		dragger.style.left = (minx-10) + "px";
  		x = minx;
  	}
  	if(x > maxx) {
  		dragger.style.left = (maxx-10) + "px"; 
  		x = maxx;
  	}

	  var dA = Math.round(fp_distToSegment(x, y, 50,0, 100,87));
	  var dB = 87-(y);
	  var dC = Math.round(fp_distToSegment(x, y, 50,0, 0,87));
	  
	  var aPct = dA/(dA+dB+dC);
	  var bPct = dB/(dA+dB+dC);
	  var cPct = dC/(dA+dB+dC);
	  
	  fp_teBTTopoPct_ = aPct;
	  fp_teBTDistPct_ = bPct;
	  fp_teBTFacPct_ = cPct;
	   
	  fp_eUpdateBikeBars();
  }, dd, true);
  dd.on('mouseDownEvent', function(ev) {
  	fp_eShowBikeBars() 
    //out('tri mouse down');
  }, dd, true);
  dd.on('mouseUpEvent', function(ev) {
  	fp_eHideBikeBars() 
    //out('tri mouse up');
  }, dd, true);
}

function fp_eShowBikeBars() {
  var bars = document.createElement("div");
  bars.id = "fp_eBikeBars";
  document.getElementById("trp_eAdvOptBlock").appendChild(bars);
  fp_dbg("showing bars");
  fp_eUpdateBikeBars();
}

function fp_eHideBikeBars() {
  var bars = document.getElementById("fp_eBikeBars");
  document.getElementById("trp_eAdvOptBlock").removeChild(bars);
}

function fp_eUpdateBikeBars() {
  var html = "";
  
  html = html + "<div style='margin-bottom:1px; border-bottom: 1px solid gray;'>Distance</div>"
  html = html + "<div style='float:left; width:55px; margin-top:1px; height:12px; background:white;'>";
  html = html + "<div style='width:"+Math.round(55*fp_teBTDistPct_)+"px; height:12px; background:blue;'><!-- --></div>";
  html = html + "</div>";
  html = html + "<div style='margin-left: 57px; font-weight:bold;'>"+Math.round(100*fp_teBTDistPct_)+"%</div>";
  html = html + "</div>";

  html = html + "<div style='margin-bottom:1px; border-bottom: 1px solid gray;'>Topography</div>"
  html = html + "<div style='float:left; width:55px; margin-top:1px; height:12px; background:white;'>";
  html = html + "<div style='width:"+Math.round(55*fp_teBTTopoPct_)+"px; height:12px; background:blue;'><!-- --></div>";
  html = html + "</div>";
  html = html + "<div style='margin-left: 57px; font-weight:bold;'>"+Math.round(100*fp_teBTTopoPct_)+"%</div>";
  html = html + "</div>";

  html = html + "<div style='margin-bottom:1px; border-bottom: 1px solid gray;'>Facility Type</div>"
  html = html + "<div style='float:left; width:55px; margin-top:1px; height:12px; background:white;'>";
  html = html + "<div style='width:"+Math.round(55*fp_teBTFacPct_)+"px; height:12px; background:blue;'><!-- --></div>";
  html = html + "</div>";
  html = html + "<div style='margin-left: 57px; font-weight:bold;'>"+Math.round(100*fp_teBTFacPct_)+"%</div>";
  html = html + "</div>";

  document.getElementById("fp_eBikeBars").innerHTML = html;
}


