var DEBUG_RESULTS = 0;
var UPDATEON = 1;
var RESULTS = [ ];//new Array();
var sourceInput = "";
var destinationInput = "";
var dayOfWeek = "";
var prevDow = "";
var nextDow = "";
var activeDetail ="";
var TIME_BUFFER = 15;
var updateRequests = new Array();
var totalSorts = 0;
var updatePollingThread;

function getModeImgURL(mode, majorHop) {
  var ext = "gif";
  // use type to determine bg
  if(mode == "intracity") {
    mode = "metro";
  }
  if(mode == "drive") {
    mode = "limo";
  }
  if(mode == "limo" || mode == "taxi") {
    ext = "png";
  }
  if(mode == "metro" && majorHop == undefined) {
    mode = "walk-metro";
    ext = "png";
  }
  return baseURL + "css/images/" + mode + "-ico." + ext;
}

function withinCart(lat1, lng1, lat2, lng2, max) {
  var dLng = 53.0*(lng2 - lng1);
  var dLat = 69.1*(lat2 - lat1);
  var dist = Math.sqrt(dLng*dLng + dLat*dLat);
  return (dist < max) ? Math.round(dist, 1) : -1;
}

function cmpDefault(a,b) { 
  if(a.fare != b.fare) {
    return a.fare - b.fare;
  } else {
    return a.totalTime - b.totalTime;
  }
}

function cmpDuration(a,b) { return a.totalTime - b.totalTime;  }

var durationSortedAscend = 0;

function cmpDurationAscend(a,b) { 
  if(a.totalTime == b.totalTime) {
    return a.fare - b.fare; 
  } else {
    return a.totalTime - b.totalTime;  
  }
}
function cmpDurationDescend(a,b) { 
  if(a.totalTime == b.totalTime) {
    return a.fare - b.fare;
  } else {    
    return b.totalTime - a.totalTime;  
  }
}

function cmpDepart(a,b) {  
  if(a.calcDepartTimeMin == b.calcDepartTimeMin) {
    return a.totalTime - b.totalTime;
  } else {
    return a.calcDepartTimeMin - b.calcDepartTimeMin; 
  }
}

var departSortedAscend = 0;

function cmpDepartAscend(a,b) {  
  if(a.calcDepartTimeMin == b.calcDepartTimeMin) {
    return a.totalTime - b.totalTime;
  } else {
    return a.calcDepartTimeMin - b.calcDepartTimeMin; 
  }
}

function cmpDepartDescend(a,b) {  
  if(b.calcDepartTimeMin == a.calcDepartTimeMin) {
    return a.totalTime - b.totalTime;
  } else {
    return b.calcDepartTimeMin - a.calcDepartTimeMin; 
  }
}

function cmpArrive(a,b) {  return a.calcArriveTimeMin - b.calcArriveTimeMin; }

var arriveSortedAscend = 0;

function cmpArriveAscend(a,b) {  
  if(a.calcArriveTimeMin == b.calcArriveTimeMin) {
    return a.totalTime - b.totalTime;
  } else {
    return a.calcArriveTimeMin - b.calcArriveTimeMin; 
  }
}
function cmpArriveDescend(a,b) { 
  if(a.calcArriveTimeMin == b.calcArriveTimeMin) {
    return a.totalTime - b.totalTime;
  } else {
    return b.calcArriveTimeMin - a.calcArriveTimeMin; 
  }
}

function cmpPrice(a,b) {  return a.fare - b.fare; }

var priceSortedAscend = 0;

function cmpPriceAscend(a,b) {  
  if(a.fare == b.fare) {
    return a.totalTime - b.totalTime;
  } else {
    return a.fare - b.fare; 
  }
}

function cmpPriceDescend(a,b) {  
  if(a.fare == b.fare) {
    return a.totalTime - b.totalTime;
  } else {
    return b.fare - a.fare; 
  }
}


function cmpMode(a,b) {  
  if (a.hops[0].mode > b.hops[0].mode) {
    return 1;
  } else if (a.hops[0].mode < b.hops[0].mode) {
    return -1; 
  } else {
    return 0;
  }
}

function sortMode() {
  $(".resultdiv").remove();
  $(".detail").remove();
  RESULTS.sort(cmpMode);
  resetSortDirection();
  totalSorts++;
  applyFilters(1);
}

function sortDuration() {
  $(".resultdiv").remove();
  $(".detail").remove();
  if(durationSortedAscend == 0) {
    resetSortDirection();
    durationSortedAscend = 1;
    RESULTS.sort(cmpDurationAscend);
  } else {
    durationSortedAscend = 0;
    RESULTS.sort(cmpDurationDescend);
  }
  totalSorts++;
  applyFilters(1);
}
function sortPrice() {
  $(".resultdiv").remove();
  $(".detail").remove();
  if(priceSortedAscend == 0) {
    resetSortDirection();
    priceSortedAscend = 1;
    RESULTS.sort(cmpPriceAscend);
  } else {
    priceSortedAscend = 0;
    RESULTS.sort(cmpPriceDescend);
  }
  totalSorts++;
  applyFilters(1);
}

