google.maps.Map.prototype.markers = new Array();
google.maps.Map.prototype.getMarkers = function () {
	return this.markers;
};
google.maps.Map.prototype.clearMarkers = function () {
	for (var i = 0; i < this.markers.length; i++) {
		this.markers[i].setMap(null);
	}
	this.markers = new Array();
};
google.maps.Marker.prototype._setMap = google.maps.Marker.prototype.setMap;
google.maps.Marker.prototype.setMap = function (map) {
	if (map) {
		map.markers[map.markers.length] = this;
	}
	this._setMap(map);
};

var Tree = function (json) {
	if (json != null) {
		this._id = json.id;
		this._address=json.address;
		this._adopted=json.adopted==1;
		this._species = json.species;
		this._location=json.location;
		this._my_adopted=json.my_adopted==1;
		this._num=json.num;
		this._suffix=json.suffix;
		this._young_tree=json.young_tree==1;
		this._latlng = new google.maps.LatLng(json.lat, json.lng)
	}
};
Tree.prototype = {
	getId: function () {
		if (this._id != null)
			return this._id;
		else
			return "";
	},
	getCoordinates: function () {
		return this._latlng;
	},
	getNum: function () {
		return this._num;
	},
	getSuffix: function () {
		return this._suffix;
	},
	getSpecies: function () {
		if(this._species != null)
			return this._species;
		else
			return "";
	},
	getLocation: function () {
		if(this._location != null)
			return this._location;
		else
			return "";
	},
	getAddress: function () {
		if(this._address != null)
			return this._address;
		else
			return "";
	},
	isAdopted: function () {
		return this._adopted;
	},
	isMy: function () {
		return this._my_adopted;
	},
	setMy: function (adopted) {
		this._my_adopted = adopted;
	},
	setAdopted: function (adopted) {
		this._adopted = adopted;
	},
	isYoung: function () {
		return this._young_tree;
	},
	getTreeDescription: function () {
		var desc = "The " + this.getNum() + this.getSuffix() + " " + this.getSpecies()
			+ " " + this.getLocation() + " " + this.getAddress();
		return desc;
	}
};

