/******************************************************************************
 *
 *  Copyright 2008 David D. Emory [additional contributors append names here]
 *
 *  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_map.js
 *
 *  Javascript file containing fields and functions that support interaction
 *  with the map panel. Currently this functionality is written exclusively for
 *  the Google Maps API; support for other map APIs is planned for future
 *  versions.
 */

// FIELD DECLARATIONS

var fp_tMapIdTT_, fp_tMapIdNT_, fp_tMapIdNM_, fp_tMapIdSP_; // path IDs to pass to map server, one for each possible path type
var fp_tTransferPtsTT_, fp_tTransferPtsNT_, fp_tTransferPtsSP_; // arrays of transfer point names; used for annotation of map

var fp_tmapbxtt_, fp_tmapbytt_, fp_tmapbwtt_, fp_tmapbhtt_;
var fp_tmapbxnt_, fp_tmapbynt_, fp_tmapbwnt_, fp_tmapbhnt_;
var fp_tmapbxsp_, fp_tmapbysp_, fp_tmapbwsp_, fp_tmapbhsp_;

var fp_tmLastBounds_; // last used zoomTo() bounds
//
// FUNCTION DEFINITIONS

/**
 * fp_tShowTripMap(id)
 * 
 * Draws a specified trip planner result path on the map. The actual lat-lon
 * coordinates to draw are retrieved from the server via an ajax query. The 
 * numeric ID used to identify the path stored on the server is passed as the
 * sole parameter; this is typically extracted from the original XML-based trip
 * query response. 
 */
function fp_tShowTripMap(id) {

  var fields = "id="+id;
  fp_ajaxLoadAsXML("fp_trpact_gmap.php", fp_processGMapOverlayResponseXML, fields);

}

/**
 * fp_processGMapOverlayResponseXML(xmlDoc)
 * 
 * Alerts the client of a response to an ajax request sent by the above method.
 * This function then does the bulk of the work for decoding the response and
 * actually drawing the map overlay feature.
 *
 * For the structure of the XML response, see <dtd/fp_gmapoverlay.dtd>.
 */
function fp_processGMapOverlayResponseXML(xmlDoc) {

  var map = fp_GMap_;
  map.clearOverlays();
	
  var topNode = xmlDoc.documentElement;
  if(topNode.nodeName == "overlay") {
    var minx = 180, miny = 180, maxx = -180, maxy = -180;
    var segments = [];
    for(var i1 = 0; i1 < topNode.childNodes.length; i1++) {
      var sNode = topNode.childNodes.item(i1);
      if(sNode.nodeName == "segment") {
        var mode = sNode.getAttribute("mode");
        var points = [];
        for(var i2 = 0; i2 < sNode.childNodes.length; i2++) {
          var pNode = sNode.childNodes.item(i2);
          if(pNode.nodeName == "point") {
            var x = pNode.getAttribute("x");
            var y = pNode.getAttribute("y");
            if(x < minx) minx = x;
            if(y < miny) miny = y;
            if(x > maxx) maxx = x;
            if(y > maxy) maxy = y;
            points.push(new GLatLng(parseFloat(y),parseFloat(x)));
          }
        }
        var color = "#000000";
        if(mode == "walk") color = "#00ff00";
        if(mode == "lbus") color = "#0000ff";
        if(mode == "hrt") color = "#ff0000";
        //alert("overlay pts="+points);
        map.addOverlay(new GPolyline(points, color,6, .75));
        segments.push(points);
      }
    }

    for(var i = 0; i <= segments.length-2; i++) {
      var mhtml = "";
      //alert(activeTab_);
      if(fp_tCurTripType_ == "tt") mhtml = "<b>Transfer Point</b>: "+fp_tTransferPtsTT_[i]+"<br/><b>From</b>: "+segNamesTT_[i]+"<br/><b>To</b>: "+segNamesTT_[i+1];
      if(fp_tCurTripType_ == "nt") mhtml = "<b>Transfer Point</b>: "+fp_tTransferPtsNT_[i]+"<br/><b>From</b>: "+segNamesNT_[i]+"<br/><b>To</b>: "+segNamesNT_[i+1];
      if(fp_tCurTripType_ == "sp") mhtml = "<b>Transfer Point</b>: "+fp_tTransferPtsSP_[i]+"<br/><b>From</b>: "+segNamesSP_[i]+"<br/><b>To</b>: "+segNamesSP_[i+1];

      var tpoint = fp_tCreateTripMarker(segments[i][segments[i].length-1], mhtml, null, false);
      map.addOverlay(tpoint);
    }

    fp_tmCreateStartMarker(segments[0][0], fp_getStartFieldValue());
    fp_tmCreateEndMarker(segments[segments.length-1][segments[segments.length-1].length-1], fp_getEndFieldValue());
    
    var sw = new GLatLng(miny,maxx);
    //alert(sw);
    var ne = new GLatLng(maxy,minx);
    //alert(ne);
    fp_tmLastBounds_ = new GLatLngBounds(sw, ne);
    map.setCenter(fp_tmLastBounds_.getCenter(), map.getBoundsZoomLevel(fp_tmLastBounds_));
    fp_showTip("Click and drag start/endpoint marker to quickly adjust trip");
  }
  else {
    alert('There was a problem with the map overlay request.');
  }
}

