/**
* @author peter.goulborn
* $Workfile: atolMapCreator.js $
* $Revision: 59 $
* $Modtime: 2/11/09 10:37 $
* $Author: Peter.goulborn $ 
*/

function atCreateMap(atElements, atDataMapUrl, atDataServiceUrl, atDistances, atResults, atForceThematic, initialView, options ) {
    //alert('atCreateMap');
    var options = options || {};
    var mapElement = $(atElements.map || 'map');
    //alert('mapElement:' + !!mapElement);
    var mapOverlay = new Element('div', {
        'id': 'atMapOverlay'
    });
    var mapTimer = new Element('img', {
        'id': 'atMapTimer',
        'src': 'images/stopwatch.gif'
    });

    mapOverlay.update(mapTimer);
    mapOverlay.hide();
    mapOverlay.setStyle({
        'zIndex': '800',
        'height': '36px',
        'width': '36px',
        'backgroundColor': '#fff',
        'position': 'absolute',
        'top': 0,
        'right': 0,
        'border': '1px solid #aaa'
    });
    mapTimer.setStyle({
        'zIndex': '1',
        'position': 'relative',
        'height': '32px',
        'width': '26px',
        'margin': '2px 5px'
    });
    //mapOverlay.insert(new Element('div', {'style': 'opacity: 0.6; background-color: #fff; width: 100%; height: 100%; '}));
    mapElement.insert({
        'bottom': mapOverlay
    });
	
	if(jQuery)
	{
		var $mapElement	= jQuery('#'+mapElement.id),
			$mapLoader	= jQuery('<div></div>')
							.addClass('ui-state-default')
							.attr('id','atMapLoader')
							.width(75)
							.css({
								'background'	: '#fff',
								'position'		: 'absolute',
								'z-index'		: '800',
								'text-align'	: 'center',
								'padding'		: 10,
								'border-width'	: 5,
								'left'			: (parseInt($mapElement.offset().left,10)+(parseInt($mapElement.width(),10)/2)-(75/2)),
								'top'			: (parseInt($mapElement.offset().top,10)+(parseInt($mapElement.height(),10)/2)-80),
								'-moz-border-radius'	:15,
								'-webkit-border-radius'	:15,
								'box-shadow'		: '5px 5px 3px #818181',
								'-webkit-box-shadow': '5px 5px 3px #818181',
								'-moz-box-shadow'	: '5px 5px 3px #818181'
							})
							.append(
								jQuery('<img/>')
									.attr({'src':'images/stopwatch.gif', 'id':'atMapTimer'})
								,
								jQuery('<span></span>')
									.html('<br />Loading...')
							)
							.hide()
							.appendTo(jQuery('body'));
			//If mapElement change its width or height, reposition the loader
			$mapElement.bind('repositionLoader',function(){
				setTimeout(function(){ 
					$mapLoader.css({
						'left' : (parseInt($mapElement.offset().left,10)+(parseInt($mapElement.width(),10)/2)-(parseInt($mapLoader.width(),10)/2))-parseInt(jQuery('body').offset().left,10),
						'top'  : (parseInt($mapElement.offset().top,10)+(parseInt($mapElement.height(),10)/2)-80)
					});
				},100);
			});
	}

    //alert('mapOverlay:' + !!mapOverlay);
    Event.observe(mapElement, 'astun:layerStart', function(layerEvent) {
        //	mapOverlay.setStyle({'left': mapElement.positionedOffset().left+'px','top': mapElement.positionedOffset().top+'px',  'height': mapElement.getHeight()+'px', 'width':mapElement.getWidth()+'px'});
		(jQuery) ? $mapLoader.fadeIn('fast') : $('atMapOverlay').show();
    });
    Event.observe(mapElement, 'astun:layerEnd', function(layerEvent) {
        //	mapOverlay.setStyle({'left': mapElement.positionedOffset().left+'px','top': mapElement.positionedOffset().top+'px',  'height': mapElement.getHeight()+'px', 'width':mapElement.getWidth()+'px'});
		(jQuery) ? $mapLoader.fadeOut('fast') : $('atMapOverlay').hide();
    });

    var mapCallbacks = {
        'click': function(e) {
            this.map.wrapper.mapElement.fire('astun:mapClick', {
                mapEvent: e
            });
        },
        'hoverPause': function(e) {
            this.map.wrapper.mapElement.fire('astun:mapHover', {
            mapEvent: e
            });
        },
        'hoverMove': function(e) {
            /*clearTimeout(this.map.wrapper.timers.hover);*/
        }
    };

    var mapStateManager = new Astun.iSharemaps.StateManager(mapElement);
    var mapWrapper = new Astun.iSharemaps.OLMap(mapElement, atDataMapUrl, {
        callbacks: mapCallbacks, themeName: window.astun.themeName
    }, atDataServiceUrl);
    



    var mapInteractions = new Astun.iSharemaps.OLInteractCtrl();
    mapWrapper.interactions = mapInteractions;

    //var layerPanel = new Astun.iSharemaps.OLLayerPanel(mapWrapper, atElements.layers || 'layers');
   //var thematicsPanel = new Astun.iSharemaps.OLLayerPanel.Thematic(mapWrapper, atElements.thematics || 'thematics');
   // var nearestPanel = new Astun.iSharemaps.OLNearestPanel(mapWrapper, atElements.findNearest || 'findNearest', atDistances, atResults);

    var layerControl = new Astun.iSharemaps.OLLayerControl(mapWrapper, null, atForceThematic);


    var mapSourceLoad = function(evt) {
        // astun:mapSourceLoad returns current mapSource as evt.memo
        var mapSource = evt.memo;
        mapWrapper.baseMapSource = mapSource.defaultBaseMap;
        var loadOptions = {
            data: {}
        };
        if( initialView ) {
			loadOptions.initialView = initialView;
        }
        var loadMap = function() {
            var loadCurrentLocation = function(locationSetting) {
                var checkLocationChange = function(previousSetting) {
                    // Load previous setting

                    var local = {};
                    local.fn = {};

                    if (locationSetting) {
                        local.currentLocation = locationSetting.evalJSON();
                    }
                    if (previousSetting) {
                        local.previousLocation = previousSetting.evalJSON();
                    }
		    
					local.previousArea = ( local.previousLocation && local.previousLocation.areaid ) ? local.previousLocation.areaid : '';
		    
                    //Initialise location object                            
                    this.currentLocation = {};

                    local.fn.load = function() {
						// Draw map, load map source   
						var $eventElement = jQuery( '#' + mapWrapper.mapElement.id );  
						var loadBaseMap = function( baseMapName ) {
							var loadInitialBase = function( evt, baseMapSource, type ) {
								if( type === 'raster'){
									mapWrapper.loadMap( baseMapSource, evt.data.dataMapSource, evt.data.loadOptions);					
									jQuery(evt.target).unbind( 'mapSourceLoaded', arguments.callee );
								}
								
							}  
							
							$eventElement.bind(
								'mapSourceLoaded', 
								{
									'dataMapSource': mapSource,
									'loadOptions': loadOptions
								},
								loadInitialBase
							);
							
							var name = mapSource.defaultBaseMap;
							if( baseMapName ) {
								for( var i = 0; i < mapSource.baseMaps.length; i++ ){
									if( mapSource.baseMaps[i] === baseMapName ) {
										name = baseMapName;
										break;
									}
								}
							}
							$eventElement.trigger('loadMapSource', [ name, 'raster' ]);
						}
						setTimeout(function() { mapWrapper.mapElement.fire('astun:loadSetting', {setting: 'baseMap', loadFunction: loadBaseMap})}, 0);
		
					}
					
                    // Is location set?
                    if (local.currentLocation && local.currentLocation.uid && local.currentLocation.uid !== -1) {
                        this.currentLocation = local.currentLocation;
                        this.currentPosition = new OpenLayers.LonLat(this.currentLocation.x, this.currentLocation.y);
                        local.validLocation = true;
                    }

                    // Is areaid set?
                    if( $('txtAreaId') ) {
						this.currentLocation.areaid = local.currentArea = $('txtAreaId').value;
					}
                    // Has area changed?
                    local.newArea = (local.currentArea && local.currentArea !== local.previousArea );
					if( local.currentArea && local.newArea ) {										
						local.newAreaSuccess = function( transport ) 
						{
							var func = {};
							
							if( transport.responseText.search( /FeatureCollection/ ) > 0 )
							{
								try {
									func.results = transport.responseText.evalJSON( );
									local.fn.load();									
									func.geoJSON = ( new OpenLayers.Format.GeoJSON ).read( func.results );
									func.featureBounds = func.geoJSON[0].geometry.getBounds();
									mapWrapper.map.zoomToExtent(func.featureBounds.scale(1.4), true); 
																	
								}
								catch( parsingError ) {
									alert( 'Error: Area search results in wrong data format.' ); 									
								}
								
							}
							else
							{						
								alert( 'Error: Area search results in wrong geometry format.' ); 
							}				
						};	 
						// fixed values as placeholder for real GeoJSON webservice and relevent settings in MapSource
						// TODO: replace with GeoJSON webservice variables
						new Ajax.Request 
						( mapWrapper.dataurl, 
							{
								method: 'get',
								parameters: {
									'RequestType': 'XSL',
									'Type': 'DataFunc',
									'ds': 'NeighbourhoodsGeoJSON',
									'xsl': 'xml\\atStripped.xsl',
									'params': local.currentArea,
									'axuid': new Date( ).valueOf( )
								},
								onFailure: function( transport ) 
								{
									alert( "Error: Failed to get neighbourhood data!" );
								},
								onSuccess : local.newAreaSuccess.bindAsEventListener( this )			
							}
						); //Ajax request 
						
						// Save location as previous if area and/or location have changed.
						
						
						func = null;
						
					}
					else {
						// If same areaid, has location changed?
						if ( local.validLocation && ( !local.previousLocation || this.currentLocation.uid !== local.previousLocation.uid ) ) {
							local.newLocation = true;
							// If location changed set start position to current location if intial view not being forced further up the stack	
							if (!loadOptions.forceInitial && loadOptions.initialViewType != 'supplied') {
								loadOptions.initialView = { 'easting': this.currentLocation.x, 'northing': this.currentLocation.y, 'zoom': this.locationZoom };
								loadOptions.initialViewType = 'supplied';
							}
						}
						local.fn.load();
					}
					if (local.newArea || local.newLocation) {
						mapWrapper.mapElement.fire('astun:saveSetting', { setting: 'previousLocation', value: Object.toJSON(mapWrapper.currentLocation) });
					}	
                }
                this.mapElement.fire('astun:loadSetting', { setting: 'previousLocation', loadFunction: checkLocationChange.bind(this) });


            }
            setTimeout(function() { mapWrapper.mapElement.fire('astun:loadSetting', { setting: 'currentLocation', loadFunction: loadCurrentLocation.bind(mapWrapper) }) }, 0);
			
			Event.observe( mapWrapper.mapElement, 'astun:mapLoaded', function( evt ) {
				layerControl.importLayerGroups( evt.memo || mapSource );
			} );						
        };
        // Handle parameters
        mapWrapper.queryHandler = new Astun.JS.Common.QueryHandler({
            'StartEasting': 'x',
            'StartNorthing': 'y',
            'StartZoom': 'z',
            'SearchLayer': 'sl',
            'SearchField': 'sf',
            'SearchValue': 'sv',
            'ServiceAction': 'sa',
            'Address': 'a',
            'UPRN': 'u'
        });

        var setInitialView = function(viewArray) {
            loadOptions.initialView = {
                'easting': viewArray[0],
                'northing': viewArray[1],
                'zoom': viewArray[2]
            }
            loadOptions.forceInitial = true;
        }

        mapWrapper.queryHandler.addCase(
					'zoom',
					'StartEasting, StartNorthing, StartZoom',
					function(values) {
					    // set initial view according to passed in parameters
					    setInitialView([values.starteasting, values.startnorthing, values.startzoom]);
					    loadMap();
					}
				);

        mapWrapper.queryHandler.addCase(
					'searchLayer',
					'SearchLayer, SearchField, SearchValue',
					function(values) {
					    // perform search on data layer and load map with appropriate view
					    var setLocationView = function( response ) {
							var featureCollectionArray = response;
							var featureCol = featureCollectionArray[ 0 ];	
												
							var feature = featureCol.features.shift( ); 
												
							var lonLat = new OpenLayers.LonLat( feature.geometry.coordinates[ 0 ][ 0 ],feature.geometry.coordinates[ 0 ][ 1 ] );
							var zoom = mapWrapper.locationZoom;
							
							// if third coordinate different then dealing with bounding box, extend to that too
							if( ( feature.geometry.coordinates[ 0 ][ 0 ] !== feature.geometry.coordinates[ 2 ][ 0 ] ) ||( feature.geometry.coordinates[ 0 ][ 1 ] !== feature.geometry.coordinates[ 2 ][ 1 ] ) ) {
								var topRight = new OpenLayers.LonLat( feature.geometry.coordinates[ 2 ][ 0 ],feature.geometry.coordinates[ 2 ][ 1 ] );
								var featureBounds = new OpenLayers.Bounds( );
								featureBounds.extend( lonLat );
								featureBounds.extend( topRight );
								featureBounds = featureBounds.scale( 2.0 ); // some padding around boundary as fudge to try and make sure appropriate zoom level is used
								var boundsWidth = featureBounds.getWidth( ) ;
								var boundsHeight = featureBounds.getHeight();
								zoom = ( boundsWidth > boundsHeight ) ? boundsWidth : boundsHeight; // make sure zoom level includes all of feature, should work so long as image width  isnt more than twice its height
								lonLat = featureBounds.getCenterLonLat( );
								
							}
							var view = {'easting': lonLat.lon, 'northing': lonLat.lat, 'zoom': zoom}
					        if (view) {
					            setInitialView([view.easting, view.northing, view.zoom]);
					            loadOptions.data.defaultLayers = [values.searchlayer];
					            loadOptions.data.defaultFilter = '^layername=' + values.searchlayer + '^qstr=' + values.searchvalue + '^';
					        }
					        if (layerControl.thematicInfo) {
					            layerControl.thematicInfo.force = 'off';
					        }
					        loadMap();
					    }
					    mapWrapper.searchISMLayer(values.searchlayer, values.searchfield, values.searchvalue, setLocationView);
					}
				);

        if (mapWrapper.queryHandler.cases.matched) {
            mapWrapper.queryHandler.processFirstCase();
        }
        else {
            // load map normally
            loadMap();
        }



    };

    Event.observe(mapWrapper.mapElement, 'astun:mapSourceLoad', mapSourceLoad);

    var msm = new Astun.iSharemaps.MapSourceManager(atDataServiceUrl, mapElement);

    options.click = options.click || 'none';
    switch (options.click) {
		case 'infopanel':
			var clickFunc = mapInteractions.onInfoClick;
			break;
		case 'tooltip':
			var clickFunc = mapInteractions.showMapToolTip;
			break;
		default: 
			// do nothing
			var clickFunc = function( evt ){};
    }
    options.hover = options.hover || 'none';
    switch (options.hover) {
		case 'tooltip':
			var hoverFunc = mapInteractions.showMapToolTip;
			break;
		default: 
			// do nothing
			var hoverFunc = function( evt ){};
    }
    
    Event.observe(mapWrapper.mapElement, 'astun:mapClick', function( evt ) {
		clickFunc.bind(this)( evt );
		
	}.bindAsEventListener(mapWrapper));
	
    Event.observe(mapWrapper.mapElement, 'astun:mapHover', function( evt ) {
		hoverFunc.bind(this)( evt );
		
	}.bindAsEventListener(mapWrapper));	
	
    Event.observe(mapWrapper.mapElement, 'astun:layerQuery', mapInteractions.findNearest.bindAsEventListener(mapWrapper));

    Event.observe(mapWrapper.mapElement, 'astun:resultsReceived', function(e) {
		if (jQuery('#atPanelResults').length>0) {
			//If content panel hidden, show it
			if(!jQuery('#atResultsSwitcher').is(':visible')) jQuery('#atInfoBoxOpenClose').trigger('click');
			jQuery('#atPanelResults').show();
            $('atResults').update(e.memo.html);

			//Styling
			jQuery('#atResults fieldset, #atResults legend').css({'padding':5, 'margin':3}).addClass('ui-corner-all ui-state-default');
			jQuery('#atResults fieldset').css('background','#fff');
			jQuery('#atResults legend').prepend(jQuery('<span/>').addClass('ui-icon ui-icon-carat-1-e').css('float','left'));
			if(!jQuery.browser.msie) jQuery('#atResults .contentDisplay').width('99%');

			//Animate the Resultbox so that user can see something happened there
			if(!jQuery('#atResults, .infoResult').is(':animated')) jQuery('.infoResult').addClass('ui-state-default ui-corner-all').css('background','#fff').add('#atResults').effect('highlight', {}, 3000);
        }
    });
    Event.observe(mapWrapper.mapElement, 'astun:resultsCleared', function(e) {
		if(jQuery('#atPanelResults').length>0) {
			jQuery('#atPanelResults').hide();
            $('atResults').update('');
        }
    });
    //alert('mapWrapper: ' + !!mapWrapper);
    return mapWrapper;
}

