/* looks after the waypoint list on the left of the page */

var letterArray = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];

var directionMarkers  = [];
var directionIds = [];
var directionCount = 0;

var orderedDirectionIds = [];

$(function() {
    $("#waypoints").sortable({
        placeholder: 'highlight', 
        axis: 'y',
        update: function(event, ui) {
          reOrderWayPoints();
          repaintRoute();
        }
    });
});

function addBlankWaypoint() {
    if(directionCount>23){
      return -1;
    }
    
    var index = directionMarkers.length;
    directionMarkers[index] = null;
    directionIds[index] = "waypoint" + index;
    directionCount++;
    
    var itemLabel = "";
    
    itemLabel = itemLabel + "<table><tr>";
    itemLabel = itemLabel + "<td width=\"26px\"><img id=\"waypointImg" + index + "\" class=\"waypoints_img\" height=\"26px\"  title=\"Click Icon, Then Click Map to Mark Destination\" onClick=\"toolWP(" + index + ")\" src=\"http://maps.google.ca/intl/en_ca/mapfiles/icon_green.png\"></td>";
    itemLabel = itemLabel + "<td class=\"waypointLbl\"><form action=\"javascript:waypointTextUpdated("+index+")\"><input type=\"text\" id=\"waypointLabel" + index + "\" title=\"Enter Location to Mark Destination\" onchange=\"waypointTextUpdated("+index+")\"></input></form></td>";
    itemLabel = itemLabel + "<td><img id=\"gasImg"+index+"\" onClick=\"showGas(" + index + ")\" title=\"Click to Show Gas Stations\" src=\"/images/maps/gas_pump_icon.gif\"></td>";
    itemLabel = itemLabel + "<td><table><tr><td><img onClick=\"moveUp('"+directionIds[index]+"')\" name=\"up\" title=\"Click to Move Up in List\" class=\"up_img\" src=\"/images/maps/up.jpg\"></td></tr>";
    itemLabel = itemLabel + "<tr><td><img onClick=\"moveDown('"+directionIds[index]+"')\" name=\"down\" title=\"Click to Move Down in List\" class=\"down_img\" src=\"/images/maps/down.jpg\"></td></tr></table></td>";
    itemLabel = itemLabel + "<td><img onClick=\"removeWaypoint(" + index + ")\" title=\"Click to Remove from List\" src=\"/images/maps/remove.jpg\"></td>";
    itemLabel = itemLabel + "</tr><tr><td colspan=\"5\"><div id=\"gas"+index+"\"></div></td></tr></table>";

    $(function() {
        $("<li id=\"waypoint" + index + "\">" + itemLabel + "</li>").appendTo( $("#waypoints") ) ;
    });
    
    reOrderWayPoints();
    
    return index;
}

function removeWaypoint(index) {
    $("#waypoint" + index).fadeOut("fast");
    $("#waypoint" + index).remove();
    
    if(directionMarkers[index]){
        map.removeOverlay(directionMarkers[index]);
        directionMarkers[index].setLatLng(null);
    }
    directionMarkers[index] = null;
    directionIds[index] = null;
    directionCount--;
    
    reOrderWayPoints();
    repaintRoute();
    
    
    var c =0;
    for(var i =0;i<directionMarkers.length;i++){
      if(directionMarkers[i] && directionMarkers[i].getLatLng()) c++;
    }

    document.getElementById("GetDirsButton").disabled = c<2;
}

function moveUp(currId) {
    var prev = $("#"+currId).prev().attr('id');
    $("#"+prev).insertAfter("#"+currId);
    reOrderWayPoints();
    repaintRoute();
};

function moveDown(currId) {
    var next = $("#"+currId).next().attr('id');
    $("#"+next).insertBefore("#"+currId);
    reOrderWayPoints();
    repaintRoute();
};

