

var ajax = new Ajax();
var listener = Class.create();
var control;
var mapContainer = null;


var selectedDevice = -1;
var devices;
var findDevicesButton;
var cancelFindDevicesButton;
var deviceSelect;
var getDataButton;
var progressBarDisplay;
var progressBar;
var xmlDoc;
var uploadButton;
var numTracks;
var numWaypoints;
var mc;
var tracks;
var waypoints;
var map;
var factory;
var factory2;
var statusDiv;
var polylines = [];
var currTrackNum = 0;
var mapShown = false;
var findDiv;
  
listener.prototype = {
	initialize: function() {},
	
	onFinishFindDevices: function(json) {
		resetButtons(true);
        devices = json.controller.getDevices();
        setStatus("Found: " + devices.length + " device(s)");
        listDevices(devices);
     },

     onProgressReadFromDevice: function(json) {
		try {
        	updateProgressBar(json.progress.getPercentage());
        	setProgress(json.progress);
       	} catch(e) {}
     },

     onFinishReadFromDevice: function(json) {
        hideProgressBar();


        setStatus("Reading data...");
        Element.hide(document.getElementById('device-container'));
        Element.hide(document.getElementById('connect-container'));
        Element.show(document.getElementById('data-container'));
        var gpsData = json.controller.gpsData;


        factory = new Garmin.GpsDataFactory();
        factory2 = new Garmin.GpsDataFactory();
        factory.parseGpxDocument(gpsData);

		showMap();

        tracks = factory.getTracks();
        waypoints = factory.getWaypoints();

        // tracks
       var innerText = "";
       innerText += "<table width=100% class='data-table'>";
       if(tracks.length > 0) {
          innerText +="<tr><td colspan='4' align=center><b>Tracks</b></td></tr>";
          innerText +="<tr><td></td><td><b>Start time</b></td></td><td><b>Duration</b></td><td></td></tr>";
       }

       for(var i=0;i<tracks.length;i++) {
           var track = tracks[i];
           var startDate = track.getStartDate();

           if(startDate == null) {
             date = "unknown";
           } else {
             date = startDate + "";
             date = date.substring(0,15);
           }

           var duration = "unknown";
           try {
              duration = track.getDuration();
           } catch(e) {}

           innerText += addTrack(date,duration,i)
        }


       innerText += "</table><br><table width=100% class='data-table'>";

       if(waypoints.length > 0) {
          innerText +="<tr><td colspan='5' align=center><b>Waypoints</b></td></tr>";
          innerText +="<tr><td></td><td><b>Name</b></td><td><b>Latitude</b></td><td><b>Longitude</b></td><td></td></tr>";
       }

        for(i=0;i<waypoints.length;i++) {
           var waypoint = waypoints[i];
           var name = waypoint.getName();
           var lat = waypoint.getLat();

           var lon = waypoint.getLng();
           var date = waypoint.getDate();
		lat = Math.round(lat*10000)/10000;
		lon = Math.round(lon*10000)/10000;
           innerText += addWaypoint(name,lat,lon,i)
        }

       numTracks = tracks.length;
       numWaypoints = waypoints.length;

       innerText += "</table>";
       addText(innerText);

       if(waypoints.length + tracks.length == 0) {
          document.getElementById('device-info-text').innerHTML = "No data found";
       } else {
          document.getElementById('device-info-text').innerHTML += '<button type="button" name="sent" value="Submit" class="large-button-container" onclick="createTrip()">' +		
			'<div class="large-button" >' + 
				'<span class="text">Create Trip</span>' + 
		'	</div>' + 
		'</button>';
       }

        setStatus("");
     }
  }


