// prevent pink tiles
OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;
OpenLayers.Util.onImageLoadErrorColor = "transparent";

// reference local blank image
Ext.BLANK_IMAGE_URL = './mapfish/client/mfbase/ext/resources/images/default/s.gif';

var layer, map, searchprotocol, p, mapnik //define variables here so they can be used globally

// define OSGB for proj4js
Proj4js.defs["EPSG:27700"] = "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs";
  
//prevent wfs from falling over
OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url=";

function createMap() {
	var options = {
		projection: new OpenLayers.Projection("EPSG:900913"),
        displayProjection: new OpenLayers.Projection("EPSG:27700"),
        units: "m",
        maxResolution: 156543.0339,
        maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34,
                                                 20037508.34, 20037508.34)
	};
return new OpenLayers.Map('map',options);
} //end createmap

function addlayers(map){
	
	
	// define wms
	layer = new OpenLayers.Layer.WMS("OA Sites WMS", "http://geoserver.thehumanjourney.net:80/geoserver/wms?",
                           {layers: 'oadigi:oasites', transparent: true, format: 'image/png', buffer:0},
                            {isBaseLayer: false});
// create Google Mercator layers
  
			//define OSM base layer	
		mapnik = new OpenLayers.Layer.TMS(
        "OpenStreetMap Mapping",
        "http://tile.openstreetmap.org/",
        {
            type: 'png', getURL: osm_getTileURL,
            displayOutsideMaxExtent: true
        }
		); 
		
		//define yahoo satellite base layer
            var yahoosat = new OpenLayers.Layer.Yahoo(
                "Yahoo Satellite Imagery",
                {'type': YAHOO_MAP_SAT, 'sphericalMercator': true}
            );
// define protocol for searching
		searchprotocol = new OpenLayers.Protocol.WFS.fromWMSLayer(layer)
		p = mapfish.Protocol.decorateProtocol({ 
			protocol: searchprotocol,
			TriggerEventDecorator: null
		});

        //define pseudo-layer for highlighting selected features
		var select = new OpenLayers.Layer.Vector("Selection", {
			protocol: p,
			strategies: [new mapfish.Strategy.ProtocolListener({append: false})],
			styleMap: new OpenLayers.Style(OpenLayers.Feature.Vector.style["select"]),
			displayInLayerSwitcher: false
		});  

    	
    
	// add layers
	map.addLayers([layer, mapnik, yahoosat, select]);

} //end addlayers

function setMapCenter() {
//define a new projection object so map can be centred using latlong
	var proj = new OpenLayers.Projection("EPSG:4326");
	var point = new OpenLayers.LonLat(-2.9, 53.6);
	this.setCenter(point.transform(proj, this.getProjectionObject()), 6);
} //end setMapCenter

