
/* ---------------------------------------------------------------------------
 * Waypoint Object
 */
var Waypoint = Class.create({
	
	MAP_CENTER_ZOOM: 14,
	
	initialize: function(json_wpt, map) {
		this.lat					= json_wpt.lat;
		this.lon					= json_wpt.lon;
		this.name					= json_wpt.name;
		this.ele					= json_wpt.ele;
		this.time					= json_wpt.time;
		this.cmt					= json_wpt.cmt;
		this.desc					= json_wpt.desc;
		this.sym					= json_wpt.sym;
		
		
		this.gicon					= new GIcon();
		this.gicon.image			= this.sym;
		this.gicon.shadow			= null;
		this.gicon.iconSize			= new GSize(20, 20);
		this.gicon.shadowSize		= null;
		this.gicon.iconAnchor		= new GPoint(10, 10);
		this.gicon.infoWindowAnchor	= new GPoint(10, 4);
		
		this.markerOptions			= {title: this.name, icon: this.gicon};
		
		this.gmarker				= new GMarker(new GLatLng(this.lat,
																this.lon),
													this.markerOptions);
		
		/* Need wpt for closure */
		var wpt = this;
		
		GEvent.addListener(wpt.gmarker,
							"click",
							function () {
								if (wpt.gmarker.infoWindowOpen) {
									wpt.gmarker.closeInfoWindow();
								} else {
									wpt.showInfoWindow();
								}
							});
		GEvent.addListener(wpt.gmarker,
							"infowindowopen",
							function() {
								wpt.gmarker.infoWindowOpen = true;
							});
		GEvent.addListener(wpt.gmarker,
							"infowindowclose",
							function() {
								wpt.gmarker.infoWindowOpen = false;
							});
		
		map.addOverlay(this.gmarker);
		this.gmarker.hide();
	},
	
	show: function(map) {
		if (!this.gmarker.isHidden()) {
			return;
		}
		
		/* Show this waypoint */
		this.gmarker.show();
	},
	
	hide: function(map) {
		if (this.gmarker.isHidden()) {
			return;
		}
		
		/* Hide this waypoint */
		this.gmarker.hide();
	},
	
	toggle: function(map) {
		if (this.gmarker.isHidden()) {
			this.show(map);
		} else {
			this.hide(map);
		}
	},
	
	getPoint: function() {
		return this.gmarker.getPoint();
	},
	
	centerMap: function(map) {
		map.setCenter(this.gmarker.getLatLng(), this.MAP_CENTER_ZOOM);
		this.showInfoWindow();
		
		return false;
	},
	
	showInfoWindow: function() {
		var markerHtml = '<div class="waypoint-info-header">' + this.name + '</div>';
		if (this.ele != null) {
			markerHtml += '<div class="waypoint-info-metadata">';
			markerHtml +=	'<span class="title">Elevation:</span>';
			markerHtml +=	this.ele;
			markerHtml += '&nbsp;feet</div>';
		}
		if (this.time != null) {
			markerHtml += '<div class="waypoint-info-metadata">';
			markerHtml +=	'<span class="title">Date &amp; Time:</span>';
			markerHtml +=	this.time;
			markerHtml += '</div>';
		}
		if (this.desc != null) {
			markerHtml += '<div class="waypoint-info-metadata">';
			markerHtml +=	'<span class="title">Description:</span>';
			markerHtml +=	this.desc;
			markerHtml += '</div>';
		}
		if (this.cmt != null) {
			markerHtml += '<div class="waypoint-info-metadata">';
			markerHtml +=	'<BR/><span class="title">Pictures:</span><a href="';
			markerHtml +=	this.cmt;
			markerHtml += '">View Pictures for this Segment</a></div>';
		}

		this.gmarker.openInfoWindowHtml(markerHtml);
		
		return false;
	}
});

var TrackSegment = Class.create({
	
	initialize: function(json_trkseg, map) {
		this.visible	= false;
		this.encoded	= json_trkseg.encoded;
		
		this.polyline	= new GPolyline.fromEncoded(this.encoded);
	},
	
	show: function(map) {
		if (this.visible) {
			return;
		}
		
		map.addOverlay(this.polyline);
		this.visible = true;
	},
	
	hide: function(map) {
		if (!this.visible) {
			return;
		}
		
		map.removeOverlay(this.polyline);
		this.visible = false;
	},
	
	getBounds: function() {
		return this.polyline.getBounds();
	},
	
	centerMap: function(map) {
		var bounds = this.getBounds();
		var zoomlevel = map.getBoundsZoomLevel(bounds);
		map.closeInfoWindow();
		map.setCenter(bounds.getCenter(), zoomlevel);
		
		return false;
	}
});

