var seoul = new google.maps.LatLng(37.565025, 126.978436);

/**
 * Map Object
 * 
 * @author Laurent Le Graverend
 * @version 0.5
 * @param container
 * @param latitude
 * @param longitude
 * @return
 */
function MyMap(container, latitude, longitude) {

	this.cont = container;
	
	if (latitude == 0 || longitude == 0) {
		this.lat = 37.565025;
		this.lng = 126.978436;
	} else {
		this.lat = latitude;
		this.lng = longitude;
	}
	
	this.initPoint = new google.maps.LatLng(this.lat, this.lng);

	this.directionDisplay;
	this.directionsService = new google.maps.DirectionsService();
	this.map;
	this.origin = null;
	this.destination = null;
	this.waypoints = [];
	this.markers = [];
	this.directionsVisible = false;
	this.markersPath = null;
	this.infowindow = null;
	
	// This is for Seoul
	this.minLatitude = 0;	
	this.maxLatitude = 0;	
	this.minLongitude = 0;
	this.maxLongitude = 0;
	
	if (typeof MyMap.initialized == "undefined") {

		MyMap.prototype.initialize = function() {
			directionsDisplay = new google.maps.DirectionsRenderer();
			this.myOptions = {
				zoom : 12,
				mapTypeId : google.maps.MapTypeId.ROADMAP,
				center : this.initPoint,
				disableDefaultUI : false,
				scrollwheel : false,
				keyboardShortcuts : false,
				draggable : true,
				disableDoubleClickZoom : false
			};
			this.map = new google.maps.Map(this.cont, this.myOptions);
			// directionsDisplay.setMap(map);
			// directionsDisplay.setPanel($("directionsPanel"));
		};
		
		MyMap.prototype.setMarkersPath = function(path) {			
			this.markersPath = path;
		};

		MyMap.prototype.setOptionsToMap = function(fullScreen) {
			var myOptionsUpdate = {
				zoom : 13,
				mapTypeId : google.maps.MapTypeId.ROADMAP,
				center : this.initPoint,
				disableDefaultUI : !fullScreen,
				scrollwheel : fullScreen,
				keyboardShortcuts : fullScreen,
				draggable : fullScreen,
				disableDoubleClickZoom : !fullScreen
			};
			map.setOptions(myOptionsUpdate);
		};

		MyMap.prototype.addNewDestination = function(lat, lng, id, string) {
			
			if (this.markers.length == 0) {
				this.minLatitude = parseFloat(lat);
				this.maxLatitude = parseFloat(lat);
				this.minLongitude = parseFloat(lng);
				this.maxLongitude = parseFloat(lng);
			}
			
			if (parseFloat(lat) < this.minLatitude) this.minLatitude = parseFloat(lat);
			else if (parseFloat(lat) > this.maxLatitude) this.maxLatitude = parseFloat(lat);
			
			if (parseFloat(lng) < this.minLongitude) this.minLongitude = parseFloat(lng);
			else if (parseFloat(lng) > this.maxLongitude) this.maxLongitude = parseFloat(lng);
			
			var latlng = new google.maps.LatLng(lat, lng);
			if (this.origin == null) {
				this.origin = latlng;
				this.addMarkerByCoord(this.origin, id, string);
			} else if (this.destination == null) {
				this.destination = latlng;
				this.addMarkerByCoord(this.destination, id, string);
			} else {
				if (this.waypoints.length < 9) {
					this.waypoints.push( {
						location : this.destination,
						stopover : true
					});
					this.destination = latlng;
					this.addMarkerByCoord(this.destination, id, string);
				} else {
					alert("Maximum number of waypoints reached");
				}
			}
		};
		
		MyMap.prototype.openInfoWindow = function(id, string) {
			if (this.infowindow != null) this.infowindow.close();
			this.infowindow = new google.maps.InfoWindow( {
				content : '<div id="contentInfoWindow' + id
						+ '" class="contentInfoWindow">' + string + '</div>'
			});
			this.infowindow.open(this.map, this.markers[id]);
		};

		MyMap.prototype.addMarker = function(lat, lng, id, string) {
			
			if (this.markersPath == null) {
				picture = "http://maps.google.com/mapfiles/marker" + String.fromCharCode(this.markers.length + 65) + ".png";
			} else {
				picture = this.markersPath + (this.markers.length + 1) + '.png';
			}
			
			var marker = new google.maps.Marker( {
				position : new google.maps.LatLng(lat, lng),
				map : this.map,
				icon : picture,
				title : id
			});

			if (string != '') {		
				google.maps.event.addListener(marker, 'click', function() {
					if (this.infowindow != null) this.infowindow.close();
					this.infowindow = new google.maps.InfoWindow( {
						content : '<div id="contentInfoWindow' + id
								+ '" class="contentInfoWindow">' + string + '</div>'
					});
					this.infowindow.open(this.map, marker);
				});
			}
			
			this.markers.push(marker);
		};
		
		MyMap.prototype.addMarkerByCoord = function(latlng, id, string) {
			
			if (this.markersPath == null) {
				picture = "http://maps.google.com/mapfiles/marker" + String.fromCharCode(this.markers.length + 65) + ".png";
			} else {
				picture = this.markersPath + (this.markers.length + 1) + '.png';
			}

			var marker = new google.maps.Marker( {
				position : latlng,
				map : this.map,
				icon : picture,
				title : id
			});

			google.maps.event.addListener(marker, 'click', function() {
				if (this.infowindow != null) this.infowindow.close();
				this.infowindow = new google.maps.InfoWindow( {
					content : '<div id="contentInfoWindow' + id
							+ '" class="contentInfoWindow">' + string + '</div>'
				});
				this.infowindow.open(this.map, marker);
			});
			this.markers.push(marker);
		};
		
		MyMap.prototype.calcRoute = function() {
			if (this.origin == null) {
				alert("Click on the map to add a start point");
				return;
			}

			if (this.destination == null) {
				alert("Click on the map to add an end point");
				return;
			}

			var mode;
			switch ($("mode").value) {
			case "bicycling":
				mode = google.maps.DirectionsTravelMode.BICYCLING;
				break;
			case "driving":
				mode = google.maps.DirectionsTravelMode.DRIVING;
				break;
			case "walking":
				mode = google.maps.DirectionsTravelMode.WALKING;
				break;
			}

			var request = {
				origin : this.origin,
				destination : this.destination,
				waypoints : this.waypoints,
				travelMode : mode,
				optimizeWaypoints : $('optimize').checked,
				avoidHighways : $('highways').checked,
				avoidTolls : $('tolls').checked
			};

			this.directionsService.route(request, function(response, status) {
				if (status == google.maps.DirectionsStatus.OK) {
					directionsDisplay.setDirections(response);
				}
			});

			clearMarkers();
			this.directionsVisible = true;
		};

		MyMap.prototype.updateMode = function() {
			if (this.directionsVisible) {
				calcRoute();
			}
		};

		MyMap.prototype.clearMarkers = function() {
			for ( var i = 0; i < this.markers.length; i++) {
				this.markers[i].setMap(null);
			}
		};

		MyMap.prototype.clearWaypoints = function() {
			this.markers = [];
			this.origin = null;
			this.destination = null;
			this.waypoints = [];
			this.directionsVisible = false;
		};

		MyMap.prototype.resetMap = function() {
			clearMarkers();
			clearWaypoints();
			directionsDisplay.setMap(null);
			directionsDisplay.setPanel(null);
			directionsDisplay = new google.maps.DirectionsRenderer();
			directionsDisplay.setMap(this.map);
			directionsDisplay.setPanel($("directionsPanel"));
		};

		MyMap.prototype.resizeMap = function() {
			setTimeout("google.maps.event.trigger(this.map, 'resize')", 500);
			setTimeout("this.map.setCenter(this.initPoint, 13)", 500);
		};
		
		MyMap.prototype.autoZoom = function() {

			var centerLatitude = this.minLatitude
					+ (this.maxLatitude - this.minLatitude) / 2;
			var centerLongitude = this.minLongitude
					+ (this.maxLongitude - this.minLongitude) / 2;
			
			this.map.setCenter(new google.maps.LatLng(centerLatitude,
					centerLongitude));

			var miles = parseFloat((3958.75 * Math.acos(Math.sin(this.minLatitude / 57.2958)
					* Math.sin(this.maxLatitude / 57.2958)
					+ Math.cos(this.minLatitude / 57.2958)
					* Math.cos(this.maxLatitude / 57.2958)
					* Math.cos(this.maxLongitude / 57.2958
					- this.minLongitude / 57.2958))));

			switch (true) {
				case (miles < 1):
					zoom = 14;
					break;
				case (miles < 2):
					zoom = 13;
					break;
				case (miles < 4):
					zoom = 12;
					break;
				case (miles < 7):
					zoom = 11;
					break;
				case (miles < 15):
					zoom = 10;
					break;
				case (miles < 50):
					zoom = 9;
					break;
				case (miles < 300):
					zoom = 7;
					break;
				case (miles < 600):
					zoom = 6;
					break;
				
			}
			this.map.setZoom(zoom);
		};

		MyMap.initialized = true;
	}	
}
