/* Online Geo-spatial Interface

   This is effectively a wrapper around various OpenLayers components
   that links them to a REST interface on a server. This combination
   provides:

   - a WMS, with layers that can be turned on and off

   - an 'area selection' layer that allows users to draw polygons
   which are saved on the server.

   - a facility to save the state of the map and layers

   OGI.Manager is the primary class to consider when using this library.
*/

   
//  The OGI namespace - this mainly contains specialised OpenLayers subclasses */

function handle_point_query(e) {
    this.queryPoint(e.xy.x, e.xy.y, function (response) {
            if (response.responseText) {
                var results = $('results');
		document.getElementById('result_table').innerHTML=response.responseText;
            }       
        }
        );
}



function createRequestObject() {
    var tmpXmlHttpObject;
    
    //depending on what the browser supports, use the right way to create the XMLHttpRequest object
    if (window.XMLHttpRequest) { 
        // Mozilla, Safari would use this method ...
        tmpXmlHttpObject = new XMLHttpRequest();
	
    } else if (window.ActiveXObject) { 
        // IE would use this method ...
        tmpXmlHttpObject = new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    return tmpXmlHttpObject;
}

//call the above function to create the XMLHttpRequest object
var http = createRequestObject();

function makeGetRequest(request, url, polygons) {
    //make a connection to the server ... specifying that you intend to make a GET request 
    //to the server. Specifiy the page name and the URL parameters to send
    var re_quest= url + polygons;
//   window.alert(re_quest);
    http.open(request, url + polygons);
	
    //assign a handler for the response
    http.onreadystatechange = processResponse;
	
    //actually send the request to the server
    http.send(null);
}

function processResponse() {
    //check if the response has been received from the server
    if(http.readyState == 4){
	
        //read and assign the response from the server
        var response = http.responseText;
		
        //do additional parsing of the response, if needed
		
        //in this case simply assign the response to the contents of the <div> on the page. 
//window.alert(response);
		
        //If the server returned an error message like a 404 error, that message would be shown within the div tag!!. 
        //So it may be worth doing some basic error before setting the contents of the <div>
    }
}




var OGI = {};
OGI.Layer = {};

// A layer class that manages the WMS and all its layers and groups
OGI.Layer.WMSGroup = OpenLayers.Class(OpenLayers.Layer.WMS, {
        
    initialize: function(name, url, groups, params, options) {
            this.groups = groups;
            params['layers'] = this.layers();
            var newArguments = [];
            newArguments.push(name, url, params, options);
            OpenLayers.Layer.WMS.prototype.initialize.apply(this, newArguments);
        },

    toggleGroup: function(name, state) 
    {
        this.groups[name]['status'] = state;
    },

    turnGroupOn: function(name) 
    {
        this.toggleGroup(name, true);
    },   

    turnGroupOff: function(name) 
    {
        this.toggleGroup(name, false);
    },   

    /* Return a list of layers that are currently turned on */
    layers: function() 
    {
        var groups = [];
        for (var name in this.groups) {
            var group = this.groups[name];
            if (!group['status']) {
                groups[group['index']] = [];
            } else {
                groups[group['index']] = group['layers'];
            }                                   
        }

        var layers = [];
        for (var i=0; i < groups.length; i++) {
            for (var j=0; j < groups[i].length; j++) {
                layers.push(groups[i][j])
            }
        }
layers = 'uk,osgb_10km_grid2'; //hardcoded default map for habitats
        return layers;
    },
    
    mergeLayers: function() 
    {
        this.mergeNewParams({'LAYERS': this.layers().join(',')});
	this.params.layers = this.layers().join(',');
	this.redraw();
    },
    showBubble: function(response)

{
 	 var popup = new OpenLayers.Popup.AnchoredBubble("chicken", 
                                     this.map.getExtent().getCenterLonLat(),
                                     null,
                                     "<div style='font-size:.8em'>"+response+"</div>",
                                     null, true, null);
	 popup.setBackgroundColor("#CEE6F2");
            this.map.addPopup(popup);

},
    queryPoint: function(x, y, callback) 
    {
        // a list of queryable layers. This shouldnt be hard coded but retrieved from the server
        var queryable_layers = {'osgb_10km_grid2': true};
        var query_layers = [];
        var layers = this.layers();
        query_layers.push('osgb_10km_grid2');
/*
        for (var i=0; i < layers.length; i++ ) {
            var layer = layers[i];
            if (queryable_layers[layer]) {
                query_layers.push(layer);
            }                    
        }
*/
        if (!query_layers.length) {
            return false;
        }
                
        var url =  this.getFullRequestString({
            REQUEST: "GetFeatureInfo",
            EXCEPTIONS: "application/vnd.ogc.se_xml",
            BBOX: this.map.getExtent().toBBOX(),
            X: x,
            Y: y,
            INFO_FORMAT: 'text/html',
            QUERY_LAYERS: query_layers.join(','),
            FEATURE_COUNT: 20,
            WIDTH: this.map.size.w,
            HEIGHT: this.map.size.h});
        OpenLayers.loadURL(url, '', this, callback, function(response) {
                alert('The point could not be queried');
            });

        return true;
    },

    /**
     * Method: destroy
     * Destroy this layer
     */
    destroy: function() {
            // for now, nothing special to do here. 
            OpenLayers.Layer.WMS.prototype.destroy.apply(this, arguments);  
        },
    
    /**
     * Method: clone
     * Create a clone of this layer
     *
     * Returns:
     * {<OGI.Layer.WMSGroup>} An exact clone of this layer
     */
    clone: function (obj) {
        
            if (obj == null) {
                obj = new OGI.Layer.WMSGroup(this.name,
                                             this.url,
                                             this.groups,
                                             this.params,
                                             this.options);
            }

            //get all additions from superclasses
            obj = OpenLayers.Layer.WMS.prototype.clone.apply(this, [obj]);

            // copy/set any non-init, non-simple values here

            return obj;
        },        

    CLASS_NAME: "OGI.Layer.WMSGroup"
    });

// A layer that manages the area selections
OGI.Layer.AreaSelection = OpenLayers.Class(OpenLayers.Layer.Vector, {

    initialize: function(name, uri, options) {
            var newArguments = [];
            newArguments.push(name, options);
            this.uri = uri;
            this.wkt = new OpenLayers.Format.WKT();
            OpenLayers.Layer.Vector.prototype.initialize.apply(this, newArguments);
            this.loadAreas();
        },

    loadAreas: function() {
            var layer = this;
            makeGetRequest('GET',layer.uri,'');
            new OpenLayers.Ajax.Request(layer.uri, {method: 'get',
                        requestHeaders: ['Accept', 'text/plain'],
                        onSuccess: function (request) {
                        var features = [], feature;
                        var areas = request.responseText.split("\n");
                        for (var i=0; i<(areas.length-1); ++i) {
                            var wkt_in = areas[i].split(':');
                            feature = layer.wkt.read(wkt_in[1]);

                            if (feature) {
                                feature.fid = wkt_in[0];
                                features.push(feature);
                            } else {
                                alert('Bad WKT: ' + wkt_in[1]);
                            }
                        }
                        layer.addFeatures(features);
                    },
                        onFailure: function (request) {
                        alert('Sorry - there is a problem creating your area selections');
                    }
            });
        },

    deleteSelection: function() {
            var del_fids = [];
            var features = this.selectedFeatures;
            for (var i=0; i < features.length; i++) {
                del_fids.push(features[i].fid);
            }

            if (!del_fids.length) {
                return;
            }
                        
            var body = del_fids.join(',');
            var layer = this;
//makeGetRequest(layer.uri,body);

            new OpenLayers.Ajax.Request(layer.uri, {method: 'delete',
                        postBody: body,                               
                        parameters: {},
                        onSuccess: function() {
                        layer.removeFeatures(features);
                    },
                        onFailure: function() {
//                        layer.removeFeatures(features);
//perform Ajax request
if(body){		    makeGetRequest('DELETE',layer.uri,'/'+body);
                    layer.removeFeatures(features);}

                        //alert('Sorry - there is a problem removing your selection');
                    }}
                ); 
        },

    addFeatures: function(features, options) {
	    var helpSlider = document.getElementById('layersDiv');        
	    var layer = this;
            var fid_features = [];
            var non_fid_features = [];
            var new_arguments = [];

            for (var i=0; i < features.length; i++) {
                var feature = features[i];
                if (feature.fid) {
                    fid_features.push(feature);
                } else {
                    non_fid_features.push(feature);
                }       
            }

            if (non_fid_features.length) {
                // can only process one feature at the moment; this should be changed
                var feature = non_fid_features[0];
                new OpenLayers.Ajax.Request(layer.uri, {method: 'post',
                            postBody: layer.wkt.write(feature),
                            onSuccess: function(transport) {
                            feature.fid = transport.responseText;
                            new_arguments.push([feature], options);
                            OpenLayers.Layer.Vector.prototype.addFeatures.apply(layer, new_arguments);
                        },
                            onFailure: function() {
                            alert('Sorry - there is a problem adding the area');
                        }}
                    );
            } else {
                new_arguments.push(fid_features, options);
		//window.alert(fid_features);
                OpenLayers.Layer.Vector.prototype.addFeatures.apply(this, new_arguments);
            }       
        },
        
    /**
     * Method: destroy
     * Destroy this layer
     */
    destroy: function() {
            // for now, nothing special to do here. 
            OpenLayers.Layer.Vector.prototype.destroy.apply(this, arguments);  
        },

    
    /**
     * Method: clone
     * Create a clone of this layer
     *
     * Returns:
     * {<OGI.Layer.AreaSelection>} An exact clone of this layer
     */
    clone: function (obj) {
        
            if (obj == null) {
                obj = new OGI.Layer.AreaSelection(this.name,
                                                  this.uri,
                                                  this.options);
            }

            //get all additions from superclasses
            obj = OpenLayers.Layer.Vector.prototype.clone.apply(this, [obj]);

            // copy/set any non-init, non-simple values here

            return obj;
        },        

    CLASS_NAME: "OGI.Layer.AreaSelection"
    });

OGI.Handler = {};
/* Override OpenLayers.Handler.Polygon to prevent drawing when the
   shift key has been pressed */
OGI.Handler.PolygonSelect = OpenLayers.Class(OpenLayers.Handler.Polygon, {

    initialize: function(control, callbacks, options) {
            OpenLayers.Handler.Polygon.prototype.initialize.apply(this, arguments);
        },

    mousedown: function(evt) 
    {
        if (!this.drawing && evt['shiftKey']) {
window.alert ("Shift active");
            return true;
        }
        OpenLayers.Handler.Polygon.prototype.mousedown.apply(this, [evt]);
        return false;
    },
    
    CLASS_NAME: "OGI.Handler.PolygonSelect"
    });





OGI.Control = {};
/* Override OpenLayers.Control.SelectFeature to ensure checkModifiers
   in it's handler is honoured when a feature is clicked. */
OGI.Control.SelectArea = OpenLayers.Class(OpenLayers.Control.SelectFeature, {

    initialize: function(layer, options) {
            OpenLayers.Control.SelectFeature.prototype.initialize.apply(this, arguments);
        },
    clickFeature: function(feature) 
    {
        if (!this.handler.checkModifiers(this.handler.evt)) {
            return;
        }
      OpenLayers.Control.SelectFeature.prototype.clickFeature.apply(this, [feature]);
    },

    CLASS_NAME: "OGI.Control.SelectArea"
    });






/**
 * Class: OpenLayers.Control.LayerSwitcher
 *
 * Inherits from:
 *  - <OpenLayers.Control>
 */
OGI.Control.HelpWindow = 
  OpenLayers.Class(OpenLayers.Control, {

    activeColor: "darkblue",
    layerStates: null,
    layersDiv: null,
    baseLayersDiv: null,
    baseLayers: null,
    dataLbl: null,
    dataLayersDiv: null,
    dataLayers: null,
    minimizeDiv: null,
    maximizeDiv: null,
    ascending: true,
    initialize: function(options) {
        OpenLayers.Control.prototype.initialize.apply(this, arguments);
        this.layerStates = [];
    },

    /**
     * APIMethod: destroy 
     */    
    destroy: function() {
        
        OpenLayers.Event.stopObservingElement(this.div);

        OpenLayers.Event.stopObservingElement(this.minimizeDiv);
        OpenLayers.Event.stopObservingElement(this.maximizeDiv);
        OpenLayers.Control.prototype.destroy.apply(this, arguments);
    },

    draw: function() {
        OpenLayers.Control.prototype.draw.apply(this);

        // create layout divs
        this.loadContents();

        // set mode to minimize
        if(!this.outsideViewport) {
            this.minimizeControl();
        }

        // populate div with current info

        return this.div;
    },


    maximizeControl: function(e) {

        //HACK HACK HACK - find a way to auto-size this layerswitcher
        this.div.style.width = "25em";      //box width
        this.div.style.height = "";

        this.showControls(false);

        if (e != null) {
            OpenLayers.Event.stop(e);                                            
        }
    },
    
    minimizeControl: function(e) {

        this.div.style.width = "0px";
        this.div.style.height = "0px";

        this.showControls(true);

        if (e != null) {
            OpenLayers.Event.stop(e);                                            
        }
    },

    /**
     * Method: showControls
     * Hide/Show all LayerSwitcher controls depending on whether we are
     *     minimized or not
     * 
     * Parameters:
     * minimize - {Boolean}
     */
    showControls: function(minimize) {

        this.maximizeDiv.style.display = minimize ? "" : "none";
        this.minimizeDiv.style.display = minimize ? "none" : "";

        this.layersDiv.style.display = minimize ? "none" : "";
    },
    
    /** 
     * Method: loadContents
     * Set up the labels and divs for the control
     */
    loadContents: function() {

        //configure main div
        this.div.style.position = "absolute";
        this.div.style.top = "5px";
        this.div.style.right = "0px";
        this.div.style.left = "";
        this.div.style.fontFamily = "sans-serif";
        this.div.style.fontWeight = "bold";
        this.div.style.marginTop = "3px";
        this.div.style.marginLeft = "3px";
        this.div.style.marginBottom = "3px";
        this.div.style.fontSize = "smaller";   
        this.div.style.color = "white";   
        this.div.style.backgroundColor = "transparent";
    

        // layers list div        
        this.layersDiv = document.createElement("div");
        this.layersDiv.id = "layersDiv";
        this.layersDiv.style.paddingTop = "5px";
        this.layersDiv.style.paddingLeft = "10px";
        this.layersDiv.style.paddingBottom = "5px";
        this.layersDiv.style.paddingRight = "0px";
        this.layersDiv.style.backgroundColor = this.activeColor;
	this.layersDiv.style.fontSize="12px";
	this.layersDiv.style.textAlign="center";
        this.layersDiv.innerHTML="Map controls<br/>";

        // had to set width/height to get transparency in IE to work.
        // thanks -- http://jszen.blogspot.com/2005/04/ie6-opacity-filter-caveat.html
        //
        this.layersDiv.style.width = "100%";
        this.layersDiv.style.height = "100%";


        this.baseLbl = document.createElement("div");
        this.baseLbl.style.marginTop = "3px";
        this.baseLbl.style.marginLeft = "3px";
        this.baseLbl.style.marginBottom = "3px";
	this.baseLbl.style.textAlign="left";
	this.baseLbl.style.fontSize="10px";
	this.baseLbl.innerHTML="<div class='olhelptext'><img src='/images/map/img/pan_off.png'/>&nbsp;Pan<br/><img src='/images/map/img/zoom_in_off.png'/>&nbsp;Zoom in to an area ( <img style='border: none; margin: 0;' src='/javascript/OpenLayers/img/zoom-world-mini.png'/> Zoom right out)<br/><img src='/images/map/img/area_selection_off.png'/>&nbsp;Select areas of interest<br/><img src='/images/map/img/delete_area_off.png'/>&nbsp;Delete selected areas of interest<br/><img src='/images/map/img/query_off.png'/>&nbsp;Query points</div>";

        
        this.baseLayersDiv = document.createElement("div");
        this.baseLayersDiv.style.paddingLeft = "10px";
                     

        this.dataLbl = document.createElement("div");
        this.dataLbl.style.marginTop = "3px";
        this.dataLbl.style.marginLeft = "3px";
        this.dataLbl.style.marginBottom = "3px";
        
        this.dataLayersDiv = document.createElement("div");
        this.dataLayersDiv.style.paddingLeft = "10px";

        if (this.ascending) {
            this.layersDiv.appendChild(this.baseLbl);
            this.layersDiv.appendChild(this.baseLayersDiv);
            this.layersDiv.appendChild(this.dataLbl);
            this.layersDiv.appendChild(this.dataLayersDiv);
        } else {
            this.layersDiv.appendChild(this.dataLbl);
            this.layersDiv.appendChild(this.dataLayersDiv);
            this.layersDiv.appendChild(this.baseLbl);
            this.layersDiv.appendChild(this.baseLayersDiv);
        }    
 
        this.div.appendChild(this.layersDiv);

        OpenLayers.Rico.Corner.round(this.div, {corners: "tl bl",
                                        bgColor: "transparent",
                                        color: this.activeColor,
                                        blend: false});

        OpenLayers.Rico.Corner.changeOpacity(this.layersDiv, 0.65);

        var imgLocation = OpenLayers.Util.getImagesLocation();
        var sz = new OpenLayers.Size(18,18);        

        // maximize button div
        var img = imgLocation + 'layer-switcher-maximize.png';
        this.maximizeDiv = OpenLayers.Util.createAlphaImageDiv(
                                    "OpenLayers_Control_MaximizeDiv", 
                                    null, 
                                    sz, 
                                    img, 
                                    "absolute");
        this.maximizeDiv.style.top = "5px";
        this.maximizeDiv.style.right = "0px";
        this.maximizeDiv.style.left = "";
        this.maximizeDiv.style.display = "none";
        OpenLayers.Event.observe(this.maximizeDiv, "click", 
            OpenLayers.Function.bindAsEventListener(this.maximizeControl, this)
        );
        
        this.div.appendChild(this.maximizeDiv);

        // minimize button div
        var img = imgLocation + 'layer-switcher-minimize.png';
        var sz = new OpenLayers.Size(18,18);        
        this.minimizeDiv = OpenLayers.Util.createAlphaImageDiv(
                                    "OpenLayers_Control_MinimizeDiv", 
                                    null, 
                                    sz, 
                                    img, 
                                    "absolute");
        this.minimizeDiv.style.top = "5px";
        this.minimizeDiv.style.right = "0px";
        this.minimizeDiv.style.left = "";
        this.minimizeDiv.style.display = "none";
        OpenLayers.Event.observe(this.minimizeDiv, "click", 
            OpenLayers.Function.bindAsEventListener(this.minimizeControl, this)
        );

        this.div.appendChild(this.minimizeDiv);
    },
    
    /** 
     * Method: ignoreEvent
     * 
     * Parameters:
     * evt - {Event} 
     */
    ignoreEvent: function(evt) {
        OpenLayers.Event.stop(evt);
    },

    /** 
     * Method: mouseDown
     * Register a local 'mouseDown' flag so that we'll know whether or not
     *     to ignore a mouseUp event
     * 
     * Parameters:
     * evt - {Event}
     */
    mouseDown: function(evt) {
        this.isMouseDown = true;
        this.ignoreEvent(evt);
    },

    /** 
     * Method: mouseUp
     * If the 'isMouseDown' flag has been set, that means that the drag was 
     *     started from within the LayerSwitcher control, and thus we can 
     *     ignore the mouseup. Otherwise, let the Event continue.
     *  
     * Parameters:
     * evt - {Event} 
     */
    mouseUp: function(evt) {
        if (this.isMouseDown) {
            this.isMouseDown = false;
            this.ignoreEvent(evt);
        }
    },

    CLASS_NAME: "OGI.Control.HelpWindow"
});







OGI.Control.QueryWindow = 
  OpenLayers.Class(OpenLayers.Control, {

    activeColor: "darkblue",
    layerStates: null,
    layersDiv: null,
    baseLayersDiv: null,
    baseLayers: null,
    dataLbl: null,
    dataLayersDiv: null,
    dataLayers: null,
    minimizeDiv: null,
    maximizeDiv: null,
    ascending: true,
    initialize: function(options) {
        OpenLayers.Control.prototype.initialize.apply(this, arguments);
        this.layerStates = [];
    },

    /**
     * APIMethod: destroy 
     */    
    destroy: function() {
        
        OpenLayers.Event.stopObservingElement(this.div);

        OpenLayers.Event.stopObservingElement(this.minimizeDiv);
        OpenLayers.Event.stopObservingElement(this.maximizeDiv);
        OpenLayers.Control.prototype.destroy.apply(this, arguments);
    },

    draw: function() {
        OpenLayers.Control.prototype.draw.apply(this);

        // create layout divs
        this.loadContents();

        // set mode to minimize
        if(!this.outsideViewport) {
            this.hideControl();
        }

        // populate div with current info

        return this.div;
    },


    maximizeControl: function(e) {

        //HACK HACK HACK - find a way to auto-size this layerswitcher
	this.div.style.display = "block";
        this.div.style.width = "25em";      //box width
        this.div.style.height = "";

        this.showControls(false);

        if (e != null) {
            OpenLayers.Event.stop(e);                                            
        }
    },
    
    minimizeControl: function(e) {
	this.div.style.display = "block";
        this.div.style.width = "0px";
        this.div.style.height = "0px";

        this.showControls(true);

        if (e != null) {
            OpenLayers.Event.stop(e);                                            
        }
    },

    hideControl: function(e) {

	this.div.style.display = "none";

        this.showControls(true);

        if (e != null) {
            OpenLayers.Event.stop(e);                                            
        }
    },


    /**
     * Method: showControls
     * Hide/Show all LayerSwitcher controls depending on whether we are
     *     minimized or not
     * 
     * Parameters:
     * minimize - {Boolean}
     */
    showControls: function(minimize) {

        this.maximizeDiv.style.display = minimize ? "" : "none";
        this.minimizeDiv.style.display = minimize ? "none" : "";

        this.layersDiv.style.display = minimize ? "none" : "";
    },
    
    /** 
     * Method: loadContents
     * Set up the labels and divs for the control
     */
    loadContents: function() {

        //configure main div
        this.div.style.position = "absolute";
        this.div.style.top = "250px";
        this.div.style.right = "0px";
        this.div.style.left = "";
        this.div.style.fontFamily = "sans-serif";
        this.div.style.fontWeight = "bold";
        this.div.style.marginTop = "3px";
        this.div.style.marginLeft = "3px";
        this.div.style.marginBottom = "3px";
        this.div.style.fontSize = "smaller";   
        this.div.style.color = "white";   
        this.div.style.backgroundColor = "transparent";
    

        // layers list div        
        this.layersDiv = document.createElement("div");
        this.layersDiv.id = "queryDiv";
        this.layersDiv.style.paddingTop = "5px";
        this.layersDiv.style.paddingLeft = "10px";
        this.layersDiv.style.paddingBottom = "5px";
        this.layersDiv.style.paddingRight = "2px";
        this.layersDiv.style.backgroundColor = this.activeColor;
	this.layersDiv.style.fontSize="12px";
	this.layersDiv.style.textAlign="center";
        this.layersDiv.innerHTML="Query results<br/>";

        // had to set width/height to get transparency in IE to work.
        // thanks -- http://jszen.blogspot.com/2005/04/ie6-opacity-filter-caveat.html
        //
        this.layersDiv.style.width = "100%";
        this.layersDiv.style.height = "100%";


        this.baseLbl = document.createElement("div");
        this.baseLbl.id = "queryDivcontent";
        this.baseLbl.style.marginTop = "3px";
        this.baseLbl.style.marginLeft = "3px";
        this.baseLbl.style.marginRight = "3px";
        this.baseLbl.style.marginBottom = "3px";
	this.baseLbl.style.paddingRight = "20px";
	this.baseLbl.style.textAlign="left";
	this.baseLbl.style.fontSize="10px";
	this.baseLbl.innerHTML="";

        
        this.baseLayersDiv = document.createElement("div");
        this.baseLayersDiv.style.paddingLeft = "10px";
                     

        this.dataLbl = document.createElement("div");
        this.dataLbl.style.marginTop = "3px";
        this.dataLbl.style.marginLeft = "3px";
        this.dataLbl.style.marginRight = "1px";
        this.dataLbl.style.marginBottom = "3px";
        
        this.dataLayersDiv = document.createElement("div");
        this.dataLayersDiv.style.paddingLeft = "10px";

        if (this.ascending) {
            this.layersDiv.appendChild(this.baseLbl);
            this.layersDiv.appendChild(this.baseLayersDiv);
            this.layersDiv.appendChild(this.dataLbl);
            this.layersDiv.appendChild(this.dataLayersDiv);
        } else {
            this.layersDiv.appendChild(this.dataLbl);
            this.layersDiv.appendChild(this.dataLayersDiv);
            this.layersDiv.appendChild(this.baseLbl);
            this.layersDiv.appendChild(this.baseLayersDiv);
        }    
 
        this.div.appendChild(this.layersDiv);

        OpenLayers.Rico.Corner.round(this.div, {corners: "tl bl",
                                        bgColor: "transparent",
                                        color: this.activeColor,
                                        blend: false});

        OpenLayers.Rico.Corner.changeOpacity(this.layersDiv, 0.65);

        var imgLocation = OpenLayers.Util.getImagesLocation();
        var sz = new OpenLayers.Size(18,18);        

        // maximize button div
        var img = imgLocation + 'layer-switcher-maximize.png';
        this.maximizeDiv = OpenLayers.Util.createAlphaImageDiv(
                                    "OpenLayers_Control_MaximizeDiv", 
                                    null, 
                                    sz, 
                                    img, 
                                    "absolute");
        this.maximizeDiv.style.top = "5px";
        this.maximizeDiv.style.right = "0px";
        this.maximizeDiv.style.left = "";
        this.maximizeDiv.style.display = "none";
        OpenLayers.Event.observe(this.maximizeDiv, "click", 
            OpenLayers.Function.bindAsEventListener(this.maximizeControl, this)
        );
        
        this.div.appendChild(this.maximizeDiv);

        // minimize button div
        var img = imgLocation + 'layer-switcher-minimize.png';
        var sz = new OpenLayers.Size(18,18);        
        this.minimizeDiv = OpenLayers.Util.createAlphaImageDiv(
                                    "OpenLayers_Control_MinimizeDiv", 
                                    null, 
                                    sz, 
                                    img, 
                                    "absolute");
        this.minimizeDiv.style.top = "5px";
        this.minimizeDiv.style.right = "0px";
        this.minimizeDiv.style.left = "";
        this.minimizeDiv.style.display = "none";
        OpenLayers.Event.observe(this.minimizeDiv, "click", 
            OpenLayers.Function.bindAsEventListener(this.minimizeControl, this)
        );

        this.div.appendChild(this.minimizeDiv);
    },
    
    /** 
     * Method: ignoreEvent
     * 
     * Parameters:
     * evt - {Event} 
     */
    ignoreEvent: function(evt) {
        OpenLayers.Event.stop(evt);
    },

    /** 
     * Method: mouseDown
     * Register a local 'mouseDown' flag so that we'll know whether or not
     *     to ignore a mouseUp event
     * 
     * Parameters:
     * evt - {Event}
     */
    mouseDown: function(evt) {
        this.isMouseDown = true;
        this.ignoreEvent(evt);
    },

    /** 
     * Method: mouseUp
     * If the 'isMouseDown' flag has been set, that means that the drag was 
     *     started from within the LayerSwitcher control, and thus we can 
     *     ignore the mouseup. Otherwise, let the Event continue.
     *  
     * Parameters:
     * evt - {Event} 
     */
    mouseUp: function(evt) {
        if (this.isMouseDown) {
            this.isMouseDown = false;
            this.ignoreEvent(evt);
        }
    },

    CLASS_NAME: "OGI.Control.QueryWindow"
});



/* This class manages the map and layers; it is the primary OGI class.
   Its constructor accepts the URL of an OGI REST interface and the
   URL of a WMS base layer. */
OGI.Manager = OpenLayers.Class({

    map: null,
    wms_layer: null,
    area_selection: null,

    initialize: function(ogi_url, wms_url) {
            this.url = ogi_url;
            var self = this;
            new OpenLayers.Ajax.Request(ogi_url, {method: 'get',
                        requestHeaders: ['Accept', 'application/json'],
                        onSuccess: function (req) {
                        var map_state = eval('('+req.responseText+')');
                        self.initMap(map_state, wms_url);
                        self.initLayerControls(map_state['layer_groups']);
                    },
                        onFailure: function (req) {
                        alert('Sorry - there is a problem creating the map');
                    }
            });
            
        },

    /* Create the map based on state information */
    initMap: function (state, wms_url) {
            // Create the layers

            this.wms_layer = new OGI.Layer.WMSGroup( "WMS", 
                                                     wms_url,
                                                     state['layer_groups'],
    {},
    {singleTile: true}
                                                     );
            

OpenLayers.Renderer.SVG.prototype.supported = function() {
        var svgFeature = "http://www.w3.org/TR/SVG11/feature#";
        return (document.implementation &&
           (document.implementation.hasFeature("org.w3c.svg", "1.0") ||
            document.implementation.hasFeature(svgFeature + "SVG", "1.1") ||
            document.implementation.hasFeature(svgFeature + "BasicStructure", "1.1") ));
};




            var area_style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
            area_style.strokeColor = "#FF1616"; 
            area_style.fillColor = "#FF1616";
            this.selection_layer = new OGI.Layer.AreaSelection("Area Selection", this.url + '/area_selections', {style: area_style});
            var self = this;
            this.selection_layer.keyboard = new OpenLayers.Handler.Keyboard( this.selection_layer, {"keyup": function (keyup) {
                        if (keyup == 46) { // the delete key
                            self.selection_layer.deleteSelection();
                        }
                    }
                }    
                );
            this.selection_layer.keyboard.activate();

            // Create the map
//            var max_extent = OpenLayers.Bounds.fromArray(state['max_extent']);
	    var max_extent= new OpenLayers.Bounds(70000, -4000, 696000, 260000);
            this.map = new OpenLayers.Map( $('map'), {'maxResolution': 'auto',
					 'maxExtent': new OpenLayers.Bounds(70000, -4000, 696000, 260000),
                                        //              'maxExtent': max_extent,
                                                      'projection': 'EPSG:27700',
                                                      'units': 'm'});

            this.layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
                    wms_url, {layers: 'uk,osgb_10km_grid2'} );
//            this.map.addLayer(this.layer);

            this.map.addLayer(this.wms_layer);
	    this.map.events.register("click", this.wms_layer, handle_point_query);
            // Add the layers
//            this.map.addLayer(this.wms_layer_overview);

//            this.map.addLayer(this.selection_layer);
 //           window.alert (max_extent);
//            this.map.addLayer(this.slr);

            // Set the map viewport
            if (state['zoom']) {
                var zoom = state['zoom'];
                // zoom in to the last viewport
                var centre = new OpenLayers.LonLat(zoom['centre']['x'], zoom['centre']['y']);
                this.map.setCenter(centre, zoom['level'], false, false);
            } else {
                // zoom to the maximum map extent
                this.map.zoomToMaxExtent();
            }

	    //add an overview map



  var wms_layer_overview = new OpenLayers.Layer.WMS( "WMS",
                wms_url, 
                {layers: "uk,urban_areas"});




	    //add an overview map
	    var overview_map_params = { 'theme':'null',
					'minResolution': '300',
					'maxResolution': '1400',
                                        'maxExtent': max_extent,
                                        'projection': 'EPSG:27700',
          			        'format': 'image/png',
                                        'units': 'm'
					};
//	    this.map.addControl(new OpenLayers.Control.OverviewMap({div: $("overviewmap"),layers: [wms_layer_overview], theme: null, size: new OpenLayers.Size(250, 100), mapOptions: overview_map_params}));




            var scalebar = new OpenLayers.Control.ScaleBar();
           this.map.addControl(scalebar);
	    

            this.map.addControl(new OpenLayers.Control.MousePosition());
            this.area_controls = {
	            nav: new OpenLayers.Control.Navigation(),
        	    area_select: new OGI.Control.SelectArea(this.selection_layer, {multiple: true}),
	            delete_area: new OGI.Control.SelectArea(this.selection_layer, {multiple: true}),
        	    draw_poly: new OpenLayers.Control.DrawFeature(this.selection_layer, OGI.Handler.PolygonSelect),
		    zoom_in: new OpenLayers.Control.ZoomBox(this.selection_layer),
		    query_window: new OGI.Control.QueryWindow()
            };
            this.area_controls['area_select'].handler.keyMask = OpenLayers.Handler.MOD_SHIFT;
		this.map.addControl(new OGI.Control.HelpWindow());
            for (var key in this.area_controls) {
                this.map.addControl(this.area_controls[key]);
            }
        },
    /* Initialise the state of the layer controls */
    initLayerControls: function (layer_groups) {
            for (var name in layer_groups) {
                var checkbox = $(name);
                if (checkbox) {
                    checkbox.checked = layer_groups[name]['status'];
                }
            }
        },

    updateLayers: function() {
               this.wms_layer.mergeLayers();
        },

    toggleLayerGroup: function(name, state) {
            if (state) {
                this.wms_layer.turnGroupOn(name);
            } else {
                this.wms_layer.turnGroupOff(name);
            }
        },

maximizeQueryControl: function(){
this.area_controls['query_window'].maximizeControl();
},
minimizeHelpControl: function(){
this.area_controls['help_window'].minimizeControl();
},


    toggleControls: function(state) {
 for (var key in this.area_controls) {
                var control = this.area_controls[key];
		control.deactivate();
}
var control = this.area_controls[state];
control.activate();
if (state=='draw_poly'){var control2 = this.area_controls['area_select']; control2.activate();}
},

    saveState: function() {
            var centre = this.map.getCenter();
            var state = {'layer_groups': this.wms_layer.groups,
                         'max_extent': this.map.getMaxExtent().toArray(),
                         'zoom': {'level': this.map.getZoom(),
                                  'centre': {'x': centre.lon,
                                             'y': centre.lat}}};
            var json = new OpenLayers.Format.JSON();
   
            // save the map state
            new OpenLayers.Ajax.Request(this.url, {method: 'put',
                        postBody: json.write(state),
                        onFailure: function (req) {
                        alert('Sorry - the state of your current map could not be saved');
                    }
            });            
        },
    
    CLASS_NAME: "OGI.Manager"
    });