function labelWaypointFromLL(index){
  var geo_print_lbl = function(response) {
    var msg = "";
  
    // check for errors
    if (response.Status.code!=G_GEO_SUCCESS){
      switch (response.Status.code)
      { 
        case G_GEO_SERVER_ERROR:
        case G_GEO_MISSING_ADDRESS:
        case G_GEO_BAD_KEY: 
          msg = "Google Map Error";
          break;
        case G_GEO_UNKNOWN_ADDRESS:  
        default :
          msg = "Unknown address."
      }
    }else{
      // get a real location msg
      var place = response.Placemark[0];

      switch(place.AddressDetails.Accuracy)
      {
        case 9: // premise
        case 8: // address
        case 7: // intersection
        case 6: // street level
          if(place.AddressDetails.Country.AdministrativeArea){
            if(place.AddressDetails.Country.AdministrativeArea.Locality &&
                 place.AddressDetails.Country.AdministrativeArea.Locality.Thoroughfare){
               msg = place.AddressDetails.Country.AdministrativeArea.Locality.Thoroughfare.ThoroughfareName;
            }else{
              if(place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea && 
                  place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality && 
                  place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare){
	       	msg = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName;
              }
            }
          }
        case 5: // postal code
          // ignore postal code
        case 4: // town
        case 3: // sub-region
          if(place.AddressDetails.Country.AdministrativeArea){
            if(place.AddressDetails.Country.AdministrativeArea.Locality){
              if(msg == "")
                msg = place.AddressDetails.Country.AdministrativeArea.Locality.LocalityName;
              else
                msg = msg + ", "+place.AddressDetails.Country.AdministrativeArea.Locality.LocalityName;
            }else{
              if(place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea &&
                  place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality){
	        if(msg == "")
	          msg = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
	        else
	          msg = msg + ", "+place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
              }
            }
          }
          break;
        case 2: // region
        case 1: // country
          msg = directionMarkers[index].getLatLng().lat()+", "+directionMarkers[index].getLatLng().lng();
        case 0: // unknown
        default:
          // fall through
      }
      
    }

    var txt = document.getElementById("waypointLabel" + index);
    if(msg){
      txt.value = msg;
    }
    
  }; // end callback
   
  if(directionMarkers[index] && directionMarkers[index].getLatLng()){
    geocoder.getLocations(directionMarkers[index].getLatLng(),geo_print_lbl);
  }
}

function waypointTextUpdated(index){

  // need to geo-code the text if possible
  var txt = document.getElementById("waypointLabel" + index);
  if(txt && txt.value && txt.value != ""){
    
    var lbl_place_marker = function(point) {
      if(point){
        if(directionMarkers[index]){
          directionMarkers[index].setLatLng(point);
        }else{
          createWaypoint(index,point,true);
        }
        repaintRoute();
      }else{
        alert("Location not found for: "+txt);
      }
    };

    geocoder.getLatLng(txt.value,lbl_place_marker);
  }
}

function behindCampgrounds(marker,b){
  return GOverlay.getZIndex(marker.getPoint().lat()+1);
}

function createWaypoint(index, point, visible){
  if(visible){
    directionMarkers[index] = new GMarker(point,{draggable:true, 
    					  autoPan:false, 
    					  title:"Drag to Move Destination", 
    					  zIndexProcess:behindCampgrounds,
    					  clickable:false});
    					  
    directionMarkers[index].getIcon().shadow=null;
    // do not cluster
    map.addOverlay(directionMarkers[index]);
  }else{
    directionMarkers[index] = new GMarker(point,{draggable:false, autoPan:false, title:"Drag to Move Destination"});
    directionMarkers[index].hide();
  }

  // must set icon after adding overlay
  reOrderWayPoints();

  var c =0;
  for(var i =0;i<directionMarkers.length;i++){
    if(directionMarkers[index] && directionMarkers[index].getLatLng()) c++;
  }

  document.getElementById("GetDirsButton").disabled = c<2;
  
  if(visible){
    // This function deletes the marker when dragged outside map
    GEvent.addListener(directionMarkers[index], 'dragend', function(markerPoint){

      if(!map.getBounds().containsLatLng(markerPoint)){
        removeWaypoint(index);
      }else{
        if(directionMarkers[index].getLatLng())
          labelWaypointFromLL(index);
          repaintRoute();
      }
    });
        
    GEvent.addListener(directionMarkers[index], "singlerightclick", function() {
      contextMenu.showDestinationMenu(index);
    });
  
  }
}

function createKnownWaypoint(latlng, layer_index, site_id){
  
  var waypt_index = addBlankWaypoint();
  if(waypt_index>-1){
    createWaypoint(waypt_index,latlng,false);
    repaintRoute();
  
    // alter the image / link based on particular info
    if($('#waypointImg'+waypt_index)){
      
      $('#waypointImg'+waypt_index).attr('src',layers[layer_index][3]);
      $('#waypointImg'+waypt_index).attr('title',layers[layer_index][2]);
      $('#waypointImg'+waypt_index).attr('height',16);
      
           
      $('#waypointImg'+waypt_index).unbind('click');
      $('#waypointImg'+waypt_index).bind('click',function(){
	     showLayerMetadata(layers[layer_index][4]);
      });
      
    }
  
    // grab the 'td' tag around the image
    var lbl = document.getElementById("waypointLabel" + waypt_index).parentNode;
  
    var url = location.href;
    url = url.substring(0,url.lastIndexOf("/"));
    url = url + "/balloons.php?name="+gnames[layer_index].replace("&","%26") +"&id="+site_id;
  
    var process_it = function(doc) {
    if(doc){
      // Parse it
      var jsonData = eval('(' + doc + ')');
        lbl.innerHTML = "<a href=\""+jsonData.www+"\" onclick=\"javascript:pageTracker._trackPageview('/external/"+jsonData.www+"')\" target=\"_blank\">"+jsonData.name+"</a>";
      }
    }
    GDownloadUrl(url, process_it);
    
    $('#waypoint-href').click();
  }
}

