var maps = [];
var geocoder;

function updateLatLngValues(mapId,marker){
	var lat = marker.getPosition().lat(),
		lng = marker.getPosition().lng();

	$('#' + mapId + '_lat').val(lat);
	$('#' + mapId + '_lng').val(lng);
}

function updateLocationName(mediaId,marker){
	var lat = marker.getPosition().lat(),
		lng = marker.getPosition().lng();

	// var location = lat+','+lng;
	// $('#' + mediaId).find('input.location_name').val(location);

	var target = $('#media_' + mediaId).find('input.location_name');
	geocode(lat,lng,target);
}

function geocode(lat,lng,target) {

	// Could do with caching these values, really? Or is that unecessary?
	// I'd like to reduce the load on Google Maps, but it's perhaps unlikely that we'd ever return a cached location

	var latlng = new google.maps.LatLng(lat, lng);

	var target = target; // Damn JS scoping...

	geocoder.geocode({'latLng': latlng}, function(results, status) {
		if (status == google.maps.GeocoderStatus.OK) {
			if (results[0]) {
				components = results[0].address_components;
				region = '';
				country = '';
				for (i = 0; i < components.length; i++) {
					// Get the "region" (this differs according to country)
					if (!region &&
						(
							(components[i].types[0] == 'colloquial_area')
							||
							(components[i].types[0] == 'administrative_area_level_1')
							||
							(components[i].types[0] == 'administrative_area_level_2')
							||
							(components[i].types[0] == 'administrative_area_level_3')
							||
							(components[i].types[0] == 'locality')
						)
					) {
						region = components[i].long_name;
					}

					if (components[i].types[0] == 'country') {
						country = components[i].long_name;
					}
				}
				if (region && country) {
					loc = region + ', '+country;
				}
				else {
					loc = results[0].formatted_address;
				}
				target.val(loc);
				target.attr('readonly','readonly');
				// The upload form uses .upload_row, the edit form uses .row
				target.parents('div.upload_row').removeClass('error');
				target.parents('div.row').removeClass('error');
			}
			else {
//				alert("Cannot find location");
				target.attr('title','Name this location');
				target.val(target.attr('title'));
				target.parents('div.upload_row').addClass('error');
				target.parents('div.row').addClass('error');
				target.attr('readonly','');
			}
		}
		else {
			/*
				This will fail for remote locations; most ocean points have no addresses!
				Will we need to somehow add these manually...?
			*/
			// alert("Geocoder failed due to: " + status);
			target.attr('title','Name this location');
			target.val(target.attr('title'));
			target.parents('div.upload_row').addClass('error');
			target.parents('div.row').addClass('error');
			target.attr('readonly','');
		}
	});
}

function closeBox(id){
	for (i=0;i<ibArray.length;i++) {
		if (ibArray[i].myId==id){
			myBox = ibArray[i].box;
			myBox.close();
		}
	}
}

function getMapInitPos(mapId){

	if (mapId == 'fancybox_map') {
		var lat = $('[name=overlay_lat]').val(),
			lng = $('[name=overlay_lng]').val(),
			markers = [{icon:'/img/icons/pin_tick.png', lat:lat, lng:lng, content:'<a class="btn" href="#"><span class="small">Add Location</span></a>'}];
	}

	if (mapId == 'media_edit_map') {
		var lat = $('[name=overlay_lat]').val() != 0 ? $('[name=overlay_lat]').val() : 3,
			lng = $('[name=overlay_lng]').val() != 0 ? $('[name=overlay_lng]').val() : 3,
			markers = [{icon:'/img/icons/pin_tick.png', lat:lat, lng:lng, content:'<a class="btn" href="#"><span class="small">Update Location</span></a>'}];
	}

	// main map
	initializeMap(mapId,'add_location',lat,lng,markers);
}

