/*
 * google_maps Javascript 1.0
 * http://agforceusa.com/
 *
 * Copyright (c) 2009 AgForceUSA
 *
 * Date: 2009-06-16 12:42:21 (Tue, 16 Jun 2009)
 */
var map, geocoder, marker, grids, counties, grid_labels, county_labels;
var current_point = null;
var processing_grids = false;
var processing_counties = false;
var marker_info_disabled_flag = false;
var marker_listener;
			  
var clckTimeOut = null; 
var options = {};
var shapeCounter_ = 0;
var markerCounter_ = 0;
var colorIndex_ = 0;
var featureTable_;
var shapes, shape_labels, markers, pin_cells;
var current_marker_id = 0;
var marker_links;
var marker_info;
var single_marker_set = false;
var shape_being_drawn = null;

jQuery.ajaxSetup({ 
  'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});

$(document).ajaxSend(function(event, request, settings) {
  if (typeof(AUTH_TOKEN) == "undefined") return;
  // settings.data is a serialized string like "foo=bar&baz=boink" (or null)
  settings.data = settings.data || "";
  settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
});

/* Document preparation */
$(document).ready(function() {
	grids = {};
	grid_labels = {};
	counties = {};	
	county_labels = {};
	shapes = {};
	shape_labels = {};
	markers = {};
	pin_cells = {};
	marker_links = {};
	marker_info = {};
	
	map = new google.maps.Map(document.getElementById("map"));
	geocoder = new GClientGeocoder();
	
	map.addControl(new GLargeMapControl3D());
	map.addControl(new GMapTypeControl());
	map.addControl(new ZoomToGridControl());
	map.addMapType(G_PHYSICAL_MAP);
	map.enableScrollWheelZoom();
	
	featureTable_ = document.getElementById("featuretbody");
	
	var centerLatitude = getParameter("center_lat");
	if (centerLatitude == "") {
		centerLatitude = 37.09023980307208;
	}
	var centerLongitude = getParameter("center_long");
	if (centerLongitude == "") {
		centerLongitude = -95.712890625;
	}
	var startZoom = getParameter("zoom");
	startZoom = parseInt(startZoom);
	if (isNaN(startZoom)) {
		startZoom = 4;
	}
	if (startZoom < 0) {
		startZoom = 0;
	}
	if (startZoom > 19) {
		startZoom = 19;
	}
	var markerLatitude = getParameter("marker_lat");
	var markerLongitude = getParameter("marker_long");
	if (markerLatitude != "" && markerLongitude != "") {
		setMarker(new GLatLng(markerLatitude, markerLongitude));
	}
	map.setCenter(new GLatLng(centerLatitude, centerLongitude), startZoom);
	var ins_plan = getParameter("ins_plan");
	if (ins_plan == "vegetation") {
		toggleTab($("#nav-sel-1"));
	} else if (ins_plan == "rainfall") {
		toggleTab($("#nav-sel-2"));
	}
	
	marker_listener = GEvent.addListener(map, 'click', marker_click_listener);
	GEvent.addListener(map, 'dblclick', function(overlay, latlong, overlaylatlong) {
		//cancel any single click handlers
		if (clckTimeOut != null) {
			window.clearTimeout(clckTimeOut);
			clckTimeOut = null;
		}
	});
	GEvent.addListener(map, 'singlerightclick', function(latlong, element, overlay) {
		singleRightClick(latlong, overlay);
	});
	GEvent.addListener(map, 'moveend', function(){
		drawGrids();
		drawCounties();
	});
	GEvent.addListener(map, 'zoomend', function(){
		drawGrids();
		drawCounties();
	});
	$(window).unload(function(){
		GUnload();
	});

	drawGrids();
	drawCounties();
	
	$('#print').onclickPrint();
	$('#location-search').onclickSearch();	
	$('#view-counties').onchangeViewCounties();
	$('#view-grids').onchangeViewGrids();
	$('#view-marker-info').onchangeViewMarkerInfo();
	$('#map-type').onchangeMapType();
	$('#view-county-labels').onchangeCountyLabels();
	$('#view-grid-labels').onchangeGridLabels();
	$('#marker_btn').onclickMarkerButton();
	$('#multi_marker_btn').onclickMultiMarkerButton();
	$('#shape_btn').onclickShapeButton();
	$('#clear_btn').onmousedownClearButton();
	$('#clear_btn').onmouseupClearButton();
	$('#clear_btn').onmouseoutClearButton();
	
	$('#marker_btn').show();
	$('#multi_marker_btn').show();
	$('#shape_btn').show();
	$('#clear_btn').show();

	
	
    select("marker_btn");
});

function marker_click_listener (overlay,latlong,overlaylatlong) {
	if (overlay) {
		mapClick(overlaylatlong, overlay);
	}
	else {
		mapClick(latlong, null);
	}
	return false;
}

function mapClick(point, overlay) {
	if (clckTimeOut) {
		window.clearTimeout(clckTimeOut);
		clckTimeOut = null;
	}
	else
	{
		clckTimeOut = window.setTimeout(function(){
			singleClick(point, overlay)
		}, 200);
	}
};

function singleClick(point, overlay){
	window.clearTimeout(clckTimeOut);
	clckTimeOut = null;
	var new_location = true;
	if (current_point == point) {
		new_location = false;
	}
	if (marker_info_disabled_flag) {
		if (current_point == point) {
			//The info window was clicked, disable reopening it
			$('#view-marker-info').attr('checked', false);
		}
		marker_info_disabled_flag = false;
	}
	//If overlay is pin, open window
	if (overlay != null) {
		$.each(markers, function(i, pin){
			if (overlay == pin) {
				new_location = false;
				if ($('#view-marker-info').attr('checked')) {
					pin.openInfoWindowHtml(marker_info[i]);
				} else if (current_marker_id == i) {
					pin.openInfoWindowHtml(marker_info[i]);
					$('#view-marker-info').attr('checked', true);
				}
				current_marker_id = i;
				current_point = point;
			}
		});
	}
	if (new_location) {
		if ($("#marker_btn").hasClass('selected')) {
			setMarker(point);
		} else if ($("#multi_marker_btn").hasClass('selected')) {
			setMultiMarker(point, overlay);
		} else if ($("#shape_btn").hasClass('selected')) {
			
		}
	}
}

function singleRightClick(point, overlay) {
	$('#right-click-menu').empty();
	var overlay_type = "";
	if (overlay) {
		var id;
		$.each(markers, function(i, pin){
			if (pin == overlay) {
				overlay_type = 'pin';
				id = i;
			}
		});
		if (overlay_type == "") {
			$.each(shapes, function(i, pin){
				if (pin == overlay) {
					overlay_type = 'shape'
					id = i;
				}
			});
		}
	}
	//load overlay menu
	if (overlay_type == 'pin') { //Pin window
		$('#right-click-menu').append(createMenuItem('Delete', function(){
			map.removeOverlay(overlay);
			$("#" + overlay_type + "_" + id).remove();
			delete markers[id];
			if ($("#featuretbody").html() == "") {
				$("#featuretable-holder").hide();
			}
			if (id == current_marker_id) {
				current_marker_id = null
				single_marker_set = false;
			}
		}));
		$('#right-click-menu').append(createMenuItem('Open Info Window', function(){
			markers[id].openInfoWindowHtml(marker_info[id]);
			if (!($('#view-marker-info').attr('checked'))) {
				$('#view-marker-info').attr('checked', true);
			}
		}, true));
		if (marker_links[id]) {
			$('#right-click-menu').append(createMenuLink('Decision Support Tool', 'dst', marker_links[id]['dst']));
			$('#right-click-menu').append(createMenuLink('Historical Rainfall Indices', 'hist', marker_links[id]['hist']));
			$('#right-click-menu').append(createMenuLink('View Actuarial Info', 'actInfo', marker_links[id]['actInfo']));
			$('#right-click-menu').append(createMenuLink('View Cost Estimator', 'cost', marker_links[id]['cost']));
		}
		$('#right-click-menu').css({
			'top': point.y,
			'left': point.x
		});
		$('#right-click-menu').show('fast');
		$('#right-click-menu').mouseleave(function(){
			$(this).hide();
		});
	} else if (overlay_type == 'shape') { //Shape Menu
		$('#right-click-menu').append(createMenuItem('Delete', function(){
			map.removeOverlay(overlay);
			$("#" + overlay_type + "_" + id).remove();
			delete shapes[id];
			map.removeOverlay(shape_labels[id]);
			delete shape_labels[id];
			if ($("#featuretbody").html() == "") {
				$("#featuretable-holder").hide();
			}
		}));
		$('#right-click-menu').css({
			'top': point.y,
			'left': point.x
		});
		$('#right-click-menu').show('fast');
		$('#right-click-menu').mouseleave(function(){
			$(this).hide();
		});
	} else { //Regular Map Menu
		//load map menu
		$('#right-click-menu').append(createMenuItem('Zoom In', function(){
			map.zoomIn();
		}));
		$('#right-click-menu').append(createMenuItem('Zoom Out', function(){
			map.zoomOut();
		}));
		$('#right-click-menu').append(createMenuItem('Zoom To Grids', function(){
			map.setZoom(10);
		}));
		$('#right-click-menu').append(createMenuItem('Center Map Here', function(){
			map.setCenter(map.fromContainerPixelToLatLng(point));
		}));
		$('#right-click-menu').css({
			'top': point.y,
			'left': point.x
		});
		$('#right-click-menu').show('fast');
		$('#right-click-menu').mouseleave(function() {
			$(this).hide();
		});
	}
}

function createMenuItem(name, click, spacer) {
	var item = document.createElement('div');
	$(item).html(name);
	$(item).addClass('right-click-menu-item');
	if (spacer) {
		$(item).addClass('right-click-spacer');
	}
	$(item).click(function() {
		click();
		$('#right-click-menu').hide();
	});
	return item;
}

function createMenuLink(name, target, href, spacer) {
	var item = document.createElement('a');
	$(item).attr('href', href);
	$(item).attr('alt', name);
	$(item).attr('target', target);
	$(item).html(name);
	$(item).addClass('right-click-menu-link');
	$(item).addClass('right-click-menu-item');
	if (spacer) {
		$(item).addClass('right-click-spacer');
	}
	return item;
}

function save_map_items_to_db(onComplete) {
	var baseURL = getBaseURL();
	var markers_completed = false;
	var shapes_completed = false;
	$("#loading").html("Preparing to Print...");
	$("#loading").show();
	var params = {};
	$.ajax({
		type: "GET",
		url: baseURL + "/clear_map_items",
		data: params,
		dataType: "html",
		success: function(msg) {
			var markers_data = {};
			$.each(markers, function(id, marker) {
				markers_data[id] = { 'lat': marker.getLatLng().lat(), 'lng': marker.getLatLng().lng() };
			})
			$.ajax({
				type: "POST",
				url: baseURL + "/save_markers",
				data: { 'markers': JSON.stringify(markers_data) },
				success: function() {
					markers_completed = true; 
					if (markers_completed && shapes_completed) {
						$("#loading").fadeOut('normal');
						onComplete();
					}
				}
			});
			//Check for incomplete shapes
			if (shape_being_drawn != null) {
				//programatically end shape drawing
				if (shape_being_drawn.getVertexCount() > 0) {
					shape_being_drawn.insertVertex(shape_being_drawn.getVertexCount(), shape_being_drawn.getVertex(0));
					GEvent.trigger(shape_being_drawn, "endline");
				}
				else {
					//a point has notbeen drawn yet.
					shape_being_drawn.disableEditing();
					map.removeOverlay(shape_being_drawn);
					delete shapes[shapeCounter_];
				}
			}
			if (marker_listener == null) {
				marker_listener = GEvent.addListener(map, 'click', marker_click_listener);
			}
			var shapes_data = {};
			$.each(shapes, function(id, shape) {
				var shape_parsed = {};
				shape_parsed['area'] = Math.round(shape.getArea() * 0.247105381) / 1000;
				var points = []
				for (i = 0; i < shape.getVertexCount(); i++) {
					points[i] = [shape.getVertex(i).lat(), shape.getVertex(i).lng()];
				}
				points = $.map(points, function(n, i) {
					return n.join(",");
				});
				points = points.join(";");
				shape_parsed['points'] = points;
				shapes_data[id] = shape_parsed;
			})
			$.ajax({
				type: "POST",
				url: baseURL + "/save_shapes",
				data: { 'shapes': JSON.stringify(shapes_data) },
				success: function() {
					shapes_completed = true;
					if (markers_completed && shapes_completed) {
						$("#loading").fadeOut('normal');
						onComplete();
					}
				}
			});
		}
	});
}

function setMarker(point) {
	if (point) {
		//Add marker
		if (current_point != point) {
			current_point = point;
			if (single_marker_set) {
				map.removeOverlay(markers[current_marker_id]);
				delete markers[current_marker_id];
			}
			var marker = null
			if (!(single_marker_set)) {
				var label_xoffset = -3;
				var label_yoffset = -30;
				var label_class = "marker-label";
				if ((markerCounter_ + 1) >= 10) {
					label_xoffset = -7;
				}
				if ((markerCounter_ + 1) >= 100) {
					label_class = "marker-label-small";
					label_yoffset = -28;
				}
				marker = new LabeledMarker(point, {
					icon: getIcon('blue'),
					labelText: markerCounter_ + 1,
					labelOffset: new GSize(label_xoffset, label_yoffset),
					labelClass: label_class
				});
				map.addOverlay(marker);
				markers[++markerCounter_] = marker;
				pin_cells[markerCounter_] = addFeatureEntry('pin', "Pin " + markerCounter_);
				current_marker_id = markerCounter_;
				single_marker_set = true;
			} else {
				var label_xoffset = -3;
				var label_yoffset = -30;
				var label_class = "marker-label";
				if ((markerCounter_) >= 10) {
					label_xoffset = -7;
				}
				if ((markerCounter_) > 100) {
					label_class = "marker-label-small";
					label_yoffset = -28;
				}
				marker = new LabeledMarker(point, {
					icon: getIcon('blue'),
					labelText: markerCounter_,
					labelOffset: new GSize(label_xoffset, label_yoffset),
					labelClass: label_class
				});
				map.addOverlay(marker);
				markers[markerCounter_] = marker;
			}
			var updateHighlight = updateHighlightGenerator(markerCounter_, true);
			var updateLocation = updateLocationGenerator(markerCounter_);
			var panToMarker = panToLocationGenerator(markerCounter_);
			GEvent.addListener(marker, "infowindowclose", function(){
				marker_info_disabled_flag = true;
			});
			GEvent.addListener(marker, "click", function(){
				updateHighlight();
			});
			//Click Handler for selecting
			$(currentRow_).click(function() {
				panToMarker();
				updateHighlight();
				updateLocation();
			});
			updateHighlight();
			//Get Location Info
			getLocationName(markerCounter_);
		}
	}
};

function setMultiMarker(point, overlay) {
	if (point) {
		current_point = point;
		var label_xoffset = -3;
		var label_yoffset = -30;
		var label_class = 'marker-label'
		if ((markerCounter_ + 1) >= 10) {
			label_xoffset = -7;
		}
		if ((markerCounter_ + 1) >= 100) {
			label_class = 'marker-label-small';
			label_yoffset = -28;
		}
		var marker = new LabeledMarker(point, {
			icon: getIcon('blue'),
			labelText: markerCounter_ + 1,
			labelOffset: new GSize(label_xoffset, label_yoffset),
			labelClass: label_class
		});
		map.addOverlay(marker);
		
		$.each(markers, function(i, pin) {
			if (pin.getIcon().image == getIcon('blue').image) {
				pin.setImage(getIcon('red').image);
			}
		});
		$.each(pin_cells, function(i , cells) {
			if ($(cells.color).hasClass('selected-table-cell')) {
				$(cells.color).removeClass('selected-table-cell');
				$(cells.color).addClass('nonselected-table-cell');
			}
		})
		
		markers[++markerCounter_] = marker;
		pin_cells[markerCounter_] = addFeatureEntry('pin', "Pin " + markerCounter_);
		current_marker_id = markerCounter_;
		//update location
		getLocationName(markerCounter_, pin_cells[markerCounter_]);
		
		// add entry and tie-in events
		var updateHighlight = updateHighlightGenerator(markerCounter_, true);
		var updateLocation = updateLocationGenerator(markerCounter_);
		var panToMarker = panToLocationGenerator(markerCounter_);
		GEvent.addListener(marker, "click", function(){
			updateHighlight();
		});
		GEvent.addListener(marker, "infowindowclose", function(){
			marker_info_disabled_flag = true;
		});
		//Click Handler for selecting
		$(currentRow_).click(function() {
			panToMarker();
			updateHighlight();
			updateLocation();
		});
	}
}

function panToLocationGenerator(markerCounter) {
	return function() {
		map.panTo(markers[markerCounter].getLatLng());
	}
}

function convertLatitudeToString(lat) {
	var latitude = "";
	lat = Math.round(lat*100000)/100000;
	if (lat < 0){
		latitude = Math.abs(lat) + "&deg;S";
	} else {
		latitude = lat + "&deg;N";
	}
	return latitude;
};

function convertLongitudeToString(lng) {
	var longitude = "";
	lng = Math.round(lng*100000)/100000;
	if (lng < 0) {
		longitude = Math.abs(lng) + "&deg;W";
	} else {
		longitude = lng + "&deg;E";
	}
	return longitude;
};

function getLocationName(markerCounter) {
	var marker = markers[markerCounter];
	var point = marker.getLatLng();
	var cells = pin_cells[markerCounter];
	$('#latitude').html(convertLatitudeToString(point.lat()));
	$('#longitude').html(convertLongitudeToString(point.lng()));
	var baseURL = getBaseURL();
	if (baseURL != null) {
		params = {
			'lat': point.lat(),
			'long': point.lng()
		};
		if ($("#nav-sel-1").hasClass('nav-menu-active')) {
			params['ins_plan'] = "vegetation"
		}
		else {
			params['ins_plan'] = "rainfall"
		}
		$.ajax({
			type: "GET",
			url: baseURL + "/get_location",
			data: params,
			dataType: "json",
			success: function(json){
				$('#state').html(json['state']);
				$('#county').html(json['county']);
				$('#grid').html(json['grid']);
				
				if (json['in_pilot_area'] == 't') {
					$('#warning-holder').hide();					
					setMarkerInfoWindow(markerCounter, point.lat(), point.lng(), json['state'], json['county'], json['grid'], true);
				}
				else {
					$('#warning-holder').fadeIn('normal');					
					setMarkerInfoWindow(markerCounter, point.lat(), point.lng(), json['state'], json['county'], json['grid'], false);
				}
				
				if (cells) {
					$(cells.desc).html('Grid: ' + json['grid']);
				}
				
				// setup links
				var grid = json['grid']
				var state_id = json['state_id'];
				var county_id = json['county_id'];
				var tool_type = json['tool_type'];
				var crop_code = "1191"
				
				if(tool_type == "api")
				{
					crop_code = "1191";
				}
				else if (tool_type == "prf")
				{
					crop_code = "0088";
				}
				else
				{
					tool_type = "api";
					crop_code = "1191";
				}
				if ($("#nav-sel-1").hasClass('nav-menu-active')) {
					$("#dst").attr("href", 'http://agforceusa.com/rma/vi/' + tool_type + '/dst/load_from_map?grid_id=' + grid + '&county_id=' + county_id + '&state_id=' + state_id);
					$("#hist").attr("href", 'http://agforceusa.com/rma/vi/' + tool_type + '/dst/load_chart_from_map?grid_id=' + grid + '&county_id=' + county_id + '&state_id=' + state_id);
				}
				else {
					$("#dst").attr("href", 'http://agforceusa.com/rma/ri/' + tool_type + '/dst/load_from_map?grid_id=' + grid + '&county_id=' + county_id + '&state_id=' + state_id);
					$("#hist").attr("href", 'http://agforceusa.com/rma/ri/' + tool_type + '/dst/load_chart_from_map?grid_id=' + grid + '&county_id=' + county_id + '&state_id=' + state_id);
				}
				if (markerCounter) {
					marker_links[markerCounter] = {
						'dst': $("#dst").attr('href'),
						'hist': $("#hist").attr('href'),
						'actInfo': $("#actInfo").attr('href'),
						'cost': $("#cost").attr('href')
					}
				}
			}
		});
	}
	geocoder.getLocations(
		point,
		function(response) {
			if (!response || response.Status.code != 200) {
				$('#address').html('-');
			}
			else {
				$('#address').html(response.Placemark[0].address);
			}
		}
	);
		
};

function setMarkerInfoWindow(markerCounter, lat, lng, state, county, grid, in_pilot){
	var marker = markers[markerCounter];
	var latitude = convertLatitudeToString(lat);
	var longitude = convertLongitudeToString(lng);
	var info = "";
	if (in_pilot) 
	{
		marker_info[markerCounter] = "<b>Grid ID: " + grid + "</b><br />" +
					  "Latitude: " + latitude + "<br />" +
					  "Longitude: " + longitude + "<br />" +
				   	  "County: " + county +	"<br />" +
					  "State: " + state;
	}
	else
	{
		marker_info[markerCounter] = "<div><div id='info-warning-holder'>This location is not currently in the pilot area.</div>" +
					  "<b>Grid ID: " + grid + "</b><br />" +
					  "Latitude: " + latitude + "<br />" +
					  "Longitude: " + longitude + "<br />" +
					  "County: " + county +	"<br />" +
					  "State: " + state + "</div>";					  
	}					
	if ($('#view-marker-info').attr('checked')) {
		marker.openInfoWindowHtml(marker_info[markerCounter]);
	}
};

function addGrids(geoms) {
	$.each(geoms, function(i, geom) {
		if (grids[i] === undefined) {
			var points = [];
			var label_points = [];
			var sw = map.getBounds().getSouthWest();
			var ne = map.getBounds().getNorthEast();
		
			$.each(geom, function(i, point){
				points.push(new GLatLng(parseFloat(point[1]), parseFloat(point[0])));
				
				var lat = parseFloat(point[1]);
				var lng = parseFloat(point[0]);
				if(lng > ne.lng()){
					lng = ne.lng();
				}				
				if(lng < sw.lng()){
					lng = sw.lng();
				}				
				if(lat > ne.lat()){
					lat = ne.lat();
				}				
				if(lat < sw.lat()){
					lat = sw.lat();
				}				
				label_points.push(new GLatLng(lat, lng));
			});
			var polygon = new GPolygon(points, "#990000", 1, 1, '#0000FF', 0, false);
			var label_poly = new GPolygon(label_points, "#990000", 1, 1, '#0000FF', 0, false);
			
			var label = new ELabel(label_poly.getBounds().getCenter(), i, 'map-grid-label', new GSize(-30, 6), 100, true);
			map.addOverlay(polygon);
			if (($('#view-grids:checked').length <= 0)) {
				polygon.hide();
			}
			map.addOverlay(label);
			if ($('#view-grid-labels:checked').length <= 0) {
				label.hide();
			}
			label.id = geom.id;
			polygon.id = geom.id;
			grid_labels[i] = label;			
			grids[i] = polygon;
		}
		else
		{
			map.removeOverlay(grid_labels[i]);
			
			var label_points = [];
			var sw = map.getBounds().getSouthWest();
			var ne = map.getBounds().getNorthEast();
		
			$.each(geom, function(i, point){
								
				var lat = parseFloat(point[1]);
				var lng = parseFloat(point[0]);
				if(lng > ne.lng()){
					lng = ne.lng();
				}				
				if(lng < sw.lng()){
					lng = sw.lng();
				}				
				if(lat > ne.lat()){
					lat = ne.lat();
				}				
				if(lat < sw.lat()){
					lat = sw.lat();
				}				
				label_points.push(new GLatLng(lat, lng));
			});
			var label_poly = new GPolygon(label_points, "#990000", 1, 1, '#0000FF', 0, false);
			
			var label = new ELabel(label_poly.getBounds().getCenter(), i, 'map-grid-label', new GSize(-30, 6), 100, true);
			
			map.addOverlay(label);
			if ($('#view-grid-labels:checked').length <= 0) {
				label.hide();
			}
			label.id = geom.id;
			grid_labels[i] = label;						
		}
	});
};

function addCounties(geoms) {
	var sw = map.getBounds().getSouthWest();
	var ne = map.getBounds().getNorthEast();
	$.each(geoms, function(id, county) {
		var name = county['name'];
		var geom = county['geom'];
		if (counties[id] === undefined) {
			counties[id] = {};
			county_labels[id] = {};
			var points = [];
			var label_points = [];
			$.each(geom, function(i, point){
				points.push(new GLatLng(parseFloat(point[1]), parseFloat(point[0])));
				var lat = parseFloat(point[1]);
				var lng = parseFloat(point[0]);
				if (lng > ne.lng()) {
					lng = ne.lng();
				}
				if (lng < sw.lng()) {
					lng = sw.lng();
				}
				if (lat > ne.lat()) {
					lat = ne.lat();
				}
				if (lat < sw.lat()) {
					lat = sw.lat();
				}
				label_points.push(new GLatLng(lat, lng));
			});
			var polygon = new GPolygon(points, "#0000FF", 1, 1, '#0000FF', 0, false);
			var center = getCentroid(label_points);
			var label = new ELabel(center, name, 'map-county-label', new GSize(-30, 6), 100, true);
			map.addOverlay(polygon);
			if ($('#view-counties:checked').length <= 0) {
				polygon.hide();
			}
			map.addOverlay(label);
			if ($('#view-county-labels:checked').length <= 0) {
				label.hide();
			}
			polygon.id = geom.id;
			label.id = geom.id;
			county_labels[id] = label;
			counties[id] = {
				'name': name,
				'shape': polygon
			};
		}
		else { //Reload label for positioning only
			var label_points = [];
			$.each(geom, function(j, point){
				var lat = parseFloat(point[1]);
				var lng = parseFloat(point[0]);
				if (lng > ne.lng()) {
					lng = ne.lng();
				}
				if (lng < sw.lng()) {
					lng = sw.lng();
				}
				if (lat > ne.lat()) {
					lat = ne.lat();
				}
				if (lat < sw.lat()) {
					lat = sw.lat();
				}
				label_points.push(new GLatLng(lat, lng));
			});
			var center = getCentroid(label_points);
			map.removeOverlay(county_labels[id]);
			var label = new ELabel(center, name, 'map-county-label', new GSize(-30, 6), 100, true);
			map.addOverlay(label);
			if ($('#view-county-labels:checked').length <= 0) {
				label.hide();
			}
			label.id = geom.id;
			county_labels[id] = label;
		}
	});
};

function getCentroid(points) {
	var area = 0;
	var center_lat = 0;
	var center_lng = 0;
	var i;
	for (i = 0; i < points.length - 1; i++) {
		var first_part = points[i].lat() + points[i + 1].lat();
		var second_part = points[i].lat() * points[i + 1].lng() - points[i+1].lat() * points[i].lng();
		center_lat += (points[i].lat() + points[i + 1].lat()) * (points[i].lat() * points[i + 1].lng() - points[i+1].lat() * points[i].lng());
		center_lng += (points[i].lng() + points[i + 1].lng()) * (points[i].lat() * points[i + 1].lng() - points[i+1].lat() * points[i].lng());
		area += (points[i].lat() * points[i + 1].lng() - points[i + 1].lat() * points[i].lng());
	}
	area = area / 2;
	center_lat = center_lat / (6 * area);
	center_lng = center_lng / (6 * area);
	return new GLatLng(center_lat, center_lng);
}

function drawCounties() {
	if (processing_counties){
		setTimeout("drawCounties()", 500);
		return;
	}
	processing_counties = true;
	if (($('#view-counties:checked').length > 0) || ($('#view-county-labels:checked').length > 0)) {
		//Get all grids that should be displayed, use grids variable as a hash with key (LongLat) of the grid. 
		var zoom = map.getZoom();
		if (zoom >= 10) {
			var baseURL = getBaseURL();
			if (baseURL != null) {
				var sw = map.getBounds().getSouthWest();
				var ne = map.getBounds().getNorthEast();
				var params = {};
				params['ne_long'] = ne.lng();
				params['ne_lat'] = ne.lat();
				params['sw_long'] = sw.lng();
				params['sw_lat'] = sw.lat();
				if ($("#nav-sel-1").hasClass('nav-menu-active')) {
					params['ins_plan'] = "vegetation"
				}
				else {
					params['ins_plan'] = "rainfall"
				}
				$.ajax({
					type: "GET",
					url: baseURL + "/get_counties",
					data: params,
					dataType: "json",
					beforeSend: function(){
						$("#loading").html("Loading...");
						$("#loading").show();
					},
					success: function(json){
						addCounties(json);
					},
					complete: function(){
						$("#loading").fadeOut("normal");
						processing_counties = false;
					}
				});
			}
			else {
				processing_counties = false;
			}
		}
		else {
			//Remove all counties on zoom out
			jQuery.each(counties, function(id, county){
				map.removeOverlay(county['shape']);
				map.removeOverlay(county_labels[id]);
				delete counties[id];
				delete county_labels[id];
			});
			processing_counties = false;
		}
		//Remove counties off the screen
		var map_bounds = map.getBounds();
		jQuery.each(counties, function(id, county){
			if (!(map_bounds.intersects(county['shape'].getBounds()))) {
				map.removeOverlay(county['shape']);
				map.removeOverlay(county_labels[id]);
				delete counties[id];
				delete county_labels[id];
			}
		});
	} else {
		processing_counties = false;
	}
};

function drawGrids() {
	//prevent overlapping of drawGrids calls
	if (processing_grids){
		setTimeout("drawGrids()", 500);
		return;
	}
	processing_grids = true;
	if( refresh_grids )
	{
		//Remove all grids/grid_labels
		jQuery.each(grids, function(id, grid){
			map.removeOverlay(grid);
			map.removeOverlay(grid_labels[id]);
			delete grid_labels[id];
			delete grids[id];
		});
		//Refresh markers
		$.each(markers, function(i, marker) {
			getLocationName(i);
		});
		
		refresh_grids = false;
	}
	
	if (($('#view-grids:checked').length > 0) || ($('#view-grid-labels:checked').length > 0)) {
		//Get all grids that should be displayed, use grids variable as a hash with key (LongLat) of the grid. 
		var zoom = map.getZoom();
		$('#zoom').html(zoom);
		if (zoom >= 10) {
			var baseURL = getBaseURL();
			if (baseURL != null) {
				var sw = map.getBounds().getSouthWest();
				var ne = map.getBounds().getNorthEast();
				var params = {};
				params['ne_long'] = ne.lng();
				params['ne_lat'] = ne.lat();
				params['sw_long'] = sw.lng();
				params['sw_lat'] = sw.lat();
				if ($("#nav-sel-1").hasClass('nav-menu-active')) {
					params['ins_plan'] = "vegetation"
				}
				else {
					params['ins_plan'] = "rainfall"
				}
				$.ajax({
					type: "GET",
					url: baseURL + "/get_grids",
					data: params,
					dataType: "json",
					beforeSend: function(){
						$("#loading").html("Loading...");
						$("#loading").show();
					},
					success: function(json){
						addGrids(json);
					},
					complete: function(){
						$('#loading').fadeOut("normal");
						processing_grids = false;
					}
				});
			}
			else {
				processing_grids = false;
			}
		}
		else {
			//Remove all grids on zoom out
			jQuery.each(grids, function(id, grid){
				map.removeOverlay(grid);
				map.removeOverlay(grid_labels[id]);
				delete grids[id];
				delete grid_labels[id];
			});
			processing_grids = false;
		}
		//Remove grids off the screen	
		var map_bounds = map.getBounds();
		jQuery.each(grids, function(id, grid){
			if (!(map_bounds.intersects(grid.getBounds()))) {
				map.removeOverlay(grid);
				map.removeOverlay(grid_labels[id]);
				delete grids[id];
				delete grid_labels[id];
			}
		});
	} else {
		processing_grids = false;
	};
};

function getParameter( name )
{
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return "";
  else
    return results[1];
};

function getBaseURL() {
	var results = /\/rma\/(vi|ri)\/(api|prf)\/maps/.exec(window.location.href);
	if (results != null) {
		results = results [0];
	}
	return results;
}

jQuery.fn.onclickPrint = function() {
	this.click(function() {
		var baseURL = getBaseURL();
		if (baseURL != null) {
			var url_params = "";
			//get midpoint based on map boundary
			var bounds = map.getBounds();
			url_params = "?longitude=" + bounds.getCenter().lng() 
			+ "&latitude=" + bounds.getCenter().lat() 
			+ "&zoom=" + map.getZoom() 
			+ "&draw_grids=" + $("#view-grids").attr('checked')
			+ "&draw_grid_labels=" + ($("#view-grids").attr('checked') && $("#view-grid-labels").attr('checked'))
			+ "&draw_counties=" + $("#view-counties").attr('checked')
			+ "&draw_county_labels=" + ($("#view-counties").attr('checked') && $("#view-county-labels").attr('checked'))
			save_map_items_to_db(function () {
				window.open(baseURL + '/print' + url_params, 'print_window', 'width=800,height=800,scrollbars=1,resizeable=1');
			});
		}
	});
	return this;
};

function onSearch() {
	var error = false;
	var use_geocoder = false;
	var error_message = "";
	//check for lat / long string
	//get rid of extra spaces
	var pieces = $('#location-input').val().split(" ");
	if (pieces.length == 2) {
		//check for N S E W
		var ns = /[NnSs]/.exec(pieces[0]);
		pieces[0] = pieces[0].replace(/[NnSs]/, "");
		var ew = /[EeWw]/.exec(pieces[1]); 
		pieces[1] = pieces[1].replace(/[EeWw]/, "");
		lat = parseFloat(pieces[0]);
		lon = parseFloat(pieces[1]);
		if (!(isNaN(lat) || isNaN(lon))) {
			if (((ns == "S") || (ns == "s")) && (lat > 0)) {
				lat = 0 - lat;
			}
			if (((ew == "W") || (ew == "w")) && (lon > 0)) {
				lon = 0 - lon;
			}
			var point = new GLatLng(lat, lon);
			map.clearOverlays();
			map.setCenter(point, 13);
			setMarker(point);
		}
		else {
			use_geocoder = true;
		}
	} 
	else {
		use_geocoder = true;
	}
	if (use_geocoder) {
		//pass potential address to geocoder
		geocoder.getLatLng($('#location-input').val(), function(point){
			if (!point) {
				alert("Could not find a valid location. Please try searching again.");
			}
			else {
				map.clearOverlays();
				map.setCenter(point, 13);
				setMarker(point);
			}
		});
	}
	return false;
};

jQuery.fn.onclickSearch = function() {
	this.click(function() {
		onSearch();
	});
	return this;
};

jQuery.fn.onchangeViewCounties = function() {
	$(this).click(function() {
		if ($(this).attr('checked')) {
			var map_bounds = map.getBounds();
			$.each(counties, function(id, county) {
				if ((map_bounds.intersects(county['shape'].getBounds()))) {
					county['shape'].show();
				}
			});
			drawCounties();
						
		} else {
			//Remove all but don't delete
			$.each(counties, function(i, county) {
				county['shape'].hide();
			});
			
		}
	})
}

jQuery.fn.onchangeViewGrids = function() {
	$(this).click(function() {
		if ($(this).attr('checked')) {
			var map_bounds = map.getBounds();
			$.each(grids, function(i, grid) {
				if ((map_bounds.intersects(grid.getBounds()))) {
					grid.show();
				}
			});
			drawGrids();
		} else {
			//Remove all but don't delete
			$.each(grids, function(i, grid) {
				grid.hide();
			});
			//setMarker(current_point);
		}
	})
};

jQuery.fn.onchangeViewMarkerInfo = function() {
	$(this).click(function() {
		if ($(this).attr('checked')) {
			if (current_marker_id) {
				if (markers[current_marker_id]) {
					markers[current_marker_id].openInfoWindowHtml(marker_info[current_marker_id]);
				}
			}
		}
		else
		{
			if (current_marker_id) {
				if (markers[current_marker_id]) {
					markers[current_marker_id].closeInfoWindow();
				}
			}
		}
	})
}

jQuery.fn.onchangeMapType = function() {
	$(this).change(function() {
		var baseURL = getBaseURL();
		if (baseURL != null) {
			var center = map.getCenter();
			var params_string = "?map=" + $('#map-type').val() +
			"&center_lat=" + center.lat() + 
			"&center_long=" + center.lng() + 
			"&zoom=" + map.getZoom() +
			"&draw_grids=" + $("#view-grids").attr('checked') +
			"&draw_grid_labels=" + ($("#view-grids").attr('checked') && $("#view-grid-labels").attr('checked')) +
			"&draw_counties=" + $("#view-counties").attr('checked') +
			"&draw_county_labels=" + $("#view-county-labels").attr('checked') +
			"&view_info=" + $("#view-marker-info").attr('checked');
			if ($("#nav-sel-1").hasClass('nav-menu-active')) {
				params_string += "&ins_plan=vegetation";
			}
			else {
				params_string += "&ins_plan=rainfall";
			}
			if ((current_marker_id != null) && (current_marker_id != 0)) {
				params_string += "&marker_long=" + markers[current_marker_id].getLatLng().lng() +
				"&marker_lat=" +
				markers[current_marker_id].getLatLng().lat()
			}
			location.href = baseURL + params_string;
		}
	});
};

jQuery.fn.onchangeCountyLabels = function() {
	$(this).click(function() {
		if ($(this).attr('checked')) {
			var map_bounds = map.getBounds();
			$.each(counties, function(id, county) {
				if ((map_bounds.intersects(county['shape'].getBounds()))) {
					county_labels[id].show();
				}
			});
			drawCounties();
		} else {
			//Remove all but don't delete
			$.each(counties, function(i, county) {
				county_labels[id].hide();
			});
		}
	});
}

jQuery.fn.onchangeGridLabels = function() {
	$(this).click(function() {
		if ($(this).attr('checked')) {
			var map_bounds = map.getBounds();
			$.each(grids, function(i, grid) {
				if ((map_bounds.intersects(grid.getBounds()))) {
					grid_labels[i].show();
				}
			});
			drawGrids();
		} else {
			//Remove all but don't delete
			$.each(grids, function(i, grid) {
				grid_labels[i].hide();
			});
		}
	})
}

jQuery.fn.onclickMarkerButton = function() {
	$(this).click(function() {
		if (select('marker_btn')) {
			if (shape_being_drawn != null) {
				//programatically end shape drawing
				if (shape_being_drawn.getVertexCount() > 0) {
					shape_being_drawn.insertVertex(shape_being_drawn.getVertexCount(), shape_being_drawn.getVertex(0));
					GEvent.trigger(shape_being_drawn, "endline");
				} else {
					//a point has notbeen drawn yet.
					shape_being_drawn.disableEditing();
					map.removeOverlay(shape_being_drawn);
					delete shapes[shapeCounter_];
				}
			}
			if (marker_listener == null) {
				marker_listener = GEvent.addListener(map, 'click', marker_click_listener);
			}
		}
		single_marker_set = false;
	});
}

jQuery.fn.onclickMultiMarkerButton = function() {
	$(this).click(function() {
		if (select("multi_marker_btn")) {
			if (shape_being_drawn != null) {
				//programatically end shape drawing
				if (shape_being_drawn.getVertexCount() > 0) {
					shape_being_drawn.insertVertex(shape_being_drawn.getVertexCount(), shape_being_drawn.getVertex(0));
					GEvent.trigger(shape_being_drawn, "endline");
				} else {
					//a point has notbeen drawn yet.
					shape_being_drawn.disableEditing();
					map.removeOverlay(shape_being_drawn);
					delete shapes[shapeCounter_];
				}
			}
			if (marker_listener == null) {
				marker_listener = GEvent.addListener(map, 'click', marker_click_listener);
			}
		}
	});
}

jQuery.fn.onclickShapeButton = function() {
	$(this).click(function() {
		if (select("shape_btn")) {
			// remove old listeners
			if (marker_listener != null) {
				GEvent.removeListener(marker_listener);
				marker_listener = null;
			}
			var polygon = new GPolygon([], '#FFC000', 2, 0.7, '#FFC000', 0.2);
			shape_being_drawn = polygon;
			startDrawing(polygon, "Shape " + (++shapeCounter_), '#00FF00');
		}
	});
}

jQuery.fn.onmousedownClearButton = function() {
	$(this).mousedown(function() {
		$(this).addClass("pushed");
		$(this).removeClass("not-pushed");
	});
}

jQuery.fn.onmouseupClearButton = function() {
	$(this).mouseup(function() {
		$(this).addClass("not-pushed");
		$(this).removeClass("pushed");
		clearShapes();
	});
}

jQuery.fn.onmouseoutClearButton = function() {
	$(this).mouseout(function () {
		$(this).addClass("not-pushed");
		$(this).removeClass("pushed");
	});
}

// A ZoomToGridControl is a GControl that displays textual "Zoom In"
function ZoomToGridControl() {
}

ZoomToGridControl.prototype = new GControl();

// Creates a one DIV for each of the buttons and places them in a container
// DIV which is returned as our control element. We add the control to
// to the map container and return the element for the map class to
// position properly.
ZoomToGridControl.prototype.initialize = function(map) {
	var zoom_holder = document.createElement("div");
	$(zoom_holder).attr('id', 'zoom-control');
  	var zoom_button = document.createElement("div");
  	$(zoom_button).addClass("zoom-not-pushed");
	var zoom_button_pushed = document.createElement("div");
	$(zoom_button_pushed).addClass("zoom-pushed");
   
	GEvent.addDomListener(zoom_holder, "mousedown", function() {
		$(zoom_button).removeClass("zoom-not-pushed");
		$(zoom_button).addClass("zoom-pushed");
	});
	GEvent.addDomListener(zoom_holder, "mouseup", function() {
		$(zoom_button).removeClass("zoom-pushed");
		$(zoom_button).addClass("zoom-not-pushed");
		map.setZoom(10);
	});
	GEvent.addDomListener(zoom_holder, "mouseout", function() {
		$(zoom_button).removeClass("zoom-pushed");
		$(zoom_button).addClass("zoom-not-pushed");
	});

	$(zoom_holder).append(zoom_button);
  	map.getContainer().appendChild(zoom_holder);
  	return zoom_button;
}

ZoomToGridControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(5, 290));
}