/* ---------------------------------------------------------------------------
 * Track Object
 */
var Track = Class.create({
	
	initialize: function(json_trk, map) {
		this.trksegs	= new Array;
		var trk			= this;
		
		json_trk.trksegs.each(function(trkseg) {
			trk.trksegs.push(new TrackSegment(trkseg, map));
		});
		
	},
	
	show: function(map) {
		this.trksegs.each(function(trkseg) {
			trkseg.show(map);
		});
	},
	
	hide: function(map) {
		this.trksegs.each(function(trkseg) {
			trkseg.hide(map);
		});
	},

	getBounds: function() {
		var bounds = new GLatLngBounds();

		this.trksegs.each(function(trkseg) {
			var tmp_bounds = trkseg.getBounds();
			bounds.extend(tmp_bounds.getSouthWest());
			bounds.extend(tmp_bounds.getNorthEast());
		});

		return bounds;
	},
	
	centerMap: function(map) {
		var bounds = this.getBounds();
		var zoomlevel = map.getBoundsZoomLevel(bounds);
		map.closeInfoWindow();
		map.setCenter(bounds.getCenter(), zoomlevel);
		
		return false;
	}
});

/* ---------------------------------------------------------------------------
 * Trip Object
 */
var Trip = Class.create({
	
	initialize: function(wpt_json, trk_json, map) {
		this.wpts		= new Array;
		this.trks		= new Array;
		
		var tmp_trip	= this;
		
		wpt_json.each(function(wpt) {
			tmp_trip.wpts.push(new Waypoint(wpt, map));
		});
		
		trk_json.each(function(trk) {
			tmp_trip.trks.push(new Track(trk, map));
		});
	},
	
	show: function(map) {
		this.showWaypoints(map);
		this.showTracks(map);
	},
	
	hide: function(map) {
		this.hideWaypoints(map);
		this.hideTracks(map);
	},
	
	showWaypoints: function(map) {
		this.wpts.each(function(wpt) {
			wpt.show(map);
		});
	},
	
	showTracks: function(map) {
		this.trks.each(function(trk) {
			trk.show(map);
		});
	},
	
	hideWaypoints: function(map) {
		this.wpts.each(function(wpt) {
			wpt.hide(map);
		});
	},
	
	hideTracks: function(map) {
		this.trks.each(function(trk) {
			trk.hide(map);
		});
	},
	
	getBoundsOfWaypoints: function() {
		var bounds = new GLatLngBounds();
		
		this.wpts.each(function(wpt) {
			bounds.extend(wpt.getPoint());
		});

		return bounds;
	},
	
	getBoundsOfTracks: function() {
		var bounds = new GLatLngBounds();

		this.trks.each(function(trk) {
			var tmp_bounds = trk.getBounds();
			bounds.extend(tmp_bounds.getSouthWest());
			bounds.extend(tmp_bounds.getNorthEast());
		});

		return bounds;
	},
	
	getBounds: function() {
		var bounds = this.getBoundsOfWaypoints();
		
		if (this.trks.length) {
			var tmp_bounds = this.getBoundsOfTracks();
			bounds.extend(tmp_bounds.getSouthWest());
			bounds.extend(tmp_bounds.getNorthEast());
		}

		return bounds;
	},
	
	centerMap: function(map) {
		var bounds = this.getBounds();
		var zoomlevel = map.getBoundsZoomLevel(bounds);
		map.closeInfoWindow();
		map.setCenter(bounds.getCenter(), zoomlevel);
		
		return false;
	},
	
	centerMapOnWaypoints: function(map) {
		var bounds = this.getBoundsOfWaypoints();
		var zoomlevel = map.getBoundsZoomLevel(bounds);
		map.closeInfoWindow();
		map.setCenter(bounds.getCenter(), zoomlevel);
		
		return false;
	},
	
	centerMapOnTracks: function(map) {
		var bounds = this.getBoundsOfTracks();
		var zoomlevel = map.getBoundsZoomLevel(bounds);
		map.closeInfoWindow();
		map.setCenter(bounds.getCenter(), zoomlevel);
		
		return false;
	}
})
