// Only load when needed?
google.load("maps", "2.xx");

// Define namespace
Ext.namespace('Globalis.Maps');

// Avoid pink tiles
OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;
OpenLayers.Util.onImageLoadErrorColor = "transparent";

// Extending OpenLayers.Control.CustomLayerSwitcher
// It is not possible to style the LayerSwitcher in OpenLayers 2.8
// Will be fixed in 2.9: http://trac.openlayers.org/ticket/1632
// Making a custom LayerSwitcher where styling is removed
// http://geojavaflex.blogspot.com/2009/11/part-23-adding-order-and-delete.html
// Original code: http://trac.openlayers.org/browser/branches/openlayers/2.8/lib/OpenLayers/Control/LayerSwitcher.js

// Subclass the control 
OpenLayers.Control.CustomLayerSwitcher =
  OpenLayers.Class(OpenLayers.Control.LayerSwitcher, {
  CLASS_NAME: "OpenLayers.Control.CustomLayerSwitcher"
});

// Override loadContents method
OpenLayers.Control.CustomLayerSwitcher =
  OpenLayers.Class(OpenLayers.Control.LayerSwitcher, {
  
    /** 
     * Method: loadContents
     * Set up the labels and divs for the control
     */
    loadContents: function() {

        this.layersDiv = document.createElement("div");
        this.layersDiv.id = this.id + "_layersDiv";
        this.baseLbl = document.createElement("div");
        this.baseLayersDiv = document.createElement("div");
        this.dataLbl = document.createElement("div");
        this.dataLayersDiv = document.createElement("div");

        this.layersDiv.appendChild(this.dataLayersDiv);
        this.div.appendChild(this.layersDiv);
    },
    
    CLASS_NAME: "OpenLayers.Control.CustomLayerSwitcher"
});

// Add two additional zoom levels to Google maps
// http://trac.openlayers.org/ticket/2429
OpenLayers.Layer.Google.prototype.RESOLUTIONS = [
	1.40625, 
    0.703125, 
    0.3515625, 
    0.17578125, 
    0.087890625, 
    0.0439453125,
    0.02197265625, 
    0.010986328125, 
    0.0054931640625, 
    0.00274658203125,
    0.001373291015625, 
    0.0006866455078125, 
    0.00034332275390625,
    0.000171661376953125, 
    0.0000858306884765625, 
    0.00004291534423828125,
    0.00002145767211914062, 
    0.00001072883605957031,
    0.00000536441802978515, 
    0.00000268220901489257,
    0.0000013411045074462891,
    0.00000067055225372314453    
];
OpenLayers.Layer.Google.prototype.MAX_ZOOM_LEVEL = 21; 




// Wrap map options and functions in one object
Globalis.Maps = {
	items: {},

	permalink: new OpenLayers.Control.Permalink(),
	restrictedExtent: new OpenLayers.Bounds(-20037508, -16200000, 20037508, 16200000),
	maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508),
	zoomExtent: new OpenLayers.Bounds(-20037508, -12200000, 20037508, 16200000),

	getCoords: function(inURL) {
		var params = this.permalink.createParams();
		var newURL = inURL.href + "?zoom=" + params.zoom + "&lat=" + params.lat + "&lon=" + params.lon + "&layers=" + params.layers; 
		document.location.href = newURL;
	},
	
	createMapLayers: function(map, mapData) {
	
		var layer, layerData;
	
		// Base map layer
		switch (mapData.service) {
			
			case 0: // Globalis (S3/TMS)
					tileUrl = 'http://globalis.s3.amazonaws.com/maptiles/3785';
	
					// Create map layer
					layer = new OpenLayers.Layer.TMS( 
			       		mapData.name,
					   	tileUrl,
			           	{ 
							layername: mapData.id, 
							serviceVersion: '', 
							type:'png',
			 				sphericalMecator: true,
							numZoomLevels: mapData.numZoomLevels//,
							//displayInLayerSwitcher: false
						}
			        );
			 		break;
	
			case 1: // Globalis (S3/XYZ)
					tileUrl = 'http://globalis.s3.amazonaws.com/maptiles/3785/' + mapData.id + '/${z}/${x}/${y}.png';
	
					layer = new OpenLayers.Layer.XYZ( 
			       		mapData.name,
					   	tileUrl,
			           	{ 
			 				sphericalMecator: true,
							numZoomLevels: mapData.numZoomLevels					
						}
			        );
			 		break;
	
			case 4: // Google Maps

					layer = new OpenLayers.Layer.Google(
					    mapData.name,
			        	{
							type: mapData.id, 
							sphericalMercator: true, 
							numZoomLevels: mapData.numZoomLevels
						}
			    	);
			 		break;
	
		}	
		map.addLayer(layer);
	
	    // Create map overlays
		for (var index in mapData.overlays) {
			layerData = mapData.overlays[index];
	
			switch (layerData.service) {
			
				case 1: // Globalis (S3/XYZ)
					tileUrl = 'http://globalis.s3.amazonaws.com/maptiles/3785/' + layerData.id + '/${z}/${x}/${y}.png';
					layer = new OpenLayers.Layer.XYZ(layerData.name, tileUrl, {
						sphericalMecator: true,
						buffer: 1,
						isBaseLayer: false,
						visibility: layerData.visibility,
						numZoomLevels: layerData.numZoomLevels,
						legend: layerData.legend
					});
					break;

				case 4: // 	GeoRSS
				    layer = new OpenLayers.Layer.GeoRSS(layerData.name, layerData.url, { 
			 			projection: new OpenLayers.Projection("EPSG:4326"),
						icon: new OpenLayers.Icon(layerData.icon, new OpenLayers.Size(21,34), new OpenLayers.Pixel(-10, -34)),
						visibility: layerData.visibility,
						legend: layerData.legend
					});
					break;
			}
			map.addLayer(layer);
		}

		return map;	
		
	}	
				

};