GLargeMapControl3D.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(20, 5));
}

//MULTI MARKER SUPPORT

function select(buttonId) {
	if (!($("#" + buttonId).hasClass('selected'))) {
		document.getElementById("marker_btn").className = "unselected";
		document.getElementById("multi_marker_btn").className = "unselected";
		document.getElementById("shape_btn").className = "unselected";
		
		document.getElementById(buttonId).className = "selected";
		return true;
	}
	return false;
}

function getIcon(color) {
	if (!color) {
		color = "blue";
	}
  	var icon = new GIcon(G_DEFAULT_ICON);
  	icon.image = "http://google.com/mapfiles/ms/micons/" + color + ".png";
  	icon.iconSize = new GSize(32, 32);
  	icon.iconAnchor = new GPoint(15, 32);
  	return icon;
}

function updateShapeGenerator(shapeCounter_, cells) {
	var cell = cells.desc;
	var shape = shapes[shapeCounter_];
	var label = shape_labels[shapeCounter_];
	var counter = shapeCounter_;
	return function(poly){
			var area = poly.getArea();
			var points = poly.getVertexCount();
			//cell.innerHTML = (Math.round(area / 10000) / 100) + "km<sup>2</sup>";
			var acres = Math.round(area * 0.247105381) / 1000;
			if (acres > 100000) {
				acres = acres.toExponential(5);
			}
			$(cell).html(acres + " acres");
			map.removeOverlay(label);
			label = new ELabel(poly.getBounds().getCenter(), 'Shape ' + counter, 'map-shape-label', new GSize(-30, 6), 100, true);
			shape_labels[counter] = label;
			map.addOverlay(label);
		}
}

