var demandmap = demandmap || {};

// TODO implement _t()
var i18n = i18n || {};

// language strings
jQuery.i18n.addDictionary({
	'REALLYDELETE': "Do you really want to delete this point?"
});

;(function($) {
	
	$.fn.DemandMap_MapEdit = function(mapSelector, _options) { 
		
		// config
		var defaults = {
			'zoomSelected': 12,
			'baseCountryCode': "NZ",
			'markerIconsByID': [],
			'zoomStart': 5, // roughly fits New Zealand boundaries
			'lat': -41.28648,
			'lng': 174.776217, // Wellington, New Zealand
			'zoomAccuracyBase': 9, // @see http://code.google.com/apis/maps/documentation/reference.html#GGeoAddressAccuracy
			'defaultMarkerIcon': null
		};
		

		
		return this.each(function(){
			defaults.defaultMarkerIcon

			// ######## private instance properties #########
			var options = $.extend({}, defaults, _options);			

			// Reference to this control
			var $this = $(this);
			var container = this;
			
			var map = $(mapSelector);
			
			var myMarker;
			
			// alert user before deleting a point
			$('.deletepoint a', container).bind('click',function(e) {
				return confirm($.i18n._t('REALLYDELETE'));
			});
			
			// Build the JSON version of a single point
			var existingCategoryID = $('select[name=CategoryID]', container).val();
			var markerData = {};

			addMode = document.URL.match('/addpoint');
			
			// if categoryID is NOT specified and NOT in addMode, it is in edit mode
			if(existingCategoryID && !addMode) {
				var zoom = options.zoomSelected;
					
				// populate markerdata from form and load it as a marker
				$("input, select", container).each(function() {
					markerData[$(this).attr('name')] = $(this).val();
				});

				markerData.Point = { x : markerData['Point[x]'], y : markerData['Point[y]'] };
				
				myMarker = updateMarker(
					new GLatLng(Number(markerData.Point.y), Number(markerData.Point.x)),
					zoom
				);
			} else {
				markerData.Point = { x : options.lng, y : options.lat };
				markerData.icon = options.defaultMarkerIcon;
				var zoom = options.zoomStart;
				// add marker to map
				var markers = map.fn('addMarkers', [markerData]);
				myMarker = markers[0];
				// don't show the marker initially if no data was loaded
				myMarker.hide();
				// if it's in addMode and CategoryID is specify, show the marker
				if (existingCategoryID) {
					updateMarker(
						myMarker.getPoint(),
						$('select[name=CategoryID]', container).val()
					);
					myMarker.show();
				}
			}
			
			map.fn('setCenter', 
				new GLatLng(Number(markerData.Point.y), Number(markerData.Point.x)),
				zoom
			);
	
			// Set up geo-coding on address fields
			$("input[name='StreetNumber'], input[name='Street'], input[name='Suburb'], input[name='City'], input[name='PostalCode'], select[name='Region']", container)
				.bind('change', function() {
					var address = $("input[name='StreetNumber']", container).val() + " " + $("input[name='Street']", container).val()
						+ ", " +  $("input[name='Suburb']", container).val() + ", " + $("input[name='City']", container).val()
						+  " " + $("input[name='PostalCode']", container).val() + ", " + $("select[name='Region']", container).val()
					//console.log(address);
	
					var geocoder = new GClientGeocoder();
					geocoder.setBaseCountryCode(options.baseCountryCode);
					geocoder.getLocations(address, function(locations) {
						//console.log(locations);
						if(locations.Status.code == 200 && locations.Placemark[0].AddressDetails.Country.CountryNameCode == options.baseCountryCode) {
							var placemark = locations.Placemark[0]
							updateFields(placemark);
						}
					});
				});
				
			$('select[name=CategoryID]', container).bind('change', function(e) {
				updateMarker(
					myMarker.getPoint(),
					$('select[name=CategoryID]', container).val()
				);
			});
	
			/*
			var url = $.sprintf('api/v1/DemandPoint.json?OwnerID=%d', currentUserID); 
	
			// Do a JSON request for my points
			$.getJSON(url, function(data) {
				// Add those points to the map
				map.fn('addMarkers', data);
			});
			*/
		
			function updateFields(placemark) {
				var latLng = new GLatLng(placemark.Point.coordinates[1], placemark.Point.coordinates[0]);

				updateMarker(latLng, $('select[name=CategoryID]', container).val());
				
				// Update latlng point and zoom based on placemark accuracy
				map.fn('setCenter', latLng, options.zoomAccuracyBase + placemark.AddressDetails.Accuracy);
				
				$('#Point-x', container).val(latLng.lng());
				$('#Point-y', container).val(latLng.lat());
				
				// Decode address
				var thoroughfare = placemark.AddressDetails.Country.Locality.Thoroughfare.ThoroughfareName;
				if(thoroughfare.match(/^([0-9]+) +(.*)$/)) {
					var streetNumber = RegExp.$1;
					var street = RegExp.$2;
				} else {
					var streetNumber = "";
					var street = thoroughfare;
				}
				var postalCode = placemark.AddressDetails.Country.Locality.PostalCode.PostalCodeNumber;
				var suburb = placemark.AddressDetails.Country.Locality.LocalityName;
				var country = placemark.AddressDetails.Country.CountryNameCode;
			
				// Update empty address fields
				if(!$("input[name='StreetNumber']", container).val()) $("input[name='StreetNumber']", container).val(streetNumber);
				if(!$("input[name='Street']", container).val()) $("input[name='Street']", container).val(street);
				if(!$("input[name='Suburb']", container).val()) $("input[name='Suburb']", container).val(suburb);
				if(!$("input[name='PostalCode']", container).val()) $("input[name='PostalCode']", container).val(postalCode);
				if(!$("input[name='Country']", container).val()) $("input[name='Country']", container).val(country);
			}
			
			function updateMarker(latLng, categoryID) {
				var geocoder = new GClientGeocoder();
				geocoder.setBaseCountryCode(options.baseCountryCode)
				geocoder.getLocations(latLng , showRegion);
				
				var markerData = {
					CategoryID: categoryID,
					Point: latLng,
					draggable: true
				};
				map.fn('clearMarkers');
				if(!Number(categoryID)) markerData.icon = options.defaultMarkerIcon;
				
				var markers = map.fn('addMarkers', [markerData]);
				markers[0].show();
				
				GEvent.addListener(markers[0], 'dragend', function(e) {
					var latLng = this.getPoint();
					$('#Point-x', container).val(latLng.lng());
					$('#Point-y', container).val(latLng.lat());
					
					geocoder.getLocations(latLng , showRegion);
				});
				
				myMarker = markers[0];
				
				return markers[0];
			}
			
			function showRegion(response) {
				$("select[name='Region']").val('');
				if (response || response.Status.code == 200) {
					place = response.Placemark[1];
					region = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
					$("select[name='Region']").val(region);
				}
			}
		})
	}
	
	// reset dropdownfile region to nothing at first
	$("select[name='Region']").val('');
})(jQuery);