// this only changes the icons ... the actual data structure remains unaltered
function reOrderWayPoints() {
    
    orderedDirectionIds = $('#waypoints').sortable('toArray');
    
    
    for(var i =0;i<orderedDirectionIds.length;i++){
      var index = -1;
      for(var j=0;j<directionIds.length && index<0;j++){
        if(directionIds[j] && directionIds[j] == orderedDirectionIds[i])
          index = j;
      }
    
      if(index > -1){
        if(directionMarkers[index]){
          if(!directionMarkers[index].isHidden()){
            // http://maps.google.ca/intl/en_ca/mapfiles/icon_green.png
            directionMarkers[index].setImage("http://maps.google.ca/intl/en_ca/mapfiles/icon_green" + letterArray[i] + ".png");
          }
        }
        
        var img = document.getElementById("waypointImg" + index);
        if(img){
          // leave marker labels alone
          if(img.src && img.src.match("http://maps.google.ca/intl/en_ca/mapfiles/icon_green") == "http://maps.google.ca/intl/en_ca/mapfiles/icon_green"){
            img.src = "http://maps.google.ca/intl/en_ca/mapfiles/icon_green" + letterArray[i] + ".png"
          }
        }
      }
    }
}

function repaintRoute(){  
    var waypoints = [];
    
    orderedDirectionIds = $('#waypoints').sortable('toArray');
    
    for(var i =0;i<orderedDirectionIds.length;i++){
      var index = -1;
      for(var j=0;j<directionIds.length && index<0;j++){
        if(directionIds[j] && directionIds[j] == orderedDirectionIds[i])
          index = j;
      }
        
      if(index > -1){
        if(directionMarkers[index]){
          waypoints[waypoints.length] = directionMarkers[index].getLatLng();
        }
      }
    }
    
    directions.clear();
    // re-paint route
    if(waypoints.length > 1){
      directions.loadFromWaypoints(waypoints,{
        preserveViewport: true
      });
    }
    
    clearGasImg();
    clearGasStations();
}

function clearDirectionMarkers(){
  var c = directions.getNumRoutes();
  if(c>0){
    // there is one more marker than there are routes
    for(var i =0;i<=c;i++){
      var marker = directions.getMarker(i);
      map.removeOverlay(marker);
    }
  }
}

/* direction control */

function getDirections(){
    orderedDirectionIds = $('#waypoints').sortable('toArray');
    
    var directions = "";
      
    for(var i =0;i<orderedDirectionIds.length;i++){
      var index = -1;
      for(var j=0;j<directionIds.length && index<0;j++){
        if(directionIds[j] && directionIds[j] == orderedDirectionIds[i])
          index = j;
      }
    
      if(index > -1){
        if(directionMarkers[index]){
          // add the ordinate
          if(directions != ""){
            directions += ":";
          }
          directions += directionMarkers[index].getLatLng().lat()+","+directionMarkers[index].getLatLng().lng();
        }
      }
    }
    
    var lang = $("#lang").attr('value');
    
    window.open("./directions.php?directions=" + directions + "&lang=" + lang, "directionswindow", "status=0,toolbar=0,location=0,menubar=0,scrollbars=1,width=760,height=700");
}

var currentMouseMoveListener = null;

function clearMarkerPlacement(){
    
    if(currentMouseMoveListener){
        GEvent.removeListener(currentMouseMoveListener);
        currentMouseMoveListener = null;
        
        // hard to clean up event chain below ... so leave the marker around
    }
}

function toolWP(index){
    var dog = true;
    var noMore = false;
    if(directionMarkers[index]) noMore = true;
    
    clearMarkerPlacement();
    
    var mouseMove = GEvent.addListener(map, 'mousemove', function(cursorPoint){

        if(!noMore){
            createWaypoint(index, cursorPoint, true);
            
            noMore = true;
            
        }
    
        if(dog){
            directionMarkers[index].setLatLng(cursorPoint);
        }
        
    }); // end listener
    currentMouseMoveListener = mouseMove;
    
    var mapClick = GEvent.addListener(map, 'click', function(){
    
        dog = false;
        // 'mousemove' event listener is deleted to save resources
        GEvent.removeListener(mouseMove);
        currentMouseMoveListener = null;
        currentIndex = null;
        
        GEvent.removeListener(mapClick);
        
        if(directionMarkers[index] && directionMarkers[index].getLatLng()){
            labelWaypointFromLL(index);
            repaintRoute();
        }
    
    });
}