function startDrawing(poly, name, color) {
	map.addOverlay(poly);
	shapes[shapeCounter_] = poly;
	poly.enableDrawing(options);
	poly.enableEditing({onEvent: "mouseover"});
	poly.disableEditing({onEvent: "mouseout"});
	GEvent.addListener(poly, "endline", function() {
 		// set back to single marker when finished
		shape_being_drawn = null;
		poly.disableEditing();
		if ($("#shape_btn").hasClass("selected")) {
			select('marker_btn');
			if (marker_listener == null) {
				marker_listener = GEvent.addListener(map, 'click', marker_click_listener);
			}
		}
		// add new entry to table
   	 	var cells = addFeatureEntry('shape', name);
		var label = new ELabel(poly.getBounds().getCenter(), 'Shape' + shapeCounter_ , 'shape-label', new GSize(-30, 6), 100, true);
		map.addOverlay(label);
		shape_labels[shapeCounter_] = label;
		var update = updateShapeGenerator(shapeCounter_, cells);
		GEvent.addListener(poly, "lineupdated", function() {
			update(this);
		});
    	GEvent.addListener(poly, "click", function(latlng, index) {
      		if (typeof index == "number") {
       			poly.deleteVertex(index);
      		}
    	});
	});
}

function addFeatureEntry(type, name) {
	var counter = 0;
	if (type == 'pin') {
		counter = markerCounter_;
	} else {
		counter = shapeCounter_;
	}
	currentRow_ = document.createElement("tr");
	if (type == 'pin') {
		$(currentRow_).addClass("clickable");
	}
	$(currentRow_).attr('id', type + '_' + counter);
	var colorCell = document.createElement("td");
	$(colorCell).attr('id', 'color_' + counter);
	if (type == 'pin') {
		$(colorCell).addClass('selected-table-cell');
	} else {
		$(colorCell).addClass('shape-table-cell');
	}
	$(colorCell).css({
	'text-align': 'center'
	});
	$(colorCell).html(counter);
	currentRow_.appendChild(colorCell);
	var descriptionCell = document.createElement("td");
	$(descriptionCell).attr('id', 'description_' + counter);
	$(descriptionCell).attr('nowrap', 'nowrap');
	currentRow_.appendChild(descriptionCell);
	featureTable_.appendChild(currentRow_);
	$("#featuretable-holder").show();
	return {desc: descriptionCell, color: colorCell};
}