function sortDepart() {
  $(".resultdiv").remove();
  $(".detail").remove();
  if(departSortedAscend == 0) {
    resetSortDirection();
    departSortedAscend = 1;
    RESULTS.sort(cmpDepartAscend);    
  } else {
    departSortedAscend = 0;
    RESULTS.sort(cmpDepartDescend);
  }
  totalSorts++;
  applyFilters(1);
}

function sortDefault() {
  $(".resultdiv").remove();
  $(".detail").remove();
  RESULTS.sort(cmpDefault);
  applyFilters(1);
}

function sortArrive() {
  $(".resultdiv").remove();
  $(".detail").remove();
  if(arriveSortedAscend == 0) {
    resetSortDirection();
    arriveSortedAscend = 1;
    RESULTS.sort(cmpArriveAscend);
  } else {
    arriveSortedAscend = 0;
    RESULTS.sort(cmpArriveDescend);
  }
  totalSorts++;
  applyFilters(1);
}

// Sorts will always be ascending, unless column is clicked successively
function resetSortDirection() {
  durationSortedAscend = 0;
  departSortedAscend = 0;
  arriveSortedAscend = 0;
  priceSortedAscend = 0;
}

function checkSortDirection() {
  if(totalSorts > 2) {
    totalSorts = 0;
    resetSortDirection();
  }
}

// Open details box or close details based on current state
function clickDetails(resultID) {
  if(activeDetail != resultID) {
    $("#details-" + activeDetail).hide();
    $("#details-" + resultID).show();
    activeDetail =  resultID;
    $(this).html("close");
  } else {
    $("#details-" + resultID).hide();
    $(this).html("details");
    activeDetail = "";
    if(waitingForRecalculate == 1) {
      $("#updates-header-update-needed").css("display","none");
      sortDefault();
      waitingForRecalculate = 0;
    }
  }
}

function closeDetails(resultID) {
  if(typeof resultID == 'undefined') {
    clearDetails();
  } else {
    $("a.details-link[rel="+resultID+"]").click();
    if(waitingForRecalculate == 1) {
      $("#updates-header-update-needed").css("display","none");
      sortDefault();
      waitingForRecalculate = 0;
    }
  }
}

function clearDetails() {
  $("#details-" + activeDetail).hide();
  activeDetail = "";
}

function excludeNodeHTML(nodeID)
{
	return "<div class=\"exclude-node-link\"><img src=\"" + baseURL + "css/images/x.gif\" align=\"absmiddle\" onclick=\"javascript:excludeNode(" + nodeID + ");\"/><a onclick=\"javascript:excludeNode(" + nodeID + ");\">Exclude station</a></div>";	
}

/*
function excludeNode(theNode)
{
	document.getElementById("hub-" + theNode).checked = false;
	applyFilters(0);
	window.scroll(0,0);
}
*/

function minorPriceColumnHTML(fare, getRide, taxiHTML) {
  var minorPriceColumnHTML = "";
  minorPriceColumnHTML += "<div class=\"col price-col\">";
  if(!getRide) {
    if(fare != 0) { minorPriceColumnHTML += "<p>$" + fare + "</p>"; }
    else          { minorPriceColumnHTML += "<p></p>"; }
    minorPriceColumnHTML += taxiHTML;
  }
  minorPriceColumnHTML += "</div>";
  return minorPriceColumnHTML;
}

function majorPriceColumnHTML(fare, agency) {
  var majorPriceColumnHTML = "";
  var agencyLink = baseURL + "main/buy/" + agency.replace(" ", "_");
  majorPriceColumnHTML += "<div class=\"col price-col\">";
  if(fare != -1) {
    majorPriceColumnHTML += "<p>$" + fare +"</p>";
    majorPriceColumnHTML += "<a href=\"" + agencyLink + "\" target=\"_blank\" class=\"buy-link\"></a>";
  } else {
    majorPriceColumnHTML += "<p class=\"small\"></p>";
    majorPriceColumnHTML += "<p class=\"small\">Transfer</p>";
  }
  majorPriceColumnHTML += "</div>";
  return majorPriceColumnHTML;
}

