//google.load("maps", "3")  ;
		var layers = {
			route : [],
			elevation : [],
			roadType : [],
			routeMarkers : [],
			waypoints : [[]]
		}	

		var colors = {
			route: 	
				{ 
					'colors' : ['#0000FF', '#FF0000'],
					'thickness' : '7', 
					'opacity' : '0.7' 
				},
			roadType: 
				{ 
					'colors' : {'Class1' : '#339900', 'Class2' : '#FF0000', 'Class3' : '#CC9900', 'None' : '#888888'},
					'thickness' : '7', 
					'opacity' : '0.7' 
				},
			elevation: 	
				{ 
					'colors' : ['#000086', '#0000CB', '#0000FF', '#007D8D', '#007D00', '#8D7D00', '#FF0000', '#CB0000', '#860000'],
					'thickness' : '7', 
					'opacity' : '0.7' 
				}


			
			
		}

		var editMode = false;

// Call this function when the page has been loaded
	function initialize() {
//		var myOptions = {
//			zoom: 12,
//			center: new google.maps.LatLng(40.749988,-74.000988),
//			mapTypeId: google.maps.MapTypeId.ROADMAP,
//			navigationControl: true,
//			scaleControl: true,
				   
//		}
		var mapOptions = {
			googleBarOptions : {
				style : "new",
				adsOptions: {
					client: "pub-0077572760990687",
					channel: "7718259730",
					adsafe: "high",
					language: "en"
				}
			}
		}

		var map = new GMap2(document.getElementById("map"), mapOptions);
		var mgrOptions = { maxZoom: 5};
		var markerMgr = new GMarkerManager(map);

		
		map.setCenter(new GLatLng(40.749988,-74.000988), 12);
		var mapControl = new GMapTypeControl();
		map.addControl(mapControl);
		map.addControl(new GLargeMapControl());
       		map.enableGoogleBar(); 
	
		function addSegmentPoint(trk, i) {
			var point = ride['tracks'][trk]['segments'][0]['points'][i];
			var coor = new GLatLng(point['lat'], point['lon']);
		
			if(point['deleted'])
				return null;

			var f = new GIcon();
			if(trk == 0)
				f.image = "http://labs.google.com/ridefinder/images/mm_20_green.png";
			else
				f.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
			f.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
			f.iconSize = new GSize(12,20);
			f.shadowSize = new GSize(22,20);
			f.iconAnchor = new GPoint(6,20);
			f.infoWindowAnchor = new GPoint(6,1);
			f.infoShadowAnchor = new GPoint(13,13);
			
			var marker = new GMarker(coor, {icon : f, draggable : true});
			
			GEvent.addListener(marker, "click", function() {
				// alert(i  + " " + coor);
			});


			
			GEvent.addListener(marker, "dblclick", function() {
				this.hide();
				point['deleted'] = 'true';
			});
			
			GEvent.addListener(marker, "dragend", function(latlng) {
				point['lat'] = latlng.lat();
				point['lon'] = latlng.lng();
			});

			GEvent.addListener(marker, "mouseover", function(latlng) {
				
				point['lat'] = latlng.lat();
				point['lon'] = latlng.lng();

				edit = document.getElementById("edit");
				html = "<p>Point #: " + i + "</p><br>";
				edit.innerHTML = html;
			});



			//segMarkers.push(marker);
			if(editMode)
				map.addOverlay(marker);
			
			return [coor, marker];
	    	}          

		var points = []
		layers['routeMarkers'][0] = [];
		for(i=0;i<ride['tracks'][0]['segments'][0]['points'].length;i++) {
			segPoint = addSegmentPoint(0, i);
			if(segPoint) {
				points.push(segPoint[0])
				layers['routeMarkers'][0].push(segPoint[1]);
			}	
		}
		
		//markerMgr.addMarkers(segMarkers);
		//markerMgr.refresh();
		//alert(markerMgr.getMarkerCount());
		

		
		var lineThickness = colors['route']['thickness']; // pixels
		var lineColor = colors['route']['colors'][0]; // blue
		var lineOpacity = colors['route']['opacity'];
		var poly = new GPolyline(points, lineColor, lineThickness, lineOpacity);
     		map.addOverlay(poly);	// edge is blue
		layers['route'][0] = [poly];

		var points = []
		layers['routeMarkers'][1] = [];
		for(i=0;i<ride['tracks'][1]['segments'][0]['points'].length;i++) {
			segPoint = addSegmentPoint(1, i);
			if(segPoint) {
				points.push(segPoint[0])
				layers['routeMarkers'][1].push(segPoint[1]);
			}	
		}
			
		var lineThickness = colors['route']['thickness']; // pixels
		var lineColor = colors['route']['colors'][1]; // blue
		var lineOpacity = colors['route']['opacity'];
		var poly = new GPolyline(points, lineColor, lineThickness, lineOpacity);
     		map.addOverlay(poly);	// edge is blue
		layers['route'][1] = [poly];

	

		// adding bike type layer
		//for(i=0;i<ride['tracks'][1]['segments'][0]['points'].length;i++) {
		//	roadType = ;
		//	p
			
		


		// adding waypoints
		function addWaypoint(i) {
			
			// creating custom markers
			var cameraIcon = new GIcon();
			var alertIcon = new GIcon();
			var startIcon = new GIcon();
			var endIcon = new GIcon();
			
			
			cameraIcon.image = "/wp-includes/images/markers/camera.png";
			cameraIcon.shadow = "/wp-includes/images/markers/camera.shadow.png";
//			cameraIcon.iconSize = new GSize(12,20);
//			cameraIcon.shadowSize = new GSize(22,20);
			cameraIcon.iconAnchor = new GPoint(15,15);
			cameraIcon.infoWindowAnchor = new GPoint(15,15);
//			cameraIcon.infoShadowAnchor = new GPoint(0,0);

			alertIcon.image = "/wp-includes/images/markers/caution.png";
			alertIcon.shadow = "/wp-includes/images/markers/caution.shadow.png";
//			cameraIcon.iconSize = new GSize(12,20);
//			cameraIcon.shadowSize = new GSize(22,20);
			alertIcon.iconAnchor = new GPoint(15,15);
			alertIcon.infoWindowAnchor = new GPoint(15,15);
//			cameraIcon.infoShadowAnchor = new GPoint(0,0);

			startIcon.image = "http://www.google.com/mapfiles/dd-start.png";
			startIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
			startIcon.iconAnchor = new GPoint(20,17);
			endIcon.image = "http://www.google.com/mapfiles/dd-end.png";
			endIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
			endIcon.iconAnchor = new GPoint(20,17);
			

		
			var pt = ride['waypoints'][i];
			var coor = new GLatLng(pt["lat"], pt["lon"]);
			var icon = null;

			function zindex(marker,b) {
				return 100;
			}
			function zindexdefault(marker,b) {
				return 0; 
			}
			
			var zindexfunc = zindexdefault;
		
			if(pt['type'] == "Image")
				icon = cameraIcon;
			else if(pt['type'] == "Alert")
				icon = alertIcon;
			else if(pt['type'] == "Start") {
				zindexfunc = zindex;	
				icon = startIcon;
			}	
			else if(pt['type'] == "End")
				icon = endIcon;

			var marker = new GMarker(coor, {icon : icon, zIndexProcess:zindexfunc});
			var caption = pt["caption"]? "<br/><b>" + pt["caption"] + "<b>" : "";
			marker.bindInfoWindowHtml("<div style='width:240px ; height:240px'><img src='" + pt["url_small"] + "'/>" + caption + "</div>")
			pt['marker'] = marker; 
			//GEvent.addListener(marker, "click", function() {
			//});
			return marker;
		}
	
		// going over the points array and creating polygons
		// from a group of sequential points with the same value
		// for the input property.
		// returns the following datastructure:
		// 'polygons' : array of arrays of points. Each one corresponds to a sequential propetry value
		// 'values' : array of values that correspond to the 'polygons' array
		function createSamePropertyPolygons(points, prop) {
			var ret = { 'polygons' : [], 'values' : [] };
			var lastPointVal = points[0][prop];
			var currGroup = [new GLatLng(points[0]['lat'], points[0]['lon'])];
			ret['values'].push(lastPointVal);
			for(var i=1;i<points.length;i++) {
				currPointVal = points[i][prop];
				point = new GLatLng(points[i]['lat'], points[i]['lon']);
				currGroup.push(point) // adding this point to the current polygon group
				if(currPointVal != lastPointVal) { // adding the last group to the return array and starting a new group
					ret['polygons'].push(currGroup);
					currGroup = [point];
					ret['values'].push(currPointVal);
					lastPointVal = currPointVal;
				}
			}

			//inserting the last group
			ret['polygons'].push(currGroup);
			
			return ret;
		}


		function addRoadTypeOverlays(trackNum) {
			layers['roadType'][trackNum] = [];
			points = ride['tracks'][trackNum]['segments'][0]['points'];
			roadTypes = createSamePropertyPolygons(points, "roadType");
			roadTypesColors = {'Class1' : '#339900', 'Class2' : '#FF0000', 'Class3' : '#CC9900', 'None' : '#888888'}
			for(j=0;j<roadTypes['polygons'].length;j++) {
				var lineThickness = colors['roadType']['thickness']; // pixels
				var lineOpacity = colors['route']['opacity'];
				var lineColor =  colors['roadType']['colors'][roadTypes['values'][j]];
				var poly = new GPolyline(roadTypes['polygons'][j], lineColor, lineThickness, lineOpacity);
				map.addOverlay(poly);
				layers['roadType'][trackNum].push(poly);
			}

		}
	
	

		function createElevationGroups(points, resolution, eleSrc){
			var ret = { 'groups' : [], 'values' : [] };
			var lastPointVal = points[0]['elevationGrade'][eleSrc];
			var lastBucket = (lastPointVal / resolution) | 0 ;
			var currGroup = [new GLatLng(points[0]['lat'], points[0]['lon'])];
			ret['values'].push(lastBucket);
			for(var i=1;i<points.length-1;i++) {
				currPointVal = points[i]['elevationGrade'][eleSrc];
				currBucket = (currPointVal / resolution) | 0 ;

				//console.log(points[i]['elevationGrade'][eleSrc] + " ---- " + currBucket);
				point1 = new GLatLng(points[i]['lat'], points[i]['lon']);
				point2 = new GLatLng(points[i+1]['lat'], points[i+1]['lon']);
				currGroup.push(point1); // adding this point to the current polygon group
				if(lastBucket != currBucket) { // adding the last group to the return array and starting a new group
					ret['groups'].push(currGroup);
					currGroup = [point1, point2];
					ret['values'].push(currBucket);

					//console.log(currBucket);
					lastBucket = currBucket;
				}
			}

			//inserting the last group
			ret['groups'].push(currGroup);
			
			return ret;

		}
		

		function addElevationOverlays(trackNum) {
			layers['elevation'][trackNum] = [];
			var elevationBuckets = [-10, -5, -2, -1, 0, 1, 2, 5, 10];
			points = ride['tracks'][trackNum]['segments'][0]['points'];
			elevationGroups = createElevationGroups	(points, 1, "HeyWhatsThat");
			for(var j=0;j<elevationGroups['groups'].length;j++) {
				if(elevationGroups['values'][j] < elevationBuckets[0])
					color = colors['elevation']['colors'][0];
				
				for(k=0;k<elevationBuckets.length-1;k++) {
					if(elevationGroups['values'][j] > elevationBuckets[k] && elevationGroups['values'][j] <= elevationBuckets[k+1]) {
						color = colors['elevation']['colors'][k];
						break;
					}
				}
				
				if(elevationGroups['values'][j] > elevationBuckets[elevationBuckets.length-1])
					color = colors['elevation']['colors'][elevationBuckets.length-1];
					
				
					
				var lineThickness = 8;
				var lineColor = color;
				var lineOpacity = 1;
		
//				console.log(elevationGroups['values'][j] + " -- " + color);
			
				var poly = new GPolyline(elevationGroups['groups'][j], color, lineThickness, lineOpacity);
				map.addOverlay(poly);
				layers['elevation'][trackNum].push(poly);
			}
		}

		
		// creating the roadType polygons and adding to the layers
		for(var i=0;i<ride['tracks'].length;i++) {
			addRoadTypeOverlays(i);
			addElevationOverlays(i);
		}




		for(var i=0; i < ride['waypoints'].length; i++) {
			var mrkr = addWaypoint(i);
			layers['waypoints'][0].push(mrkr)
			map.addOverlay(mrkr);
		}
		

	}        

	function toggleLayer(setVisible, type, trackNum) {
		var overlays = layers[type][trackNum];
		if(setVisible) {
			for(i in overlays)
				overlays[i].show();
		}
		else {
			for(i in overlays)
				overlays[i].hide();
		}
	}

	function hideAllOverlays() {
		toggleLayer(false, 'route', 0);
		toggleLayer(false, 'route', 1);
		toggleLayer(false, 'elevation', 0);
		toggleLayer(false, 'elevation', 1);
		toggleLayer(false, 'roadType', 0);
		toggleLayer(false, 'roadType', 1);
		toggleLayer(false, 'routeMarkers', 0);
		toggleLayer(false, 'routeMarkers', 1);
	}		
	
	function updateMap() {
		hideAllOverlays();
		var mapControl = document.getElementById("mapControl");	
		for (var i=0; i < mapControl.layer.length; i++) {
			if (mapControl.layer[i].checked) {
				for (var j=0; j < mapControl.routes.length; j++) {
					if(mapControl.routes[j].checked)	
						window.toggleLayer(true, mapControl.layer[i].value, j);
//						alert(j + " " + document.mapControl.layer[i].value);
				}
			}
			
		}
		
	}

		
	function d2h(d) {
	
		ret =  d.toString(16);
		if(ret.length==1)
			ret = '0' + ret;
		return ret
	}

	function meter2ft(m) {
		return Math.round(meters * 3.281);
	}
	
	function meter2mile(m) {
		return Math.round(meters * 0.000621);
	}


	function sendData() {
		var url = "http://www.bikingnyc.com/getdata.php" ;
		var request = YAHOO.util.Connect.asyncRequest('POST', url, null, 'ride=' + JSON.stringify(ride)); 
	}	

// google.setOnLoadCallback(initialize);
var $j = jQuery.noConflict();
$j(document).ready(function(){
	initialize();
	updateMap();
});