//Closure to call updateMarker on proper marker
function updateHighlightGenerator(markerCounter, opt_changeColor) {
	return function() {
		updateMarkerHighlight(markerCounter, opt_changeColor);
	}
}

function updateLocationGenerator(markerCounter) {
	return function() {
		getLocationName(markerCounter);
	}
}

function updateMarkerHighlight(id, opt_changeColor) {
	var marker = markers[id];
	var cells = pin_cells[id];
	if (opt_changeColor) {
		$.each(markers, function(i, pin) {
			if (pin.getIcon().image == getIcon('blue').image) {
				pin.setImage(getIcon('red').image);
			}
		});
		$.each(pin_cells, function(i , cells) {
			if ($(cells.color).hasClass('selected-table-cell')) {
				$(cells.color).removeClass('selected-table-cell');
				$(cells.color).addClass('nonselected-table-cell');
			}
		})
		marker.setImage(getIcon('blue').image);
		$(cells.color).removeClass('nonselected-table-cell');
		$(cells.color).addClass('selected-table-cell');
		
		getLocationName(id);
  	}
}

function clearShapes(){
	//Remove all user defined shapes
	jQuery.each(shapes, function(id, shape){
		map.removeOverlay(shape);
		map.removeOverlay(shape_labels[id]);
		delete shapes[id];
		delete shape_labels[id];
	});	
	shapeCounter_ = 0;
	
	// Remove all user markers
	jQuery.each(markers, function(id, pin){
		map.removeOverlay(pin);
		delete markers[id];
	});	
	markerCounter_ = 0;
	
	single_marker_set = false;
	// Clear table entries
	$("#featuretbody").empty();
	$("#featuretable-holder").hide();
}

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

