
var AllotmentGroupMap = function(){
	
	var mapId = 'ag-map-container';
	var map = null;
	var manager = null; // MarkerManager instance
	
	var lastBoundingBox = null;  
	var lastParams = null;
	var tooltip = null;
	var infoWindow = null;

	var queryInput = null;  // Where user can type text to filter
	var queryDefaultValue = ''; // Where user can type text to filter

	function init(){
		util.setLoading(true);
		MapUtils.loadAPI( build );
	}

	function build(){
		
		var lat = parseFloat( jQuery('#lat').val() );
		var lng = parseFloat( jQuery('#lng').val() );
		var agLocation = new GLatLng( lat, lng);

		// Create the map
		map = new GMap2( document.getElementById( mapId  ) );
		map.setCenter(agLocation , 13 );
		map.setUIToDefault();
		map.enableContinuousZoom(); 
				
		// Put allotmentgroup marker on the map		
		var icon = new GIcon( G_DEFAULT_ICON );
		icon.image = '/img/map/marker.png';
		
		var marker = new GMarker(agLocation, {
			icon:icon
		});
				
		map.addOverlay(marker);

		// Create the MapManager
		manager = new MarkerManager(map);

	}
	
	return {
		init:init
	}
}();


var SearchMap = function(){
	
	var map = null;
	var manager = null;
	var mapId = 'google-map';

	var tooltip = null;
	var infoWindow = null;

	var detailContainer = null;
	
	var activeMarker = null; // Were we store which marker was clicked
	
	// Will be filled with some properties we set in tpl (by calling getSettings )
	var settings = {};
	
	function init(){

		if ( map ) return true;
		getSettings();
		MapUtils.loadAPI( buildMap );
	}
	
	function buildMap(){
		
		if (map){
			return false;
		}

		// Create the map
		map = new GMap2(document.getElementById( mapId ));
		map.setCenter( new GLatLng( 53.448289, 5.786362), 10 );
		map.setUIToDefault();
		// Why doesn't this work ???
		//MapUtils.restrictViewAreaToAmeland();
		// create the MapManager
		manager = new MarkerManager(map);

		tooltip = jQuery('<div id="tooltip"></div>').appendTo( jQuery('#' + mapId ) );
		detailContainer = jQuery('#search-map-detail');
		setLoading( false );
		refreshMarkers();
	}
	
	function show(){
		init();
	}
	
	// Fill the mapProperties obj based on values provided in the form
	function getSettings(){

		var inputs = jQuery('#map-properties').find('input[type=hidden]');

		for ( var i = 0, j=inputs.length; i<j; i++ ){
			var input = inputs.eq(i);
			settings[input.attr('name')] = input.val(); 
		}
		
	}
	
	function refreshMarkers(){
		if (!map){
			init();
			return;
		}

		var limit = parseInt( SliceDice.searchProperties.limit ) || 10;
		var page = SliceDice.getCurrentPage();
		var rangeStart = (page-1) * limit;
		var rangeEnd = rangeStart + limit;
		
	
		var data = {} ;

		var searchType = SliceDice.searchProperties.searchType;
		data.searchType = searchType;
		data.ids = '';

		
		if (  searchType == 'house'){
			
			// Build a string with array for performance reasons
			var ids = [];
			for ( var i=rangeStart, j=resultArray.length; i<j && i<=rangeEnd; i++){
				ids.push(
						'A',  resultArray[i][0], 
						'MP', resultArray[i][4], 
						'OP' , resultArray[i][7] 
				);
			}
			data.ids = ids.join('');
			
		}else if( searchType == 'hotel'){
			
			var orgArray = SliceDice.buildOrgArray();
			
			// Build the string that represents the orgs we want to fetch
			var ids = [];
			for ( var i = rangeStart, j=orgArray.length; i<j && i<= rangeEnd;i++ ){

				// Set the orgId
				ids.push('ORG', orgArray[i].id ); 
				
				// For each ag, provide min- and original price
				for ( var k = 0, l= orgArray[i].allotmentGroups.length; k<l; k++){
					ids.push( 
						'A', orgArray[i].allotmentGroups[k][0], // AllotmentgroupId
						'MP', orgArray[i].allotmentGroups[k][4],// MinPrice 
						'OP', orgArray[i].allotmentGroups[k][7] // OriginalPrice
						)
				}
			}
			
			data.ids = ids.join('');
			
			
		}

		setLoading(true);
		Ajax.doRequest('map/', data, handleRefreshMarkers );
	}
	
	// forMarker is the google GMarker obj. reqMarker is our obj we retrieved from backend
	function getSingleResult( forMarker, reqMarker ){

		util.setLoading(true);
		
		var searchType = SliceDice.searchProperties.searchType; 
		var data = {};
		
		data.ids = ''
		data.searchType = searchType;
		if (searchType == 'house'){
			data.ids = 'A' + reqMarker.id + 'MP' + reqMarker.minPrice + 'OP' + reqMarker.originalPrice;	
		}else if (searchType == 'hotel'){
						
			// Set the orgId
			data.ids += 'ORG'; 
			data.ids += reqMarker.id;

			// Get all orgs, so we can filter out the one we need to view
			var orgArray = SliceDice.buildOrgArray();
			
			for ( var i=0; i< orgArray.length; i++ ){
				
				if (orgArray[i].id == reqMarker.id ){					

					for ( var k = 0, l= orgArray[i].allotmentGroups.length; k<l; k++){
						data.ids += 'A' + orgArray[i].allotmentGroups[k][0]; 	// AllotmentgroupId
						data.ids += 'MP' + orgArray[i].allotmentGroups[k][4]; 	// MinPrice 
						data.ids += 'OP' + orgArray[i].allotmentGroups[k][7];	// OriginalPrice
					}
					break;
				}
			}
			
		}

		Ajax.doRequest('ags/', data, function(resp){

			if (!detailContainer){
				return false;
			}
			
			// Add some animation to clarify refreshing of result
			if ( !detailContainer.html().length ) {
				detailContainer.html(resp.data.html).show('slow');	
			}else{
				detailContainer.fadeOut();
				
				detailContainer.fadeOut(200, function(){
					detailContainer.html(resp.data.html);
					detailContainer.fadeIn(400);
				});
			}
			
			// If we already have an activemarker, revert the icon
			if (activeMarker){
				activeMarker.backToNormal();
			}
			
			// Set the picked icon to active
			forMarker.setImage(reqMarker.iconActiveUrl);
			
			// Assign new activeMarker an
			activeMarker = forMarker;
			
			activeMarker.backToNormal = function(){
				this.setImage(reqMarker.iconUrl);				
			};
			util.setLoading(false);
			
		} );
	}
	
	function handleRefreshMarkers( resp ){

	
		manager.clearMarkers();
		
		var batch = MapUtils.createMarkers( resp.data.markers, {
			tooltip: tooltip,
			infowindow:infoWindow,
			map:map
		});

		manager.addMarkers( batch, 1 );
		manager.refresh();
		setLoading( false );
	}

	function setLoading( load ){
		util.setLoading( load );
	}

	return {
		init:init,
		show:show,
		refresh: refreshMarkers,
		getSingleResult: getSingleResult,
		buildMap: buildMap
	};

}();