function load() {

	// initialize buttons
 	findDevicesButton = document.getElementById('find-devices-button');
 	deviceSelect = document.getElementById('device-select');
   	getDataButton = document.getElementById('get-data-button');
	progressBarDisplay = document.getElementById('progress-bar-display');
    progressBar = document.getElementById('progress-bar');
  	uploadButton = document.getElementById('upload-button');
  	findDiv = document.getElementById('connect-container');

	
	try {
        control = new Garmin.DeviceControl();
		if(control.isPluginInitialized()) {
		}

     	if(control.unlock( unlockKey )) {
			control.register( new listener() );
      		control.unlock(unlockKey);
  			findDevices();
      	} else {
   			findDiv.innerHTML = "The plug-in was not unlocked successfully";
 		}
 	} catch(e) {
		findDiv.innerHTML += 'Error: you must first <a href="http://www.garmin.com/products/communicator/" target="_blank">Download the Garmin Communicator Plugin</a>';
 	}

	mc = new Garmin.MapController("map-container");
	mapContainer = document.getElementById("map-container");

  	deviceSelect.onchange = function() {
   		if(deviceSelect >= 0) {
         	var device = control.getDevices()[deviceSelect.value];
      		control.setDeviceNumber(deviceSelect.value);
    	}
   	}
}
  
  function findDevices() {
     setStatus("Finding devices...");
     resetButtons(false);
     control.findDevices();
  }

  function resetButtons(isTrue) {
     findDevicesButton.disabled = !isTrue;
  }
  
  function showProgressBar() {
    Element.show(progressBar);
  }
  function hideProgressBar() {
    Element.hide(progressBar);
  }
  
  function updateProgressBar(value) {
     var percent = (value <= 100) ? value : 100;
     progressBarDisplay.style.width = percent + "%";
  }

  function listDevices(devices) {
     for( var i=0; i < devices.length; i++ ) {
        deviceSelect.options[i] = new Option(devices[i].getDisplayName(),devices[i].getNumber());
        if(devices[i].getNumber() == control.deviceNumber) {
           deviceSelect.selectedIndex = i;
        }
     }

	
     document.getElementById('device-container').className = devices.length > 0 ? "" : "display-none";
     getDataButton.disabled = devices.length > 0 ? false : true;
     if(devices.length > 0) Element.hide(document.getElementById('connect-container'));

  }
  
  function setDevice(n) {
    selectedDevice = n;
  }
  
  function getData() {
    control.deviceNumber = deviceSelect.options[deviceSelect.selectedIndex].value;
    showProgressBar();
    control.readFromDevice();
  }
  
  function setStatus(status) {
     document.getElementById('status-text').innerHTML = status;
  }

  function setProgress(progress) {
     document.getElementById('progress-text').innerHTML = progress;
  }
  
  function addWaypoint(name,lat,lon,num) {
    // var xml = (new XMLSerializer()).serializeToString(xmlDoc.getElementsByTagName("wpt")[num]);
     var text = "";
     text +="<tr><td><input type='checkbox' id='waypoint"+num+"' name='waypoints[]' value=''></td>";
     text +="<td>" + name + "</td>";
     text +="<td>" + lat + "</td>";
     text +="<td>" + lon + "</td>";
     text +="<td><a href='javascript:preview(\"waypoint\","+num+")'>preview</a></td></tr>";
     return text;
  }
  
  function addTrack(date,duration,num) {
    // var xml = (new XMLSerializer()).serializeToString(xmlDoc.getElementsByTagName("trk")[num]);
     var text = "";
     text +="<tr><td><input type='checkbox' id='track"+num+"' name='tracks[]' value=''></td>";
     text +="<td>" + date + "</td>";
     text +="<td>" + duration + "</td>";
     text +="<td><a href='javascript:preview(\"track\","+num+")'>preview</a></td></tr>";
     return text;
  }

  function formatDate(date) {
    return date.substring(0,10) + " " + date.substring(11,19);
  }
  
  function checkSelected() {
    var isData = false;
     for(var i=0; i<numTracks; i++) {
        if(document.getElementById('track'+i).checked) {
           document.getElementById('track'+i).value = factory2.produceTrackGpxString(tracks[i]);

           isData = true;
        }
     }
     
     for(var i=0; i<numWaypoints; i++) {
        if(document.getElementById('waypoint'+i).checked) {
           document.getElementById('waypoint'+i).value = factory2.produceWaypointGpxString(waypoints[i]);

           isData = true;
        }
     }
     return isData;
  }

  function createTrip() {
     if(checkSelected()) {
        document.form.submit();
     } else {
       alert("You must select at least 1 waypoint or track to create a trip");
     }
  }
  
  function showMap() {
	Element.show('map-container');
	
	mapContainer.className = "map-container";
	loadMap(mapContainer, getMapFromName("Hybrid"));	
  }
  
  function preview(type,id) {
     if(type == "track") {
       showTrack(id);
     } else {
       showWaypoint(id);
     }
  }

  function parseXML(xml) {
     try { //Internet Explorer
        xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async="false";
        xmlDoc.loadXML(xml);
     } catch(e) {
        try { //Firefox, Mozilla, Opera, etc.
           parser=new DOMParser();
           xmlDoc=parser.parseFromString(xml,"text/xml");
        } catch(e) {
           alert(e.message);
           return;
        }
     }
    var innerText = "";

    
    // tracks
    var tracks = xmlDoc.getElementsByTagName("trk");
    innerText += "<table width=100% class='panelblue'>";
    if(tracks.length > 0) {
       innerText +="<tr><td colspan='4' align=center><b>Tracks</b></td></tr>";
       innerText +="<tr><td></td><td><b>Track name</b></td><td><b>Start time</b></td><td></td></tr>";
    }

    for(var i = 0; i < tracks.length; i++) {
       name = xmlDoc.getElementsByTagName("trk")[i].childNodes[1].childNodes[0].nodeValue;
       date = xmlDoc.getElementsByTagName("trk")[i].childNodes[5].childNodes[1].childNodes[3].childNodes[0].nodeValue;
       innerText += addTrack(name,formatDate(date),i);
    }

    // waypoints
    var wpts = xmlDoc.getElementsByTagName("wpt");
    innerText += "</table><br><table width=100% class='panelblue'>";

    if(wpts.length > 0) {
       innerText +="<tr><td colspan='5' align=center><b>Waypoints</b></td></tr>";
       innerText +="<tr><td></td><td><b>Name</b></td><td><b>Latitude</b></td><td><b>Longitude</b></td><td></td></tr>";
    }

    for(var i = 0; i < wpts.length; i++) {
       name = xmlDoc.getElementsByTagName("wpt")[i].childNodes[3].childNodes[0].nodeValue;
       lat = xmlDoc.getElementsByTagName("wpt")[i].attributes[0].nodeValue;
       lon = xmlDoc.getElementsByTagName("wpt")[i].attributes[1].nodeValue;
		lat = Math.round(lat*10000)/10000;
		lon = Math.round(lon*10000)/10000;
       innerText += addWaypoint(name,lat,lon,i);
    }
    
    numTracks = tracks.length;
    numWaypoints = wpts.length;

    innerText += "</table>";
    addText(innerText);

    if(wpts.length + tracks.length == 0) {
       document.getElementById('device-info-text').innerHTML = "No data found";
    } else {
       document.getElementById('device-info-text').innerHTML += '<input type="button" name="sent" onclick="createTrip()" value="Create Trip" class="buttonOrange" id="uploadButton">'
    }

  }
  
  function simplifyTrack(track) {
     var gpx = "<gpx>" + factory.produceTrackGpxString(track) + "</gpx>";
     removeLoadingDiv();
     addLoadingDiv("Loading...");
     ajax.abort();
     
     ajax.doPost("/simplify_track.php", "gpx="+gpx, simplifyTrackResponse,"text");
  }
  
  function simplifyTrackResponse(xml) {
    removeLoadingDiv();
    factory2.parseGpxString(xml);
    var tracks2 = factory2.getTracks();
    
    drawTrack(tracks2[0]);
  }
  function addLoadingDiv(message) {
     var mapContainer = document.getElementById('map-container');

     statusDiv = document.createElement('div');
     statusDiv.id = 'statusDiv';

     messageWidth = 120;
     messageHeight = 20;

     mapWidth = 500
     mapHeight = 400;


     leftPos = (mapWidth-messageWidth)/2;
     topPos = (mapHeight-messageHeight)/2;

	statusDiv.className = "map-status-container";

     statusDiv.style.left = leftPos+'px';
     statusDiv.style.top = topPos+'px';
     statusDiv.style.width = messageWidth + "px";
     statusDiv.style.height = messageHeight + "px";

     statusDiv.innerHTML = "<font size=+0>"+message+"</font>";

     mapContainer.appendChild(statusDiv);
  }

  function removeLoadingDiv() {
     if(statusDiv) {
        document.getElementById('map-container').removeChild(statusDiv);
     }
     statusDiv = null;
  }

  function drawTrack(track) {
     var bounds = new GLatLngBounds();
     var pt;
     var lat;
     var lon;
     var points = [];
     var delta;

     for(i=0; i<track.getNumSegments(); i++) {
        seg = track.getSegment(i);
        delta = Math.ceil(seg.getLength() / 300);
        for(var j=0; j<seg.getLength(); j+= delta) {
           pt = seg.getPoint(j);
           lat = parseFloat(pt.getLat());
           lon = parseFloat(pt.getLng());
           latlng = new GLatLng(lat,lon);
           points.push(latlng);
           bounds.extend(latlng);

        }
     }

     var polyline = new GPolyline(points,"#FF0000",2,1);
     map.clearOverlays();
     var zoom = map.getBoundsZoomLevel(bounds);
     var center = bounds.getCenter()
     map.setCenter(center,zoom);
     map.addOverlay(polyline);
     polylines[currTrackNum] = polyline;

  }



  function showTrack(num) {
     currTrackNum = num;
     if(polylines[num]) {
        map.clearOverlays();
        var polyline = polylines[num];
        var bounds = polyline.getBounds();
        var zoom = map.getBoundsZoomLevel(bounds);
        var center = bounds.getCenter()
        map.setCenter(center,zoom);
        map.addOverlay(polyline);
     } else {

        var track = tracks[num];
        var n = 0;
        for(var i=0; i<track.getNumSegments(); i++) {
           seg = track.getSegment(i);
           n += seg.getLength();
        }

        if(n > 400) {
           simplifyTrack(track);
        } else {
           drawTrack(track);
        }
     }
  }
  
  function showWaypoint(num) {
     var waypoint = waypoints[num];
     map.clearOverlays();
     var pt = new GLatLng(waypoint.getLat(), waypoint.getLng());
     var marker = new GMarker(pt);
     map.addOverlay(marker);
     map.setCenter(pt,14);
  }


  function addText(text) {
    document.getElementById('device-info-text').innerHTML += text;
  }


jQuery(document).ready(function() {

	load();
});