var Location = function (id, json) {
	this._trees = [];
	for(var i in json) {
		var tree = new Tree(json[i]);
		this._trees.push(tree);
	}
	this._latlng = this._trees[0].getCoordinates();
	this._id = id;
}
Location.prototype = {
	getId: function () {
		return this._id;
	},
	getCoordinates: function () {
		return this._latlng;
	},
    setCoordinates: function(latlng) {
        this._latlng = latlng;
    },
	getMarker: function () {
		return (this._marker);
	},
	getTrees: function () {
		return this._trees;
	},
	setMyAdopted: function (adopted) {
		var trees = this.getTrees();
		trees[0].setMy(adopted);
		trees[0].setAdopted(adopted);
		this.getMarker().setIcon(this.getMarkerColor());
	},
	getMarkerColor: function () {
		var icon = "/images/map_icons/";
		var trees = this.getTrees();

		if (trees.length > 1) {
			var my = false;
			for(var i in trees) {
				if(trees[i].isMy()) {
					my = true;
					break;
				}
			}
			if(my){
				icon += "your_multiple_tree.png";
			}
			else {
				icon += "multiple_tree.png";
			}
		}
		else {
			if (trees[0].isMy()) {
				icon += "your_tree.png";
			}
			else if (trees[0].isAdopted()) {
				icon += "adopted_tree.png";
			}
			else if (trees[0].isYoung()) {
				icon += "young_tree.png";
			}
			else {
				icon += "reg_tree.png";
			}
		}
		return icon;
	},
	createMarker: function () {
		var icon = this.getMarkerColor();

		var marker = new google.maps.Marker({
			position: this.getCoordinates(),
			icon: icon,
			map: NMD.map
		});

		this._marker = marker;
		this.setupMarkerClick();
	},
	setupMarkerClick: function () {
		google.maps.event.clearListeners(this.getMarker(), 'click');
		var loc = this;
		google.maps.event.addListener(this.getMarker(), 'click', function () {
            if(NMD.editLocation == null) {
			    loc.openInfoWindow.call(loc);
            }
		});
	},
	getTreeIds: function () {
		var treeIds = [];
		var trees = this.getTrees();
		for (var i in trees) {
			treeIds.push(trees[i].getId());
		}
		return treeIds;
	},
	openInfoWindow: function (extraMessage) {
		if(extraMessage == undefined) {
			extraMessage = "";
		}
		var treeIds = this.getTreeIds();
		var loc = this;
		$.post("/controllers/trees_ajax.php?cmd=getMarkerHtml",
			{'tree_ids[]': treeIds},
			function (html) {
				NMD.infoWindow.setContent(extraMessage+html);
				NMD.infoWindow.open(NMD.map, loc.getMarker());
				NMD.selectedLocation = loc;
			}, 'html'
		)
	},
	showEdit: function () {
		google.maps.event.clearListeners(NMD.map, "dragend");
		google.maps.event.removeListener(NMD.zoomListener);
        NMD.map.setZoom(19);
        NMD.map.setCenter(this.getCoordinates());
        var trees = this.getTrees();
		var html =
			 '<p>Please <strong>click on the marker and drag</strong> this tree ('+trees[0].getTreeDescription()+
             ') to the correct location and let us know if there are any other inaccuracies.</p>'+
			 '<form id="editmapform"><label for="editmap_comments">Comments:</label><br/><input type="text" id="editmap_comments"/></form>'+
             '<a href="#" id="edit_confirm_marker">Submit</a> ' +
             '<a href="#" id="edit_cancel_marker">Cancel</a>';

		NMD.infoWindow.setContent(html);
		NMD.infoWindow.open(NMD.map, this.getMarker());
        var marker = this.getMarker();
        google.maps.event.addListener(NMD.infoWindow, "closeclick", function () {
			NMD.infoWindow.open(NMD.map, marker);
		});
		this.getMarker().setDraggable(true);
		NMD.editLocation = this;
	},
    confirmEdit: function() {
        var treeIds = this.getTreeIds();
        var loc = this;
        $.post("/controllers/trees_ajax.php?cmd=updateLocation",
            {
                tree_id: treeIds[0],
                old_lat: this.getCoordinates().lat(),
                old_lng: this.getCoordinates().lng(),
                new_lat: this.getMarker().getPosition().lat(),
                new_lng: this.getMarker().getPosition().lng(),
				comments: $("#editmap_comments").val()
            },
            function() {
                NMD.setupMapListeners();
                google.maps.event.clearListeners(NMD.infoWindow, "closeclick");
                NMD.mapMoveCallback = function() {
                    loc.openInfoWindow("<p>Thanks! We will be in touch if additional info is required.</p>");
                }
                NMD.centerMap(loc.getMarker().getPosition().lat(), loc.getMarker().getPosition().lng());
                NMD.editLocation = null;
            }, 'html'
        );
    },
    cancelEdit: function() {
        NMD.setupMapListeners();
        google.maps.event.clearListeners(NMD.infoWindow, "closeclick");
        this.getMarker().setMap(null);
        NMD.mapMoveCallback = function() {
            NMD.selectedLocation.openInfoWindow();
        };
        NMD.centerMap(this.getCoordinates().lat(), this.getCoordinates().lng());
        NMD.editLocation = null;
    }
}

