/** Top-level javascript file for the IPCC DDC visualisation application.

    @author Stephen Pascoe
*/

WMSC.VisApp = OpenLayers.Class.create();
WMSC.VisApp.prototype = {
    initialize: function(div, control) {
	this.layerControl = control;
	this.figureCounter = 1;
	this.showCoast = 1;

	// This is taken from Layer.js with slight alterations.  One
	// can't override both numZoomLevels and minResolution with
	// the current OpenLayers code.  Instead calculate resolutions
	// directly.
	var numZoomLevels = 10;
	var maxResolution = 0.5625;
	var resolutions = new Array();
	for (var i=0; i < numZoomLevels; i++) {
	    resolutions.push(maxResolution / Math.pow(1.4, i));
	}

	this.map = new WMSC.Map(div, { 
	    resolutions: resolutions,
	    controls: []
	});

	this.boxesLayer = new OpenLayers.Layer.Boxes("Sub-selection");
	this.subselControl = new WMSC.SubSelectionMouseToolbar(new OpenLayers.Pixel(5,240),
							       'vertical', this.boxesLayer);

	this.map.events.register('moveend', this, this.updateLayerControl);
	this.map.events.register('zoomend', this, this.updateLayerControl);
	this.layerControl.events.register('changeSelection', this, this.updateSelectionBox);
	this.layerControl.events.register('changeWMS', this, this.updateVisLayer);

	this.map.addControl(new OpenLayers.Control.PanZoomBar());
	this.map.addControl(this.subselControl);
	this.map.addControl(new OpenLayers.Control.MousePosition());

	// Setup a dummy baselayer.  This will be replaced asynchronously by this.updateVisLayer()
	this.updateVisLayer();

	this.coastLayer = null;
	if (this.showCoast) {
	    this._initCoast('coastline_01');
	}

	this.map.addLayer(this.boxesLayer);
	this.map.zoomToExtent(new OpenLayers.Bounds(-180,-90,180,90));	
    },
    destroy: function() {
	this.layerControl.destroy();
	//!not working
	//this.map.destroy();
	this.boxesLayer.destroy();
	this.subselControl.destroy();
    },

    _initCoast: function(layerName) {
	if (this.coastLayer) {
	    if (this.coastLayer.params.LAYERS == layerName) {
		return;
	    }
	    else {
		this.map.removeLayer(this.coastLayer);
	    }
	}
	this.coastLayer = new OpenLayers.Layer.WMS("Coastline",
						   "http://labs.metacarta.com/wms/vmap0",
						   {layers: layerName, format: 'image/gif',
						    transparent: 'true'});
	this.map.addLayer(this.coastLayer);
    },

    updateVisLayer: function() {
	if (this.visLayer) {
	    this.map.removeLayer(this.visLayer);
	}
	if (this.layerControl.wmsEndpoint == null) {
	    // Setup a dummy baselayer.
	    this.visLayer = new OpenLayers.Layer.WMS("OpenLayers WMS",
						     "http://labs.metacarta.com/wms/vmap0",
						     {layers: 'basic',format: 'image/png'});
	}
	else {
			// if this is a wmc layer, use the url in the layer
			endpoint = this.layerControl._selectedLayer.getEndpoint();
			if (endpoint == null)
				endpoint = this.layerControl.wmsEndpoint;
	    	this.visLayer = new OpenLayers.Layer.WMS("DDC-Vis layer",
	    					endpoint,
						     {format: 'image/png',
						      version: '1.3.0', CRS: 'CRS:84'
						     });
	}
	this.visLayer.mergeNewParams(this.layerControl.wmsParams);
	this.visLayer.setZIndex(300);
        this.map.addLayer(this.visLayer);
	this.loadLegend();
    },	

    clearSubsel: function() {
	this.subselControl.deactivateSubsel();
	this.updateLayerControl();
    },

    loadLegend: function() {
	function setLegend(response) {
	    $('legend').innerHTML = response.responseText;
	}

	if (this.layerControl.wmsEndpoint == null) {
	    $('legend').innerHTML = '';
	}
	else {
	    var url = this.visLayer.getFullRequestString({
		REQUEST: 'GetLegend',
		FORMAT: 'text/html'
	    });
	    OpenLayers.loadURL(url, '', this, setLegend);
	}
    },

    makeFigure: function(typeInput, formatSelect) {
	var clim = this.visLayer;
	var caption = 'IPCC Data Distribution Centre: www.ipcc-data.org\n' + this.layerControl.getStateDescription().join('.\n');
	if (typeInput.length) {
	    for (var i=0; i<typeInput.length; i++) {
		if (typeInput[i].checked) {
		    var figType = typeInput[i].value;
		    break;
		}
	    }
	}
	else {
	    if (typeInput.checked) {
		var figType = typeInput.value;
	    }
	    else {
		var figType = 'colour';
	    }
	}


	var url = clim.getFullRequestString({
              REQUEST: 'GetFigure',
			   BBOX: this.subselControl.getActiveBounds().toBBOX(),
			   CAPTION: caption,
			   TYPE: figType,
			   //FORMAT: form.fig_format.value
	                   FORMAT: formatSelect.value
			   });
	if (formatSelect.value == 'application/postscript') {
	    location.href = url;
	}
	else {
	    window.open(url, 'figure_'+this.figureCounter, 'toolbars=no,location=no,directories=no,menubar=no');
	    this.figureCounter++;
	}
    },
    
    updateLayerControl: function() {
	var b = this.subselControl.getActiveBounds();
	this.layerControl.setSelection(b, noCascade=true);

	// Switch to higerres coasts if needed
	var coastLayer;
	if (this.map.getZoom() > 5) {
	    coastLayer = 'coastline_02';
	}
	else {
	    coastLayer = 'coastline_01';
	}
	if (this.showCoast && this.coastLayer.params.LAYERS != coastLayer) {
	    this._initCoast(coastLayer);
	}
    },
    updateSelectionBox: function() {
	var old_b = this.subselControl.getActiveBounds();
	var new_b = this.layerControl.getSelection();
	
	// Validation.  negative tests required to catch NaN
	if (!(new_b.left > -180.0 && new_b.left < 180.0)) {
	    new_b.left = old_b.left;
	}
	if (!(new_b.right > -180.0 && new_b.right < 180.0)) {
	    new_b.right = old_b.right;
	}
	if (!(new_b.top > -90.0 && new_b.top < 90.0)) {
	    new_b.top = old_b.top;
	}
	if (!(new_b.bottom > -90.0 && new_b.bottom < 90.0)) {
	    new_b.bottom = old_b.bottom;
	}
	if (new_b.left > new_b.right) {
	    var t = new_b.left; new_b.left = new_b.right; new_b.right = t;
	}
	if (new_b.bottom > new_b.top) {
	    var t = new_b.bottom; new_b.bottom = new_b.top; new_b.top = t;
	}
	
	this.subselControl.setSubSel(new_b);
    }
};