//elabel version 1.7 - by Mike Williams.
function ELabel(point, html, classname, pixelOffset, percentOpacity, overlap){
this.point=point;
this.html=html;
this.classname=classname||"";
this.pixelOffset=pixelOffset||new GSize(0,0);
if (percentOpacity){
if(percentOpacity<0){percentOpacity=0;}
if(percentOpacity>100){percentOpacity=100;}}
this.percentOpacity=percentOpacity;
this.overlap=overlap||false;
this.hidden=false;
}
ELabel.prototype=new GOverlay();
ELabel.prototype.initialize=function(map){
var div=document.createElement("div");
div.style.position="absolute";
div.innerHTML='<div class="'+this.classname+'">'+this.html+'</div>';
map.getPane(G_MAP_FLOAT_SHADOW_PANE).appendChild(div);
this.map_=map;
this.div_=div;
if (this.percentOpacity){
if(typeof(div.style.filter)=='string'){div.style.filter='alpha(opacity:'+this.percentOpacity+')';}
if(typeof(div.style.KHTMLOpacity)=='string'){div.style.KHTMLOpacity=this.percentOpacity/100;}
if(typeof(div.style.MozOpacity)=='string'){div.style.MozOpacity=this.percentOpacity/100;}
if(typeof(div.style.opacity)=='string'){div.style.opacity=this.percentOpacity/100;}}
if (this.overlap){
var z=GOverlay.getZIndex(this.point.lat());
this.div_.style.zIndex=z;
}
if (this.hidden){
this.hide();
}}
ELabel.prototype.remove=function(){
this.div_.parentNode.removeChild(this.div_);
}
ELabel.prototype.copy=function(){
return new ELabel(this.point, this.html, this.classname, this.pixelOffset, this.percentOpacity, this.overlap);
}
ELabel.prototype.redraw=function(force){
var p=this.map_.fromLatLngToDivPixel(this.point);
var h=parseInt(this.div_.clientHeight);
this.div_.style.left=(p.x+this.pixelOffset.width)+"px";
this.div_.style.top=(p.y+this.pixelOffset.height - h)+"px";
}
ELabel.prototype.show=function(){
if (this.div_){
this.div_.style.display="";
this.redraw();
}
this.hidden=false;
}
ELabel.prototype.hide=function(){
if (this.div_){
this.div_.style.display="none";
}
this.hidden=true;
}
ELabel.prototype.isHidden=function(){
return this.hidden;
}
ELabel.prototype.supportsHide=function(){
return true;
}
ELabel.prototype.setContents=function(html){
this.html=html;
this.div_.innerHTML='<div class="'+this.classname+'">'+this.html+'</div>';
this.redraw(true);
}
ELabel.prototype.setPoint=function(point){
this.point=point;
if (this.overlap){
var z=GOverlay.getZIndex(this.point.lat());
this.div_.style.zIndex=z;
}
this.redraw(true);
}
ELabel.prototype.setOpacity=function(percentOpacity){
if (percentOpacity){
if(percentOpacity<0){percentOpacity=0;}
if(percentOpacity>100){percentOpacity=100;}}
this.percentOpacity=percentOpacity;
if (this.percentOpacity){
if(typeof(this.div_.style.filter)=='string'){this.div_.style.filter='alpha(opacity:'+this.percentOpacity+')';}
if(typeof(this.div_.style.KHTMLOpacity)=='string'){this.div_.style.KHTMLOpacity=this.percentOpacity/100;}
if(typeof(this.div_.style.MozOpacity)=='string'){this.div_.style.MozOpacity=this.percentOpacity/100;}
if(typeof(this.div_.style.opacity)=='string'){this.div_.style.opacity=this.percentOpacity/100;}}}
ELabel.prototype.getPoint=function(){
return this.point;
}
ELabel.prototype.U=function(){
return this.point;
}
ELabel.prototype.V=function(){
return this.point;
}
ELabel.prototype.W=function(){
return this.point;
}
ELabel.prototype.X=function(){
return this.point;
}
ELabel.prototype.Y=function(){
return this.point;
}
ELabel.prototype.Z=function(){
return this.point;
}