function taxiExcludeHTML(mode, origin, destination) {
  var taxiExcludeHTML = "";
  var originOrDest = (origin == 1) ? "origin" : "dest";
  if(mode == "taxi") {
    taxiExcludeHTML += "<div class=\"taxiBlurb\">Taxi too expensive?<br/>";
    taxiExcludeHTML += "<a onClick=\"taxiExclude('" + originOrDest + "');\">Exclude</a><br/>";
    taxiExcludeHTML += "<a onClick=\"enableGetRide(" + origin + "," + destination + ");\">Get a Ride</a><br/>";
    taxiExcludeHTML += "</div>";
  } else if(mode == "walk" || mode == "metro") {
    taxiExcludeHTML += "<div class=\"taxiBlurb\">Want taxi instead? <a onClick=\"taxiInclude('" + originOrDest + "');\"><nobr>Click Here</nobr></a></div>";
  }
  return taxiExcludeHTML;
}

function modeImageColumnHTML(mode, majorHop) {
  var modeImageColumnHTML = "";
  modeImageColumnHTML += "<div class=\"col mod-img-col\">";
  modeImageColumnHTML += "<p><img src=\"" + getModeImgURL(mode, majorHop) + "\"/></p>";
  modeImageColumnHTML += "</div>";
  return modeImageColumnHTML;
}

function modeColumnHTML(mode, agencyName, description, mapLink) {
  var modeColumnHTML = "";

  modeColumnHTML += "<div class=\"col mod-col\">";
  if(mode == "metro" || mode == "intracity") {
    modeColumnHTML += "<p><strong>Walk +</strong></p>";
  }
  if(mode == "metro") {
    modeColumnHTML += "<p class=\"" + mode + "-ico\"><strong>" + capFirst(mode) + "</strong></p>";
    modeColumnHTML += "<p><strong>" + agencyName + "</strong></p>";
  } else if(mode == "drive") {
    modeColumnHTML += "<p class=\"" + mode + "-ico\"><strong>Get A Ride</strong></p>";
  } else if(mode == "walk" || mode == "taxi") {
    modeColumnHTML += "<p class=\"" + mode + "-ico\"><strong>" + capFirst(mode) + "</strong></p>";
  } else {
    modeColumnHTML += "<p class=\"rail-ico\"><strong>" + agencyName + "</strong></p>";
  }
  if(description != "") {
    modeColumnHTML += "<p>" + description + "</p>";
  }
  if(mode != "bus" && mode != "rail") {
    modeColumnHTML += "<p><a href=\"" + mapLink + "\" target=\"_blank\">Map</a></p>";
  }
  modeColumnHTML += "</div>";

  return modeColumnHTML;
}

function departColumnHTML(formattedTime, mapLinkHTML, excludeNodeMarkup) {
  var departColumnHTML = "";
  departColumnHTML += "<div class=\"col depart-col\">";
  departColumnHTML += "<p><strong>" + formattedTime + "</strong>";
  departColumnHTML += mapLinkHTML + "</p>";
  departColumnHTML += excludeNodeMarkup;
  departColumnHTML += "</div>";
  return departColumnHTML;
}

function arriveColumnHTML(formattedTime, mapLinkHTML, excludeNodeMarkup, timeEstimated) {
  var arriveColumnHTML = "";
  arriveColumnHTML += "<div class=\"col arrive-col\">";
  arriveColumnHTML += "<p><strong>" + formattedTime + "</strong>";
  arriveColumnHTML += mapLinkHTML + "</p>";
  if(timeEstimated) { arriveColumnHTML += "<p>Estimated time</p>"; } // Arrival times are Approximate
  arriveColumnHTML += excludeNodeMarkup;
  arriveColumnHTML += "</div>";
  return arriveColumnHTML;
}

function timeColumnHTML(unformattedTime) {
  return "<div class=\"col time-col\"><p><strong>" + timeMinToFDuration(unformattedTime) + "</strong></p></div>";
}

function getNodeMapLink(nodeId, nodeText) {
  return "<a href=\"" + baseURL + "showmap/" + nodeId + "\" target=\"_blank\">" + nodeText + "</a>";
}

function getGMapLink(location) {
  return "<a href=\"http://maps.google.com/maps?q=" + location.replace("&", "%26") + "\" target=\"_blank\">" + location + "</a>";
}

function getGDirLink(mode, source, destination, departTime) {
  var gMapLinkBase = "http:\/\/maps.google.com\/maps?f=d&source=s_d";
  var gMapLink = gMapLinkBase;
  var modeFlag = (mode == "walk") ? "w" : "rB";
  gMapLink += "&saddr=" + source.replace("&", "%26");
  gMapLink += "&daddr=" + destination.replace("&", "%26");
  if(mode == "walk" || mode == "metro" || mode == "rail" || mode == "intracity") {
    gMapLink += "&dirflg=" + modeFlag + "&ttype=dep";
  }
  if(mode == "metro" || mode == "rail" || mode == "intracity") {
    var d_minutes = departTime % 100;
    var d_hours = (departTime - d_minutes) / 100;
    var d_ampm = d_hours > 11 ? "pm" : "am";
    if(d_hours == 0) { d_hours +=  12; };
    if(d_minutes < 10) { d_minutes = "0" + d_minutes; };
    gMapLink += "&time=" + d_hours + ":" + d_minutes + d_ampm;
  }
  gMapLink = gMapLink.replace("#", "%23");
  return gMapLink;
}