var NMD = {
	locations: {},
	map: null,
	infoWindow: new google.maps.InfoWindow(),
	selectedLocation: null,
    editLocation: null,
    mapMoveCallback: null,
	loadMarkerTimeout: null,
	zoomListener: null,
	setupMap: function () {
		var mapOptions = {
			zoom: 11,
			center: new google.maps.LatLng(40.6951995413696, -73.9782737009043),
			mapTypeId: google.maps.MapTypeId.ROADMAP,
			scrollwheel: true,
			mapTypeControlOptions: {
				mapTypeIds: [google.maps.MapTypeId.ROADMAP,google.maps.MapTypeId.HYBRID,google.maps.MapTypeId.SATELLITE]
			}
		};
		NMD.map = new google.maps.Map(document.getElementById("googlemapdiv"), mapOptions);
		NMD.setupMapListeners();
	},
	setupMapListeners: function () {
		NMD.zoomListener = google.maps.event.addListener(NMD.map, "zoom_changed", NMD.setVisibleMarkers);
		google.maps.event.addListener(NMD.map, "dragend", NMD.setVisibleMarkers);
	},
	setVisibleMarkers: function () {
		// remove existing markers from map
		this.locations = {};

		if (NMD.map.getZoom() > 16) {
			$('#zoom_message').hide();
			clearTimeout(NMD.loadMarkerTimeout);
			NMD.loadMarkerTimeout = setTimeout(function () {
				var bounds = NMD.map.getBounds();
				$.post('/controllers/trees_ajax.php?cmd=getTrees', {
					nelat: bounds.getNorthEast().lat(),
					nelng: bounds.getNorthEast().lng(),
					swlat: bounds.getSouthWest().lat(),
					swlng: bounds.getSouthWest().lng()
				}, function (jsonLocations) {

					NMD.map.clearMarkers();
					for (var i in jsonLocations) {
						var location = new Location(i, jsonLocations[i]);
						location.createMarker();
						NMD.locations[location.getId()] = location;
					}
					if(NMD.mapMoveCallback !=null)
					{
						NMD.mapMoveCallback();
						NMD.mapMoveCallback=null;
					}
				}, 'json');
			}, 500);
		}
		else {
			NMD.map.clearMarkers();
            NMD.infoWindow.close();
			$('#zoom_message').show();
		}
	},
	centerMap: function (lat, lng) {
		NMD.map.setZoom(17);
		NMD.map.setCenter(new google.maps.LatLng(lat, lng));
	},
	searchLocations: function (locationName, listDiv, cssClass, callback) {
		$.post('/common_files/classes/smarty/cms/events/EventsCMSAjaxController.php?cmd=getParks', {
			park_name: locationName,
			cssClass: cssClass
		}, function (data) {
			if (data.point == 'list') {
				listDiv.html(data.list);
				listDiv.show();
			}
			else
				if (data.point == false) {
					var geocoder = new google.maps.Geocoder();
					geocoder.geocode({
						address: locationName,
						bounds: new google.maps.LatLngBounds(new google.maps.LatLng(40.494116, -74.259453), new google.maps.LatLng(40.908479, -73.712883))
					}, function (response, status) {
						if (status == google.maps.GeocoderStatus.OK) {
							var latlng = response[0].geometry.location;
							var point = {
								lat: latlng.lat(),
								lng: latlng.lng()
							};
							callback(point);
						}
						else {
							callback(false);
						}
					});
				}
				else {
					callback(data.point);
				}
		}, 'json');
	}
}


$(function () {
	NMD.setupMap();
	$(".close_window").live("click", function () {
		NMD.infoWindow.close();
	});

	$("#find_location_txt").focus(function(){
		if($(this).val() == "Enter Zip Code, Address or Intersection") {
			$(this).val("");
		}
	});
	$("#find_location_txt").blur(function(){
		if($(this).val() == "") {
			$(this).val("Enter Zip Code, Address or Intersection");
		}
	});
    $("#find_location_txt").keypress(function (e) {
		if (e.keyCode == 13) {
			$('#find_location_btn').click();
			return false;
		}
		return true;
	});
	$("#find_location_btn").click(function () {
		var geocoder = new google.maps.Geocoder();
		geocoder.geocode({
			address: $("#find_location_txt").val(),
			bounds: new google.maps.LatLngBounds(new google.maps.LatLng(40.494116, -74.259453), new google.maps.LatLng(40.908479, -73.712883))
		}, function (response, status) {
			if (status == google.maps.GeocoderStatus.OK) {
				var latlng = response[0].geometry.location;
				NMD.centerMap(latlng.lat(), latlng.lng());
			}
			else {
				$("#find_location_btn").after("<span class='error'>Location was not found. Please try to type in a different location</span>");
			}
		});
	});
	$(".report_incorrect_location").live("click",function(){
		var id=$(this).attr('rel');

        $.post('/controllers/trees_ajax.php?cmd=getTree', {
            'tree_ids[]': id
        }, function (jsonLocations) {
            for (var i in jsonLocations) {
                var location = new Location(i, jsonLocations[i]);
                location.createMarker();
                location.showEdit();
            }
        }, 'json');
        return false;
	});
    $("#edit_cancel_marker").live("click", function() {
        NMD.editLocation.cancelEdit();
    });
    $("#edit_confirm_marker").live("click", function() {
        NMD.editLocation.confirmEdit();
    });
	if($('#lat').val()!='' && $('#lng').val()!='')
	{
		NMD.mapMoveCallback=function(){
			var id=$('#lat').val()+'_'+$('#lng').val();
			var loc=NMD.locations[id];
			loc.openInfoWindow.call(loc);
		};
		NMD.centerMap($('#lat').val(), $('#lng').val());
	}
	$(".show_actions_lnk").live("click",function(){
		$(this).parent().next().toggle();
		if($(this).text() == "Show actions") {
			$(this).text("Hide actions");
		}
		else {
			$(this).text("Show actions");
		}
		return false;
	});
});