Ext.onReady(function() {

Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

//set up map
var map = createMap();
addlayers(map);

// define the map controls and where they should all go	
infodiv = document.getElementById("info");
var scalep = infodiv.getElementsByTagName("p")[0];
map.addControl(new OpenLayers.Control.Scale(scalep));
map.addControl(new OpenLayers.Control.MousePosition({element: infodiv.getElementsByTagName("p")[2]}));
map.addControl(new OpenLayers.Control.ScaleLine());



//create toolbar
var toolbar = new mapfish.widgets.toolbar.Toolbar({
 map: map,
 configurable: false,
 id: 'toolbarid'
});





	
// create store to display results
var store = new Ext.data.Store({
		reader: new mapfish.widgets.data.FeatureReader({}, 
			[
			{name: 'projcode'},
			{name: 'projectnam'},
			{name: 'sitecode'},
			{name: 'year', type: 'float'},
			{name: 'projtype'},
			{name: 'town'},
			{name: 'county'}])
			});
			
// create search store mediator for adding search results to the store
var searchstoreMediator= new mapfish.widgets.data.SearchStoreMediator({
		protocol: p,
		store: store,
		append: false
		});
		

// create expander for search results
var expander = new Ext.grid.RowExpander({
				tpl: new Ext.Template('<p><b>Project Name:</b> {projectnam}</p><br>',
									'<p><b>Project Type:</b> {projtype}</p><br>',
									'<p><b>Project Code:</b> {projcode}</p><br>',
									'<p><b>Site Code:</b> {sitecode}</p><br>',
									'<p><b>Year:</b> {year}</p><br>',
									'<p><b>Town:</b> {town}</p><br>',
									'<p><b>County:</b> {county}</p><br>')
				});
		
 //create viewport and items for components to live in
var viewport = new Ext.Viewport({
        layout:'border',
		listeners: {
			afterlayout: {
				fn: setMapCenter,
				scope: map,
				single: true
			}
		},
		items:[
	            	new Ext.BoxComponent({ 
        	        region: 'north',
                	el: 'north',
                	height: 85
            		}),
			{region: 'east',
              		split: true,
			xtype: 'panel',
			title: 'Help',
              		margins: '0 0 0 0',
			width: 200,
              		minSize: 175,
              		maxSize: 400,
			collapsible: true,
			items: [{contentEl: 'help',
                	border: false
                	}]
			}, //end region definition
			{region: 'west',
                	id: 'west-panel',
                	title: 'Info',
			margins: '0 0 0 5',
                	width: 200,
                	minSize: 175,
                	maxSize: 400,
                	collapsible: true,
			border: true,
			split: true,
                	items: [{
                    		contentEl: 'west',
                    		title: 'Layers',
                    		el: 'tree',
				xtype: 'layertree',
				height: 180,
                border: false,
				collapsible: true,
				map: map},
				{title: 'Map Info',
				contentEl: 'info',
				border: false,
				collapsible: true},
			new Ext.grid.GridPanel
			({
			title: 'Search results',
			region: 'south',
			plugins: expander,
			store: store,
			height: 300,
			cm: new Ext.grid.ColumnModel([
				expander,
				{id: 'projectnam',
				header: 'Project Name',
				sortable: true,
				dataindex: 'projectnam'
				}]),//end columns definition
			viewConfig: {
            forceFit:true
			}
			}) //end grid panel params
			]},
			{region: 'center',
                	id: 'map',
			title: 'Map',
                	layout: 'fit',
                	xtype: 'mapcomponent',
                	map: map,
			tbar: toolbar
            		}
         ]

}); //end viewport setup

viewport.doLayout();

// define searcher to be activated by toolbar
var searcher = new mapfish.Searcher.Map({
               mode: mapfish.Searcher.Map.BOX,
               protocol: p
       	});



//define spacers for toolbar
var addSeparator = function(){
    toolbar.add(new Ext.Toolbar.Spacer());
    toolbar.add(new Ext.Toolbar.Separator());
    toolbar.add(new Ext.Toolbar.Spacer());
}

//set up controls on toolbar

toolbar.addControl(
        new OpenLayers.Control.ZoomToMaxExtent({
            map: map,
            title: 'Zoom to maximum map extent'
        }), {
            iconCls: 'zoomfull', 
            toggleGroup: 'map'
        }
    );
    
    addSeparator();

    toolbar.addControl(
        new OpenLayers.Control.ZoomBox({
            title: 'Zoom in: click in the map or use the left mouse button and drag to create a rectangle'
        }), {
            iconCls: 'zoomin', 
            toggleGroup: 'map'
        }
    );

    toolbar.addControl(
        new OpenLayers.Control.ZoomBox({
            out: true,
            title: 'Zoom out: click in the map or use the left mouse button and drag to create a rectangle'
        }), {
            iconCls: 'zoomout', 
            toggleGroup: 'map'
        }
    );
    
    toolbar.addControl(
        new OpenLayers.Control.DragPan({
            isDefault: true,
            title: 'Pan map: keep the left mouse button pressed and drag the map'
        }), {
            iconCls: 'pan', 
            toggleGroup: 'map'
        }
    );
    
    addSeparator();
    
            
    var nav = new OpenLayers.Control.NavigationHistory();
    map.addControl(nav);
    nav.activate();
    
    toolbar.add(
        new Ext.Toolbar.Button({
            iconCls: 'back',
            tooltip: 'Previous view', 
            handler: nav.previous.trigger
        })
    );
        
    toolbar.add(
        new Ext.Toolbar.Button({
            iconCls: 'next',
            tooltip: 'Next view', 
            handler: nav.next.trigger
        })
    );
    
    addSeparator();

    toolbar.addControl(searcher, {
	iconCls: 'infobox',
	togglegroup: 'map',
	tooltip: 'searcher'
	});	
	//searcher.activate();

    toolbar.activate();

// loading image
Ext.get('loading').fadeOut({remove: true});
}); //end ext.onReady

// figure out which tiles we need from osm
function osm_getTileURL(bounds) {
    var res = this.map.getResolution();
    var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
    var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
    var z = this.map.getZoom();
    var limit = Math.pow(2, z);
    
    if (y < 0 || y >= limit) {
        return OpenLayers.Util.getImagesLocation() + "404.png";
    } else {
        x = ((x % limit) + limit) % limit;            
        return this.url + z + "/" + x + "/" + y + "." + this.type;
    }
}