Ext.onReady(function(){

	// Loop through all maps defined in view template(s)
	for ( var mapId in Globalis.Maps.items ){
		var mapData = Globalis.Maps.items[mapId];

		// Map options		
		var options = {
			controls: [],
	        projection: new OpenLayers.Projection("EPSG:900913"),
	        displayProjection: new OpenLayers.Projection("EPSG:4326"),
	        units: "m",
	        maxResolution: 156543.0339,
	        maxExtent: Globalis.Maps.maxExtent,
			restrictedExtent: Globalis.Maps.restrictedExtent
		};

		// Create map instance
		var map = new OpenLayers.Map(options);

		// Toggle legends for map overlays
		map.events.register("changelayer", this, function(evt){
			// If legend exist for this layer
			if (!Ext.isEmpty(evt.layer.legend)) {
				// Toggle div containing legend
				Ext.fly(evt.layer.legend).toggleClass('x-hide-display');
			}
		});


		// Add map controls
		map.addControl(Globalis.Maps.permalink);
		map.addControl( new OpenLayers.Control.MouseDefaults() );
		map.addControl( new OpenLayers.Control.KeyboardDefaults() );

		// PanZoomBar and CustomLayerSwitcher is only used for full view maps
		if (mapData.view === 'full') {
			map.addControl( new OpenLayers.Control.PanZoomBar() );			
			map.addControl(new OpenLayers.Control.CustomLayerSwitcher({
				div: OpenLayers.Util.getElement('layerswitcher')
			}));
		}
		else {
			map.addControl(new OpenLayers.Control.PanZoom());
		}

		// Add map layers from map data
		Globalis.Maps.createMapLayers(map, mapData);


		if (mapData.view == 'full') {

			var bigMapButton = new Ext.Button({
				iconCls: 'arrow_out',
				handler: function(button){

					var bigMapWindow = new Ext.Window({
						title: 'Globalis: ' + mapData.name,
			            layout: 'fit',
						x: 15,
						y: 15,
		                modal: true,
						resizable: false,
						draggable: false,
						listeners: {
							/*
							afterrender: function(){
								map.render(this.body.dom);
			    			},
			    			*/
							close: function(){
								map.render(mapPanel.body.dom);
			    			}
		  				},
						// http://www.extjs.com/forum/showthread.php?t=73919
						monitorResize: true,
						doConstrain: function(){
							this.constructor.prototype.doConstrain.apply(this, arguments);
							var size = Ext.getBody().getViewSize();
							this.setWidth(size.width-50);
							this.setHeight(size.height-50);
							map.render(this.body.dom);
						}												
		            });
		        	bigMapWindow.show(this);
				}			
			});	

			var mapToolbar = new Ext.Toolbar({
			    items: [ '->', bigMapButton ]
			});
			
			var mapPanel = new Ext.Panel({
				region: 'center',
				border: true,
				split: true,
				margins: '5 0 5 5',				
				width: 519,
				bbar: mapToolbar,
				listeners: {
					bodyresize: function(){
						map.updateSize();		
			    	}								
		  		}					
			});

			var legendPanel = new Ext.Panel({
				title: Ext.fly('legend').dom.title,
				region: 'east',
				collapsible: true,
				split: true,
				contentEl: 'legend',
				width: '193',
				autoScroll: true,
				margins: '5 5 5 0',
				cmargins: '5 5 5 5'					
			});	

			var mapLayout = new Ext.Panel({
			    layout: 'border',
			    renderTo: 'map_' + mapId,
				border: true,
			    width: '100%',				
				height: mapData.height,
			    items: [ mapPanel, legendPanel ]
			});
			
		} else if (mapData.view !== 'widget') {

			var mapPanel = new Ext.Panel({
				renderTo: 'map_' + mapId,
				height: mapData.height,
				bodyStyle: 'background-color: #9bb2cc;'
			});

		} else {

			// Show LayerSwitcher for map widget
			map.addControl(new OpenLayers.Control.LayerSwitcher());

			var mapPanel = new Ext.Panel({
				title: 'Globalis: ' + mapData.name,
				region: 'center',
				split: true,
				margins: '5 0 5 5',
				bodyStyle: 'background-color: #9bb2cc;',
				listeners: {
					bodyresize: function(){
						map.updateSize();						
			    	}								
		  		}					
			});

			var legendPanel = new Ext.Panel({
				title: 'Forklaring',
				region: 'east',
				collapsible: true,
				split: true,
				margins: '5 5 5 0',
				contentEl: 'legend',
				width: '20%',
				minWidth: 155,
				maxWidth: 220,
				autoScroll: true,
				bodyStyle: 'padding: 5px;',
				listeners: {
					afterrender: function(p){
						//console.log(p.body.dom);
						//p.setTitle('xxx');
						// Restrict percentage width to min/max width
						if (p.getWidth() > p.maxWidth) p.setWidth(p.maxWidth);
						else if (p.getWidth() < p.minWidth) p.setWidth(p.minWidth);
	    			}
  				}
			});	

			new Ext.Viewport({
				layout: 'border',
				items: [ mapPanel, legendPanel ]
			});

		}

		if (map.getCenter()){
			map.render(mapPanel.body.dom);		
		}
		else if (mapData.position) {
			var position = new OpenLayers.LonLat( mapData.position.longitude, mapData.position.latitude).transform(map.displayProjection, map.projection);
			map.setCenter(position, mapData.position.zoom);
			map.render(mapPanel.body.dom);	
		}
		else if (mapData.bounds) {
			map.render(mapPanel.body.dom);
			var boundsArray = mapData.bounds.split(',');
			var bounds = new OpenLayers.Bounds( boundsArray[0], boundsArray[1], boundsArray[2], boundsArray[3] ).transform(map.displayProjection, map.projection);
			map.zoomToExtent(bounds);
		}
		else {
			map.render(mapPanel.body.dom);
			map.zoomToExtent(Globalis.Maps.zoomExtent, true);
		}

		// Add country boundary if exist
		if (!Ext.isEmpty(mapData.boundary)) {
			var baseUrl = '';

		    var style = new OpenLayers.Style({
				fillOpacity: 0.15,
		        strokeWidth: 0,
		        fillColor: '#ffcc00'
		    });
		    var styleMap = new OpenLayers.StyleMap({'default': style});


			
			var boundary_110m = new OpenLayers.Layer.GML( 
				'Boundary 110m', 
				baseUrl + '/layout/set/blank/content/view/json/' + mapData.boundary + '/(scale)/110', { 
					format: OpenLayers.Format.GeoJSON,
                    styleMap: styleMap,
                  	projection: new OpenLayers.Projection("EPSG:4326"),
					maxResolution: 160000,
					minResolution: 70000
				} 
			);

			var boundary_50m = new OpenLayers.Layer.GML( 
				'Boundary 50m', 
				baseUrl + '/layout/set/blank/content/view/json/' + mapData.boundary + '/(scale)/50', { 
					format: OpenLayers.Format.GeoJSON,
                    styleMap: styleMap,
                  	projection: new OpenLayers.Projection("EPSG:4326"),
					maxResolution: 60000,
					minResolution: 8000
				} 
			);

			var boundary_10m = new OpenLayers.Layer.GML( 
				'Boundary 10m', 
				baseUrl + '/layout/set/blank/content/view/json/' + mapData.boundary + '/(scale)/10', { 
					format: OpenLayers.Format.GeoJSON,
                    styleMap: styleMap,
                  	projection: new OpenLayers.Projection("EPSG:4326"),
					maxResolution: 7000
				} 
			);

			map.addLayers([ boundary_110m, boundary_50m,  boundary_10m ]);
		}

	}

});