/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
 * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
 * full text of the license. */


/**
 * @requires OpenLayers/Layer/Grid.js
 * @requires OpenLayers/Tile/Image.js
 * @requires OpenLayers.Layer.WMS
 */

/**
 * Class: OpenLayers.Layer.WMSReproj
 * Instances of OpenLayers.Layer.WMSReproj are used to display data from OGC Web
 * Mapping Services. Create a new WMS layer with the <OpenLayers.Layer.WMSReproj>
 * constructor. This layer will actually respect the reproject parameter
 * 
 * Inherits from:
 *  - <OpenLayers.Layer.WMS>
 */
OpenLayers.Layer.WMSReproj = OpenLayers.Class(OpenLayers.Layer.WMS, {
    /**
     * Property: reproject
     * {Boolean} Try to reproject this layer if its coordinate reference system
     *           is different than that of the base layer.  Default is true.  
     *           Set this in the layer options. Just use the normal WMS or set 
     *           to false if you do not want this functionality. 
     */
    reproject: true,
	
	/**
	 * Property: projection
	 * {String | OpenLayers.Projection} REQUIRED if reproject is true. 
	 * The projection that the WMS expects the bbox parameter in.
	 */
	targetProjection: null,
 
    /**
     * APIProperty: isBaseLayer
     * {Boolean} Default is false for this type of WMS layer
     */
    isBaseLayer: false,

    initialize: function(name, url, params, options) {
		OpenLayers.Layer.WMS.prototype.initialize.apply(this,arguments);
        this.events.on({
            "loadstart": function(){
                this.mapProjection = this.map.getProjectionObject();
				this.requireTransform = !(this.targetProjection.equals(this.mapProjection));
            },
            "loadend": function(){
                this.mapProjection = null;
				this.requireTransform = false;
            },
            scope: this
        });
    },
	
	
	/**
     * Method: getURL
     * Return a GetMap query string for this layer
     *
     * Parameters:
     * bounds - {<OpenLayers.Bounds>} A bounds representing the bbox for the
     *                                request.
     *
     * Returns:
     * {String} A string with the layer's url and parameters and also the
     *          passed-in bounds and appropriate tile size specified as 
     *          parameters.
     */
    getURL: function (bounds) {
        if(this.mapProjection && this.requireTransform){
			bounds.transform(this.mapProjection,this.targetProjection)
		}
		//call parent function
		return OpenLayers.Layer.WMS.prototype.getURL.call(this,bounds);
    },
	
	   /**
     * Method: setMap
     * Set the map property for the layer. This is done through an accessor
     *     so that subclasses can override this and take special action once 
     *     they have their map variable set. 
     * 
     *     Here we take care to bring over any of the necessary default 
     *     properties from the map. 
     * 
     * Parameters:
     * map - {<OpenLayers.Map>}
     */
    setMap: function(map){
		if (this.targetProjection && typeof this.targetProjection == "string") {
			this.targetProjection = new OpenLayers.Projection(this.targetProjection);
		}
		//call parent function
		OpenLayers.Layer.WMS.prototype.setMap.apply(this,arguments);
	},
	
    /** 
     * APIMethod: getFullRequestString
     * Combine the layer's url with its params and these newParams. 
     *   
     *     Add the SRS parameter from projection -- this is probably
     *     more eloquently done via a setProjection() method, but this 
     *     works for now and always.
     *
     * Parameters:
     * newParams - {Object}
     * altUrl - {String} Use this as the url instead of the layer's url
     * 
     * Returns:
     * {String} 
     */
    getFullRequestString:function(newParams, altUrl) {
        var projectionCode = this.targetProjection.getCode();
        var value = (projectionCode == "none") ? null : projectionCode
        if (parseFloat(this.params.VERSION) >= 1.3) {
            this.params.CRS = value;
        } else {
            this.params.SRS = value;
        }

        return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(
                                                    this, arguments);
    },	
	
	CLASS_NAME: "OpenLayers.Layer.WMSReproj"
});