function buildOriginHop(originInfo, nodeInfo, departTime, prevDay) {
  var extraDay = (prevDay == 1) ? " (" + prevDow + ")" : "";
  var arriveTime = timeSubtractHHMM(nodeInfo.departTime, timeMinToHHMM(TIME_BUFFER));
  var destAddr = nodeInfo.sourceAddr1;
  var destLatLng   = nodeInfo.sourceLat + "," + nodeInfo.sourceLng;
  var destId = nodeInfo.sourceNodeId;
  var mode = (originInfo.getRide) ? "drive" : originInfo.mode;
  var originHTML = "";
  originHTML += "<div class=\"entry origin-entry\"><h2 class=\"notext\">origin</h2><div class=\"entry-c\">";
  originHTML += "<div class=\"row\">";
  originHTML += minorPriceColumnHTML(originInfo.fare, originInfo.getRide, taxiExcludeHTML(mode, 1, 0));	
  originHTML += modeImageColumnHTML(mode);
  originHTML += modeColumnHTML(mode, originInfo.description, "", getGDirLink(mode, sourceInput, destLatLng, departTime));		 
  originHTML += departColumnHTML(timeHHMMToFTime(departTime) + extraDay, getGMapLink(sourceInput), "");
  originHTML += arriveColumnHTML(timeHHMMToFTime(arriveTime), getNodeMapLink(destId, destAddr), excludeNodeHTML(nodeInfo.sourceNodeId), true);
  originHTML += timeColumnHTML(originInfo.time);
  originHTML += "<div class=\"cl\">&nbsp;</div></div></div><div class=\"cl\">&nbsp;</div></div>";
  return originHTML;
}


function buildIntercityHop(fare, mode, agency, routeName, departTime, arriveTime, totalTime, sourceId, sourceAddr, destId, destAddr) {
  var hopHTML = "";
  hopHTML += "<div class=\"entry intercity-entry\"><h2 class=\"notext\">intercity</h2>";
  hopHTML += "<div class=\"entry-c\">";
  hopHTML += "<div class=\"row\">";
  hopHTML += majorPriceColumnHTML(fare, agency);
  hopHTML += modeImageColumnHTML(mode, (mode == "intracity") ? null : 1);
  hopHTML += modeColumnHTML(mode, agency, routeName, getGDirLink(mode, sourceInput, destinationInput, departTime));
  hopHTML += departColumnHTML(
	      timeHHMMToFTime(departTime), 
	      (mode == "limo" || mode == "walk" || mode == "intracity" || mode == "taxi") ? getGMapLink(sourceAddr) : getNodeMapLink(sourceId, sourceAddr),
	      (mode == "limo" || mode == "walk" || mode == "intracity" || mode == "taxi") ? "" : excludeNodeHTML(sourceId));
  hopHTML += arriveColumnHTML(
		    timeHHMMToFTime(arriveTime),
		    (mode == "intracity" || mode == "limo" || mode == "walk" || mode == "taxi") ? getGMapLink(destAddr) : getNodeMapLink(destId, destAddr),
		    (mode == "intracity" || mode == "metro" || mode == "limo" || mode == "walk" || mode == "taxi") ? "" : excludeNodeHTML(destId),
		    (mode == "intracity" || mode == "metro" || mode == "limo" || mode == "walk" || mode == "taxi"));
  hopHTML += timeColumnHTML(timeHHMMToMin(totalTime));
  hopHTML += "<div class=\"cl\">&nbsp;</div></div></div><div class=\"cl\">&nbsp;</div></div>";  
  return hopHTML;
}

function buildTransfer(departTime, arriveTime, sourceId, sourceAddr, destId, destAddr) {
  //console.log("called buildTransfer");
  var transferHTML = "";
  var totalTime = timeMinToFDuration(timeHHMMToMin(arriveTime) - timeHHMMToMin(departTime));
  transferHTML += "<div class=\"entry\">";// intercity-entry\">";
  transferHTML += "<div class=\"entry-c\">";
  transferHTML += "<div class=\"row\">";
  transferHTML += "<div class=\"col price-col\">";
  transferHTML += "<p class=\"small\"></p>";
  transferHTML += "<p class=\"small\">Station Change</p>";
  transferHTML += "</div>";
  
  transferHTML += "<div class=\"col mod-col\">";
  transferHTML += "<p class=\"rail-ico\"><strong>";
  // transfer
  transferHTML += "</strong></p>";
  transferHTML += "</div>";
      
  transferHTML += departColumnHTML(timeHHMMToFTime(departTime), getNodeMapLink(sourceId, sourceAddr), excludeNodeHTML(sourceId));  
  transferHTML += arriveColumnHTML(timeHHMMToFTime(arriveTime), getNodeMapLink(destId, destAddr), excludeNodeHTML(destId), false);  
  transferHTML += timeColumnHTML(timeHHMMToMin(arriveTime) - timeHHMMToMin(departTime));

  transferHTML += "<div class=\"cl\">&nbsp;</div>";
  transferHTML += "</div>";
  transferHTML += "</div>";
  transferHTML += "</div>";
  
  return transferHTML;
}