/*
* LabeledMarker Class
*
* Copyright 2007 Mike Purvis (http://uwmike.com)
* 
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* 
*       http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This class extends the Maps API's standard GMarker class with the ability
* to support markers with textual labels. Please see articles here:
*
*       http://googlemapsbook.com/2007/01/22/extending-gmarker/
*       http://googlemapsbook.com/2007/03/06/clickable-labeledmarker/
*/

/* Constructor */
function LabeledMarker(latlng, options){
    this.latlng = latlng;
    this.labelText = options.labelText || "";
    this.labelClass = options.labelClass || "markerLabel";
    this.labelOffset = options.labelOffset || new GSize(0, 0);
    
    this.clickable = options.clickable || true;
    
    if (options.draggable) {
        // This version of LabeledMarker doesn't support dragging.
        options.draggable = false;
    }
    
    GMarker.apply(this, arguments);
}


/* It's a limitation of JavaScript inheritance that we can't conveniently
   extend GMarker without having to run its constructor. In order for the
   constructor to run, it requires some dummy GLatLng. */
LabeledMarker.prototype = new GMarker(new GLatLng(0, 0));


// Creates the text div that goes over the marker.
LabeledMarker.prototype.initialize = function(map) {
        // Do the GMarker constructor first.
        GMarker.prototype.initialize.apply(this, arguments);
        
        var div = document.createElement("div");
        div.className = this.labelClass;
        div.innerHTML = this.labelText;
        div.style.position = "absolute";
        map.getPane(G_MAP_MARKER_PANE).appendChild(div);

        if (this.clickable) {
                // Pass through events fired on the text div to the marker.
                var eventPassthrus = ['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mouseout'];
                for(var i = 0; i < eventPassthrus.length; i++) {
                        var name = eventPassthrus[i];
                        GEvent.addDomListener(div, name, newEventPassthru(this, name));
                }

                // Mouseover behaviour for the cursor.
                div.style.cursor = "pointer";
        }
        
        this.map = map;
        this.div = div;
}