//Here we put all functions that can be used in both maps
var MapUtils = function(){
	
	var loadCallback = null;
	var tooltip = null;
	var map = null;
	
	var markerClickHandler = null;
	
	// Loads the google maps api and Markermanager. 
	// If provided, the callback function will be called after completion 
	function loadAPI( callback ){
		
		if ( typeof(GMap2) != 'undefined' && typeof(MarkerManager) != 'undefined' ){
			if ( callback ){
				callback();
			}
		}
		
		// First get the Maps Api. After it has loaded, MapUtils.afterLoad() will be called.
		loadCallback = callback;
		
		if ( !jQuery('#maps-api-url').length){ 
			return false;
		}
		util.setLoading( true );
		var url = jQuery('#maps-api-url').val() + '&callback=MapUtils.afterLoad';
		jQuery('body').append('<script type="text/javascript" src="' + url + '"></script>');

	}

	function afterLoad(){
		
		if ( !GBrowserIsCompatible ) { return false;} 
		
		if ( typeof( MarkerManager ) == 'undefined' ){
			// Only google api has been loaded, we need markermanager too
			jQuery.getScript('/javascript/markermanager.js');
			return;
		}

		if ( loadCallback ){
			loadCallback();
		}
		loadCallback = null;
		util.setLoading( false );
	}
	
	function createMarkers( markers, mapOpts ){

		// Mapopts provided some elements we need - this way we can use all functions for both maps 
		tooltip = mapOpts.tooltip;
		map = mapOpts.map;

		// Create an array of markers
		var batch = [];
		for ( var i = 0, j = markers.length; i<j; i++ ){
			batch[i] = createMarker( markers[i] );
		}
		return batch;

	}
	
	function setMarkerClickHandler(func){
		markerClickHandler = func;
	}
	
	// Builds the icon to show on the map based on request marker attrs (could be a custom icon if defined )
	function buildIcon(reqMarker){
		
		var icon = new GIcon( G_DEFAULT_ICON );

		if ( reqMarker.iconUrl != undefined && reqMarker.iconUrl != ''){
			icon.image = reqMarker.iconUrl;
		}
		
		if (reqMarker.iconWidth ){
			icon.iconSize = new GSize( reqMarker.iconWidth, reqMarker.iconHeight );
			
			icon.shadow =  '';
			
			// 0,0 means that top left corner of the iocon is the position. We have to move it somewhat to the top and left.
			var toLeft = parseInt(reqMarker.iconWidth)/2;
			var toTop = parseInt(reqMarker.iconHeight)/2;
			icon.iconAnchor = new GPoint(toLeft,toTop);
		}

		
		return icon;
	}
	
	// reqMarker: the marker object returned by Ajax class
	function createMarker( reqMarker ){

		// Position of the marker 
		var pos = new GLatLng( parseFloat(reqMarker.lat), parseFloat( reqMarker.lng) );
		
		// Use our internal icon function
		var icon = buildIcon( reqMarker );
		
		// Create the marker 		
		var marker = new GMarker( pos, {
			title : reqMarker.name,
			icon : icon 
			}
		);

		// Show tooltip while hovering
		GEvent.addListener(marker, 'mouseover', function(){
			showToolTip( this.getTitle(),  map.fromLatLngToContainerPixel(this.getLatLng()) );
		});
		GEvent.addListener(marker, 'mouseout', hideToolTip );
		
		if ( typeof( markerClickHandler) == 'function'){
			
			// Open an infoWindow when clicked on a marker
			GEvent.addListener(marker, 'click', function( ){
				markerClickHandler( marker, reqMarker );
				return false;
			});
			
			
		}else{
			
			// Open an infoWindow when clicked on a marker
			GEvent.addListener(marker, 'click', function( ){
				SearchMap.getSingleResult( marker, reqMarker );
				return false;
			});
						
		}

		return marker;
	}
	
	
	function showToolTip( content, pos ){
		tooltip.html( content ).css({
			'top' : pos.y + 'px',
			'left' : pos.x + 'px'
		}).show();
	}
	
	function hideToolTip(){
		tooltip.hide().empty();	
	}
	
	function openInfoWindow( html ){
		infoWindow.html(html).show();
	}

	function closeInfoWindow(){
		if (infoWindow)infoWindow.hide().empty();
	}
	
	
	// Don't think the coordinates of Ameland will change in the near future, so I figured I can place this here [len]
	function restrictViewAreaToAmeland( gMap ){
		
		// Set texel bounding box
		var allowedArea = new GLatLngBounds(new GLatLng(53.501934, 5.607147), new GLatLng(53.407076, 6.015015));

		GEvent.addListener( gMap , "move", function(){

			// Perform the check and return if OK
	        if ( allowedArea.containsLatLng(gMap.getCenter()) ) {
	        	return true;
	        }
	        // It`s not OK, so find the nearest allowed point and move there
	        var C = gMap.getCenter();
	        var X = C.lng();
	        var Y = C.lat();

	        var AmaxX = allowedArea.getNorthEast().lng();
	        var AmaxY = allowedArea.getNorthEast().lat();
	        var AminX = allowedArea.getSouthWest().lng();
	        var AminY = allowedArea.getSouthWest().lat();

	        if (X < AminX) {X = AminX;}
	        if (X > AmaxX) {X = AmaxX;}
	        if (Y < AminY) {Y = AminY;}
	        if (Y > AmaxY) {Y = AmaxY;}
	       
	        gMap.setCenter(new GLatLng(Y,X));

		});
		gMap.disableScrollWheelZoom();
		// Also we want to prevent zooming out too far
		
		var minMapScale = 9;
		// get array of map types
		var mapTypes = gMap.getMapTypes();
		// overwrite the getMinimumResolution() and getMaximumResolution() methods for each map type
		for (var i=0; i<mapTypes.length; i++) {
			mapTypes[i].getMinimumResolution = function() {return minMapScale;}
		}		
	}
	
	return {
		loadAPI : loadAPI,
		afterLoad: afterLoad,
		createMarkers:createMarkers,
		setMarkerClickHandler:setMarkerClickHandler,
		restrictViewAreaToAmeland:restrictViewAreaToAmeland
	}
}();