function buildDestinationHop(destInfo, nodeInfo, arriveTime, nextDay) {
  var extraDay = (nextDay == 1) ? " (" + nextDow + ")" : "";
  var departTime = timeAddHHMM(nodeInfo.arriveTime, timeMinToHHMM(TIME_BUFFER));
  var sourceAddr = nodeInfo.destAddr1;
  var destId = nodeInfo.destNodeId;
  var mode = (destInfo.getRide) ? "drive" : destInfo.mode;
  var sourceLatLng = nodeInfo.destLat + "," + nodeInfo.destLng; 
  var destHTML = "";

  destHTML += "<div class=\"entry destination-entry\"><h2 class=\"notext\">destination</h2>";
  destHTML += "<div class=\"entry-c\">";
  destHTML += "<div class=\"row\">";    
  destHTML += minorPriceColumnHTML(destInfo.fare, destInfo.getRide, taxiExcludeHTML(mode, 0, 1));
  destHTML += modeImageColumnHTML(mode);
  destHTML += modeColumnHTML(mode, destInfo.description, "", getGDirLink(mode, sourceLatLng, destinationInput, departTime));
  destHTML += departColumnHTML(timeHHMMToFTime(departTime), getNodeMapLink(destId, sourceAddr), excludeNodeHTML(nodeInfo.sourceNodeId));
  destHTML += arriveColumnHTML(timeHHMMToFTime(arriveTime) + extraDay, getGMapLink(destinationInput), "", true);
  destHTML += timeColumnHTML(destInfo.time);
  destHTML += "<div class=\"cl\">&nbsp;</div></div></div><div class=\"cl\">&nbsp;</div></div>";
  return destHTML;
}

function capFirst(a_string) {
  return a_string.charAt(0).toUpperCase() + a_string.slice(1);
}

function setInputs(source, destination) {
  sourceInput = source;
  destinationInput = destination;
}

function setDayOfWeek(a_dow) {
  dayOfWeek = a_dow;
}

function setPrevAndNextDow(a_prevDow, a_nextDow) {
  prevDow = a_prevDow;
  nextDow = a_nextDow;
}

function enableGetRide(origin, dest) { 
  if(origin == 1) {
    $("#get-ride-origin").attr("checked",true);
    $("#mode-taxi-origin").attr("checked",false);
    $("#mode-walk-origin").attr("checked",false);
    $("#mode-metro-origin").attr("checked",false);
  }
  if(dest == 1) {
    $("#get-ride-dest").attr("checked",true);
    $("#mode-taxi-dest").attr("checked",false);
    $("#mode-walk-dest").attr("checked",false);
    $("#mode-metro-dest").attr("checked",false);
  }
  applyFilters();
}

function handleGetRide() { 
  var addFare = 0;
  var subtractFare = 0;
  var origin =  $("#get-ride-origin").attr("checked");
  var dest = $("#get-ride-dest").attr("checked");
  //alert("handleGetRide origin: " + origin + " dest: " + dest);
  for(var i = 0; i < RESULTS.length; i++) {
    subtractFare = 0;
    addFare = 0;
    if(RESULTS[i].origin.mode == "taxi" &&
       (RESULTS[i].origin.getRide != origin)) {
      // Enabling ride for origin
      if(origin) {
	subtractFare-=RESULTS[i].origin.fare;
	RESULTS[i].origin.getRide = 1;
      } else {
	// Disabling ride for origin
	addFare+=RESULTS[i].origin.fare;
	RESULTS[i].origin.getRide = 0;
      }
      
    }
    if(RESULTS[i].destination.mode == "taxi" &&
       (RESULTS[i].destination.getRide != dest)) { 
      if(dest) {
	// Enabling ride for dest
	subtractFare-=RESULTS[i].destination.fare;
	RESULTS[i].destination.getRide = 1; 
      } else {
	// Disabling ride for dest
	addFare+=RESULTS[i].destination.fare;
	RESULTS[i].destination.getRide = 0;
      }
    }
    RESULTS[i].fare += (addFare + subtractFare);
  }
  //applyFilters();
}