function newEventPassthru(obj, event) {
        return function() { 
                GEvent.trigger(obj, event);
        };
}

// Redraw the rectangle based on the current projection and zoom level
LabeledMarker.prototype.redraw = function(force) {
        GMarker.prototype.redraw.apply(this, arguments);
        
        // We only need to do anything if the coordinate system has changed
        if (!force) return;
        
        // Calculate the DIV coordinates of two opposite corners of our bounds to
        // get the size and position of our rectangle
        var p = this.map.fromLatLngToDivPixel(this.latlng);
        var z = GOverlay.getZIndex(this.latlng.lat());
        
        // Now position our DIV based on the DIV coordinates of our bounds
        this.div.style.left = (p.x + this.labelOffset.width) + "px";
        this.div.style.top = (p.y + this.labelOffset.height) + "px";
        this.div.style.zIndex = z + 1; // in front of the marker
}

// Remove the main DIV from the map pane, destroy event handlers
LabeledMarker.prototype.remove = function() {
        GEvent.clearInstanceListeners(this.div);
        this.div.parentNode.removeChild(this.div);
        this.div = null;
        GMarker.prototype.remove.apply(this, arguments); 
}

/*
    http://www.JSON.org/json2.js
    2009-06-29

    Public Domain.
*/
var JSON=JSON||{};(function(){function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
if(typeof rep==='function'){value=rep.call(holder,key,value);}
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
v=partial.length===0?'[]':gap?'[\n'+gap+
partial.join(',\n'+gap)+'\n'+
mind+']':'['+partial.join(',')+']';gap=mind;return v;}
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+
mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
return str('',{'':value});};}
if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
return reviver.call(holder,key,value);}
cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
throw new SyntaxError('JSON.parse');};}}());