function fp_tmGetBaseIcon() {
  var baseIcon = new GIcon();
  baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
  baseIcon.iconSize = new GSize(20, 34);
  baseIcon.shadowSize = new GSize(37, 34);
  baseIcon.iconAnchor = new GPoint(9, 34);
  baseIcon.infoWindowAnchor = new GPoint(9, 2);
  baseIcon.infoShadowAnchor = new GPoint(18, 25);
  return baseIcon;
}

var fp_tmStartMarker_, fp_tmEndMarker_;

function fp_tmCreateStartMarker(pt, locText) {
  if(fp_tmStartMarker_ != null) fp_GMap_.removeOverlay(fp_tmStartMarker_);
  var startIcon = new GIcon(fp_tmGetBaseIcon());
  startIcon.image = "http://www.google.com/mapfiles/dd-start.png";
  fp_tmStartMarker_ = fp_tCreateTripMarker(pt, "<b>Start</b>: "+locText, startIcon, true);
  GEvent.addListener(fp_tmStartMarker_, "dragend", function() {
    fp_makeNewEndpointRequest("start", fp_tmStartMarker_.getPoint().x, fp_tmStartMarker_.getPoint().y);
  });
  fp_GMap_.addOverlay(fp_tmStartMarker_);
}

function fp_tmCreateEndMarker(pt, locText) {
  if(fp_tmEndMarker_ != null) fp_GMap_.removeOverlay(fp_tmEndMarker_);
  var endIcon = new GIcon(fp_tmGetBaseIcon());
  endIcon.image = "http://www.google.com/mapfiles/dd-end.png";
  var fp_tmEndMarker_ = fp_tCreateTripMarker(pt, "<b>End</b>: "+locText, endIcon, true);
  GEvent.addListener(fp_tmEndMarker_, "dragend", function() {
    fp_makeNewEndpointRequest("end", fp_tmEndMarker_.getPoint().x, fp_tmEndMarker_.getPoint().y);
  });
  fp_GMap_.addOverlay(fp_tmEndMarker_);
}

/**
 * fp_tCreateTripMarker(..)
 * 
 * Utility function for creating a new point-based trip marker on the map --
 * either one of the two endpoints or a mid-path transfer point.
 * 
 * -- parameters --
 * point (GPoint): the location to draw the point 
 * html (String): content to be displayed in the mouse-click infobox
 * icon (GIcon) the graphical icon to represent the point
 * draggable (Boolean): whether or not the marker can be dragged by the mouse
 */
function fp_tCreateTripMarker(point, html, icon, draggable) {
  var marker = (icon == null) ? new GMarker(point, {
    draggable: draggable
  }) : new GMarker(point, {
    icon: icon,
    draggable: draggable
  });
  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml(html);
  });
  return marker;
}

/**
 * fp_makeNewEndpointRequest(..)
 * 
 * Initiates a new endpoint resolution request in response to an endpoint
 * marker being dragged to a new location by the user. Initiates an ajax
 * call to the nearbylocs PHP action. Uses a search radius of 500' by default.
 * 
 * -- parameters --
 * ptType (String): either "start" or "end"
 * x, y (Number): new point location in decimal degrees 
 */
function fp_makeNewEndpointRequest(ptType, x, y) {
  var fields = "x="+x+"&y="+y+"&r=500";
  
  if(ptType == "start") 
    fp_ajaxLoadAsXML("fp_trpact_nearbylocs.php", fp_alertNewStartLocation, fields);
  if(ptType == "end")
    fp_ajaxLoadAsXML("fp_trpact_nearbylocs.php", fp_alertNewEndLocation, fields);

}

/**
 * fp_alertNewStartLocation(xmlDoc)
 * 
 * Alerts the client of a response to an ajax request sent by the above method
 * for a new *start* location. If a valid nearby location was found, a full trip
 * request is then automatically dispatched.
 */
function fp_alertNewStartLocation(xmlDoc) {

  if(xmlDoc.documentElement.nodeName == "locations") {
    fp_processProximityResponseXML(xmlDoc);
    if(fp_proxLocCount_ == 0) alert("No locations found in the immediate proximity")
    else {
      fp_startLocSelFromMap(0);
      fp_makeTripRequest(1);
    }
  } else {
    alert('There was a problem with the nearby locs request.');
  }
}

/**
 * fp_alertNewEndLocation(xmlDoc)
 * 
 * Alerts the client of a response to an ajax request sent by the above method
 * for a new *end* location. If a valid nearby location was found, a full trip
 * request is then automatically dispatched.
 */
function fp_alertNewEndLocation(xmlDoc) {

  if(xmlDoc.documentElement.nodeName == "locations") {
    fp_processProximityResponseXML(xmlDoc);
    if(fp_proxLocCount_ == 0) alert("No locations found in the immediate proximity")
    else {
      fp_endLocSelFromMap(0);
      fp_makeTripRequest(1);
    }
  } else {
    alert('There was a problem with the nearby locs request.');
  }
}

function fp_tShowTopoGraph(id) {

}