function buildHop(a_mode,
		  a_fare,
		  a_distance,
		  a_wifi,
		  a_power,
		  a_agency,
		  a_routeName,
		  a_departTime,
		  a_arriveTime,
		  a_totalTime,
		  a_sourceNodeId,
		  a_sourceAddr1,
		  a_sourceAddr2,
		  a_sourceCity,
		  a_sourceState,
		  a_sourceZip,
		  a_sourceLat,
		  a_sourceLng,
		  a_destNodeId,
		  a_destAddr1,
		  a_destAddr2,
		  a_destCity,
		  a_destState,
		  a_destZip,
		  a_destLat,
		  a_destLng,
		  a_updateRequest
		  ) {

  var hop = { 'mode' : a_mode,
	      'fare' : a_fare,
	      'distance' : a_distance,
	      'wifi' : a_wifi,
	      'power' : a_power,
	      'agency' : a_agency,
	      'routeName' : a_routeName,
	      'departTime' : a_departTime,
	      'arriveTime' : a_arriveTime,
	      'totalTime'  : a_totalTime,
	      'sourceNodeId' : a_sourceNodeId,
	      'sourceAddr1' : a_sourceAddr1,
	      'sourceAddr2' : a_sourceAddr2,
	      'sourceCity' : a_sourceCity,
	      'sourceState' : a_sourceState,
	      'sourceZip' : a_sourceZip,
	      'sourceLat' : a_sourceLat,
	      'sourceLng' : a_sourceLng,
	      'destNodeId' : a_destNodeId,
	      'destAddr1' : a_destAddr1,
	      'destAddr2' : a_destAddr2,
	      'destCity' : a_destCity,
	      'destState' : a_destState,
	      'destZip' : a_destZip,
	      'destLat' : a_destLat,
	      'destLng' : a_destLng,
	      'updateRequest' : a_updateRequest
  };
  return hop;
}

function addToQueryRequests(a_id, a_requestArray) {
  for(var i = 0; i < a_requestArray.length; i++) {
    updateRequests.push(getNewRequest(a_id, a_requestArray[i]));
  }
}

function addToResults(a_id, 
		      a_fare, 
		      a_departTime,
		      a_arriveTime, 
		      a_totalTime, 
		      a_layoverTime,
		      a_numHops,
		      a_origin,
		      a_destination,
		      a_hasQueryRequest,
		      a_hops) {
  var actualOriginTimeBuffer = (a_origin.mode == "none") ? 0 : TIME_BUFFER;
  var actualDestinationTimeBuffer = (a_destination.mode == "none") ? 0 : TIME_BUFFER;

  var actualDepartTime = timeMinToHHMM(timeHHMMToMin(a_departTime) - (actualOriginTimeBuffer + a_origin.time));
  var actualArriveTime = timeMinToHHMM(timeHHMMToMin(a_arriveTime) + (actualDestinationTimeBuffer + a_destination.time));

  var actualDepartTimeMin = timeHHMMToMin(a_departTime) - (actualOriginTimeBuffer + a_origin.time);
  var actualArriveTimeMin = timeHHMMToMin(a_arriveTime) + (actualDestinationTimeBuffer + a_destination.time);

  if(a_arriveTime < a_departTime) {
    actualArriveTimeMin += 1440;
  }

  RESULTS.push({   'id'         : a_id,
		   'fare'       : a_fare,
		   'departTime' : a_departTime,
		   'arriveTime' : a_arriveTime,
		   'calcDepartTime' : actualDepartTime,
		   'calcArriveTime' : actualArriveTime,
		   'calcDepartTimeMin' : actualDepartTimeMin,
		   'calcArriveTimeMin' : actualArriveTimeMin,
		   'totalTime'  : a_totalTime,
		   'layoverTime' : a_layoverTime,
		   'numHops'    : a_numHops,
		   'origin'     : a_origin,
		   'destination': a_destination,
		   'hops'       : a_hops,
		   'unavailable' : 0,
		   'badscrape'  : a_hasQueryRequest, // default?
		   'filtered'   : 0 });

}

function showDetails(a_id) {
  $("#details-" + a_id).toggle();

}

function sendUpdateRequest() {
  // updateRequests built in results view : contains list of hops that need updates
  if(DEBUG_RESULTS)
    console.log("results.js::starting thread for " + updateRequests.length + " updates");

  $("#num-results-waiting").html(updateRequests.length);

  updatePollingThread = setInterval(function() { requestUpdate(updateRequests); }, 2000);
  //requestUpdate(updateRequests);
}