function initializeMap(mapId,type,lat,lng,markers) {

	var map;
	var myLatlng = new google.maps.LatLng(lat,lng);
	var markersArray = [];
	var myOptions = {};
	var ib;
	geocoder = new google.maps.Geocoder();

	// var cluster 	= true; // Are we clustering the markers?
	// This is now a global variable!
	var zoom_to_fit = true; // Are we zooming the map to fit?

	// Load the map

	var default_zoom = 2;
	var min_zoom = 1;
	var max_zoom = 10;


	// "Homepage"
	if (document.getElementById('home') !== null) {
		myOptions = {
			zoom: default_zoom,
			center: myLatlng,
			disableDoubleClickZoom: true,
			mapTypeId: google.maps.MapTypeId.SATELLITE,
			mapTypeControlOptions: {
				position: google.maps.ControlPosition.TOP_RIGHT,
				style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
			},
			streetViewControl: false,
			maxZoom: max_zoom,
			minZoom: min_zoom
		};

		cluster = false; // Don't cluster on the homepage

	}
	// "Add media" page
	else if (document.getElementById('multimedia_upload_edit') !== null) {
		myOptions = {
			zoom: default_zoom,
			center: myLatlng,
			disableDoubleClickZoom: true,
			mapTypeId: google.maps.MapTypeId.SATELLITE,
			mapTypeControlOptions: {
				position: google.maps.ControlPosition.TOP_RIGHT,
				style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
			},
			streetViewControl: false,
			minZoom: min_zoom
		};
	}
	// Other pages
	else {
		myOptions = {
			zoom: default_zoom,
			center: myLatlng,
			disableDoubleClickZoom: true,
			mapTypeId: google.maps.MapTypeId.SATELLITE,
			mapTypeControlOptions: {
				position: google.maps.ControlPosition.TOP_RIGHT,
				style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
			},
			streetViewControl: false,
			maxZoom: max_zoom,
			minZoom: min_zoom
		};

		// If this is the multimedia page and we're viewing all images, don't zoom to fit
		if ($('button[name=type]').val() == 'all') {
			zoom_to_fit = false;
		}
	}

	// small map type
	if (type == 'small') {
		myOptions = {
			zoom: 0,
	 		draggable: false,
			scrollwheel: false,
			disableDefaultUI: true,
			center: myLatlng,
			mapTypeId: google.maps.MapTypeId.ROADMAP,
			streetViewControl: false
		};
	}

	map = new google.maps.Map(document.getElementById(mapId), myOptions);

	for( var i=0; i<markers.length; i++) {
		var marker = null;
		var marker = new google.maps.Marker({
			position: new google.maps.LatLng(markers[i].lat,markers[i].lng),
			map: map,
			zIndex: markers[i].zIndex,
			draggable: type == 'add_location',
			icon: new google.maps.MarkerImage(
				markers[i].icon,
				new google.maps.Size(29, 34), // dimensions
				new google.maps.Point(0,0), // start point
				new google.maps.Point(15, 29) // anchor
			),
			content: markers[i].content
		});

		markersArray.push(marker);

		// update lat and lng values if small map
		// if (type == 'small') {
		// 		updateLatLngValues(mapId,markersArray[0]);
		// 	}

		if (marker.content) {

			// 'Add Location' type
			if (type == 'add_location') {
				var boxHTML = marker.content;

				var infoBoxOptions = {
					content: boxHTML,
					boxClass: 'infoBox add_locations',
					disableAutoPan: false,
					maxWidth: 0,
					pixelOffset: new google.maps.Size(25, -33),
					zIndex: null,
					closeBoxMargin: false,
					closeBoxURL: '',
					infoBoxClearance: new google.maps.Size(1, 1),
					isHidden: false,
					pane: "floatPane",
					enableEventPropagation: false
				};

				ib = new InfoBox(infoBoxOptions);
				ib.open(map, marker);

				// update input values
				updateLatLngValues(mapId,marker);

				// center marker on doubleclick
				google.maps.event.addListener(map, 'dblclick', function(e) {
					marker.setPosition(e.latLng);
					updateLatLngValues(mapId,marker);
				});

				// hide button on drag
				google.maps.event.addListener(marker, 'dragstart', function() {
					ib.hide();
				});
				// show button and update values on drag end
				google.maps.event.addListener(marker, 'dragend', function() {
					ib.show();
					updateLatLngValues(mapId,marker);
				});
			}

			if (type == 'results') {

				var boxHTML = marker.content;

				var infoBoxOptions = {
					content: boxHTML,
					boxClass: 'infoBox infoBoxContent',
					disableAutoPan: false,
					maxWidth: 0,
					pixelOffset: new google.maps.Size(25, -37),
					zIndex: null,
					closeBoxMargin: false,
					closeBoxURL: '',
					infoBoxClearance: new google.maps.Size(5, 5),
					isHidden: true,
					pane: "floatPane",
					enableEventPropagation: false
				};

				if (!ib) {
					ib = new InfoBox(infoBoxOptions);
				}

				google.maps.event.addListener(ib, 'domready', function(){
					$('.iw_content').find('.carousel_iw').jcarousel();
				});


				google.maps.event.addListener(marker, 'click', function() {
					if (!ib.div_ || ib.marker != this) {
						ib.setContent(this.content);
						ib.setPosition(this.getPosition());
						ib.open(map,this);
						ib.show();

						ib.marker = this;
					} else {
						ib.close();
					}
				});

			}

		}

	}

	// fit map to bounds, only if more than 1 marker and we've set zoom_to_fit
	if (markersArray.length > 1 && zoom_to_fit) {
		var bounds = new google.maps.LatLngBounds();
		for (var i=0; i<markersArray.length; i++) {
			bounds.extend(markersArray[i].getPosition());
		}
		map.fitBounds(bounds);
	}

	if (cluster) { // Are we clustering icons?
		var mcStyles = [{
			url: '/img/icons/cluster_2.png',
			height: 39,
			width: 40,
			anchor: [28, 35],
			textColor: 'transparent'
		},{
			url: '/img/icons/cluster_4.png',
			height: 51,
			width: 45,
			anchor: [31, 42],
			textColor: 'transparent'
		},{
			url: '/img/icons/cluster_6.png',
			height: 57,
			width: 60,
			anchor: [32, 53],
			textColor: 'transparent'
		},{
			url: '/img/icons/cluster_8.png',
			height: 68,
			width: 68,
			anchor: [38, 52],
			textColor: 'transparent'
		},{
			url: '/img/icons/cluster_10.png',
			height: 78,
			width: 74,
			anchor: [48, 48],
			textColor: 'transparent'
		}];

		// gridSize sets the size of an area that will be clustered; the higher the number, the more markers will be grouped into a single cluster
		// maxZoom is the highest zoom level at which icons will be clustered
		var mcOptions = {gridSize: 20, maxZoom: 6, styles: mcStyles};


		var markerCluster = new MarkerClusterer(map, markersArray, mcOptions);
	}

	maps[mapId] = {map:map, markers:markersArray};



}