function refreshResults() {
  $.post(baseURL + 'ajax/rescrape', function(data) { });
  clearInterval(updatePollingThread);
  updateState = STATE_DONE;  
  setTimeout(function() { updateState = STATE_IDLE; sendUpdateRequest(); }, 1000);
  $("#updates-header-finding").css("display","block");
  updateTimer = 0;
  clearTimeout(updateThread);
  updateThread = setInterval(function() { 
			       if(updateState == STATE_DONE ||
				  updateTimer > 20) {
				 $("#updates-header-finding").css("display","none");
				 // Force IE to Redraw
				 $(".main").attr("className", $(".main").attr("className"));
				 // FIXME: auto load updates?
				 loadUpdates();				 
				 // FIXME: wait for closed details box to redraw screen
				 sortDefault();
				 clearTimeout(updateThread);
			       }
			       updateTimer++;
			     }, 1500);

}

function displayResults(update) {  
  if(typeof update == 'undefined') {
    update = 0;
  }
  
  var buyAllLink = "";
  var resultHTML = "";
  totalResults = RESULTS.length;

  for(var i = 0; i < totalResults; i++) {
    if(RESULTS[i].filtered == 0) {
      var numHops = RESULTS[i].numHops;
      var departTime = timeMinToHHMM(RESULTS[i].calcDepartTimeMin);
      var arriveTime = timeMinToHHMM(RESULTS[i].calcArriveTimeMin);
      var prevDay = (RESULTS[i].calcDepartTimeMin < 0) ? " (" + prevDow + ")" : "";
      var nextDay = (RESULTS[i].calcArriveTimeMin > 1440) ? " (" + nextDow + ")" : "";

      resultHTML = "";
      resultHTML += "<div class=\"box resultdiv\" id=\"" + RESULTS[i].id +"\"><div class=\"box-t\"><div class=\"box-b\"><div class=\"cl\">&nbsp;</div>";
      resultHTML += "<div class=\"ticket\"><div class=\"left-side\">";
      if(RESULTS[i].badscrape == 1) {
	resultHTML += "<div class=\"badscrape-alert\">*</div>";
	resultHTML += "<h3 class=\"unconfirmed-fare\">$" + RESULTS[i].fare + "</h3>";
      } else {
	resultHTML += "<h3>$" + RESULTS[i].fare + "</h3>";
      }
      resultHTML += "<a class=\"select-link notext\" rel=\"" + RESULTS[i].id + "\">select</a></div>";
      resultHTML += "<div class=\"modes\">";
      if(RESULTS[i].hops.length < 2)
	resultHTML += "<br/>";
      for(var j = 0; j < numHops; j++) {
	if(j < 3) {
	  var agencyDisplay = RESULTS[i].hops[j].agency == 'mbta' ? RESULTS[i].hops[j].agency.toUpperCase() : capFirst(RESULTS[i].hops[j].agency);
	  resultHTML += "<p class=\"" + RESULTS[i].hops[j].mode + "-ico\">" + agencyDisplay + "</p>";
	}
      }
      resultHTML += "</div><div class=\"cl\">&nbsp;</div></div><div class=\"cl\">&nbsp;</div>";
      resultHTML += "<div class=\"cols\">";
      resultHTML += "<div class=\"col depart-col\"><h3>depart</h3><p class=\"arr\">" + RESULTS[i].hops[0].sourceCity + " " + timeHHMMToFTime(departTime) + prevDay + "</p></div>";
      resultHTML += "<div class=\"col arrive-col\"><h3>arrive</h3><p>" + RESULTS[i].hops[numHops-1].destCity + " " + timeHHMMToFTime(arriveTime) + nextDay +  "</p></div>";
      resultHTML += "<div class=\"col\"><h3>duration</h3>";
      resultHTML += "<p>" + timeHHMMToFDuration(RESULTS[i].totalTime) + "</p>";
      //if(RESULTS[i].layoverTime > 0) {
      //resultHTML += "<p class=\"small\">Layovers: " + timeMinToFDuration(RESULTS[i].layoverTime) + "</p>";
      //}
      resultHTML += "</div><div class=\"cl\">&nbsp;</div></div>";
      resultHTML += "<div class=\"actions\"><ul>";
      resultHTML += "<li><a class=\"details-link\" rel=\"" + RESULTS[i].id + "\">details</a></li>";
      resultHTML += "<li><a class=\"disable-link\">share</a></li>";
      resultHTML += "<li><a class=\"disable-link\">print</a></li>";
      if(DEBUG_RESULTS) {
	resultHTML += "<li><a class=\"disable-link\">" + RESULTS[i].id + "</a></li>";
      } else {
	resultHTML += "<li><a class=\"disable-link\">email</a></li>";
      }
      resultHTML += "</ul></div>";
      resultHTML += "<div class=\"cl\">&nbsp;</div></div></div>";
      
      // Details
      resultHTML += "<div class=\"detail pop-up\" id=\"details-" + RESULTS[i].id + "\">";
      resultHTML += "<div class=\"pop-up-t\">&nbsp;</div>";
      resultHTML += "<div class=\"pop-up-c\"><div class=\"pop-up-rel\"><h2>Your DOOR TO DOOR Itinerary</h2>";
      resultHTML += "<div class=\"close-details-div\"><a class=\"close-details\" rel=\"" + RESULTS[i].id + "\">close</a></div>";
      resultHTML += "<div class=\"info\">";

      if(RESULTS[i].origin.mode != "none")
      	resultHTML += buildOriginHop(RESULTS[i].origin, RESULTS[i].hops[0], departTime, (RESULTS[i].calcDepartTimeMin < 0));
      
      for(var j =0; j < numHops; j++) {
	var agencyDisplay = RESULTS[i].hops[j].agency == 'mbta' ? RESULTS[i].hops[j].agency.toUpperCase() : capFirst(RESULTS[i].hops[j].agency);    
	if(j == 0) {
	    buyAllLink = baseURL + "main/buy/" + agencyDisplay;
	}
	//console.log("results.js: building result: " + RESULTS[i].id + " hop" + j + " fare: " + RESULTS[i].hops[j].fare);
	resultHTML += buildIntercityHop(RESULTS[i].hops[j].fare, RESULTS[i].hops[j].mode, agencyDisplay, RESULTS[i].hops[j].routeName,
					RESULTS[i].hops[j].departTime, RESULTS[i].hops[j].arriveTime, RESULTS[i].hops[j].totalTime,
					RESULTS[i].hops[j].sourceNodeId, RESULTS[i].hops[j].sourceAddr1 + " " + RESULTS[i].hops[j].sourceCity , 
					RESULTS[i].hops[j].destNodeId, RESULTS[i].hops[j].destAddr1 + " " + RESULTS[i].hops[j].destCity);

	if(j < (numHops - 1)) {
	  if(RESULTS[i].hops[j].destNodeId != RESULTS[i].hops[j + 1].sourceNodeId) {
	    if(withinCart(RESULTS[i].hops[j].destLat, RESULTS[i].hops[j].destLng, 
			  RESULTS[i].hops[j+1].srcLat, RESULTS[i].hops[j+1].srcLng, 0.05) != -1) { // lat/lng
	      resultHTML += buildTransfer(RESULTS[i].hops[j].arriveTime, RESULTS[i].hops[j+1].departTime,
					  RESULTS[i].hops[j].destNodeId, RESULTS[i].hops[j].destAddr1 + " " + RESULTS[i].hops[j].destCity,
					  RESULTS[i].hops[j + 1].sourceNodeId, RESULTS[i].hops[j+1].sourceAddr1 + " " + RESULTS[i].hops[j+1].sourceCity);
	    }
	  }
	}
      }
      
      if(RESULTS[i].destination.mode != "none")
	resultHTML += buildDestinationHop(RESULTS[i].destination, RESULTS[i].hops[RESULTS[i].numHops-1], arriveTime, (RESULTS[i].calcArriveTimeMin > 1440));
      
      //resultHTML += "</div></div>";
      resultHTML += "<div class=\"info-bottom\">";

      if(airbnb == "") {
	resultHTML += "<h2>$" + RESULTS[i].fare + " - Total Fare</h2>";
	resultHTML += "<a href=\"" + buyAllLink + "\" class=\"buy-all notext\" target=\"_blank\">Open new windows to Buy All</a><div class=\"cl\">&nbsp;</div>";
      } else {
	resultHTML += "<a href=\"" + baseURL + "main/affiliate/airbnb/" + airbnb.url + "\" class=\"airbnb-link notext\" target=\"_blank\">AirBnB to " + airbnb.city + "</a><div class=\"cl\">&nbsp;</div>";

      }
      resultHTML += "</div></div></div>";
      resultHTML += "<div class=\"cl\">&nbsp;</div></div>";
      resultHTML += "<div class=\"pop-up-b\">&nbsp;</div></div></div>";
            
      $("#all-results").append(resultHTML);
    }
  }
  
	$('.ticket').each(function() {
		$(this).find('.left-side .badscrape-alert, .unconfirmed-fare').bt(
		'This provider\'s website currently is not returning fare and ticket availability information.<br/>This is the most recent fare for this trip that we\'re aware of, but it may have changed.',{
		  padding: 20,
		  width: 200,
		  spikeLength: 80,
		  spikeGirth: 20,
		  cornerRadius: 20,
		  fill: '#f0d9af',
		  strokeWidth: 3,
		  strokeStyle: '#7f7f7f',
		  cssStyles: {color: '#000', fontSize: '12px'},
		  
		shadow: true,
		shadowOffsetX: 3,
		shadowOffsetY: 3,
		shadowBlur: 8,
		shadowColor: 'rgba(0,0,0,.9)',
		shadowOverlap: false,
		noShadowOpts: {strokeStyle: '#999', strokeWidth: 2}
		});
	});
  
}


