/**
* WIYBY Enhancements 2008
* 
* WIYBY RELEASE 13.1
*
* Author : ESRI(UK) Stuart Mellanby
* Version:		$Revision: 1.12 $
* Date : 01/02/2008
* 
* Copyright Environment Agency 2008 - not to be distributed
* or used without explicit permission from the Environment Agency
*/

/* Copyright (c) 2006-2007 MetaCarta, Inc., published under the BSD license.
 * See http://svn.openlayers.org/trunk/openlayers/release-license.txt 
 * for the full text of the license. */

/** 
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/BaseTypes.js
 * @requires OpenLayers/Events.js
 *
 * Class: WiybyOverViewControl
 * Create an overview map to display the extent of your main map and provide
 * additional navigation control.  Create a new overview map with the
 * <WiybyOverViewControl> constructor.
 *
 * Inerits from:
 *  - <OpenLayers.Control>
 */
WiybyOverViewControl = OpenLayers.Class(OpenLayers.Control, {
	
	/**
     * Property: id
     * {String} For div.id
     */
    id:  "WiybyOverViewControl",
    
    /**
     * Property: element
     * {DOMElement} The DOM element that contains the overview map active click div
     */
    element: null,
       
    /**
     * Property: width
     * {String} For mapOverViewExtentsRectangle
     */
    width:  130,
    
	/**
     * Property: height
     * {String} For mapOverViewExtentsRectangle
     */
	height:  123,
		
	overviewTopOriginal: null,
	overviewLeftOriginal: null,
	//overviewSideLengthOriginal: null,
	overviewTopSideLengthOriginal: null,
	overviewLeftSideLengthOriginal: null,
	
	/*ovMinX:  -75491,
	ovMaxX:  818173,
	ovMinY:  -2708,
	ovMaxY:  690285,*/
	ovMinX:  -25049,
	ovMaxX:  764289,
	ovMinY:  -34153,
	ovMaxY:  714353,
	
	/**
     * APIProperty: ovmap
     * {<OpenLayers.Bounds>} A reference to the overview rectangle bounding box.
     */
    bounds: null,
    
    /**
     * APIProperty: events
     * {<OpenLayers.Events>} An events object that handles all 
     *                       events on the map
     */
    events: null,
    
  
    draw: function() 
   	{
		this.calculateOverviewExtent();
       	this.drawOvMapDiv();
		this.registerClickEvents();
   	
   	},
	
	registerClickEvents: function()
	{
		var currentDiv = OpenLayers.Util.getElement("ovmapimage");
		this.elementEvents = new OpenLayers.Events(currentDiv, currentDiv);
        this.elementEvents.register('mousedown', this, this.overViewMapClick);
	},
	
	drawOvMapDiv: function()
	{
		if ( map.getZoom() == 0 )
		{
			this.writeOvDiv("overviewMapRegionTop", 	"0", 	"0", 	0, 0, "red");
			this.writeOvDiv("overviewMapRegionLeft", 	"0", 	"0", 	0, 0, "red");
			this.writeOvDiv("overviewMapRegionRight", 	"0", 	"0", 	0, 0, "red");
			this.writeOvDiv("overviewMapRegionBottom", 	"0", 	"0", 	0, 0, "red"); 
		}
		else
		{	
			var borderWeight = 2;
			var overviewMapRegionTopTop;
			var overviewMapRegionLeftTop;
			var overviewMapRegionRightTop;
			var overviewMapRegionBottomTop;
			
			var leftTop = this.overviewTopOriginal + borderWeight;
			overviewMapRegionTopTop = this.overviewTopOriginal;
			overviewMapRegionLeftTop = leftTop;
			
			//To aid drawin a complte rectangle for largest scale
			if (this.overviewLeftSideLengthOriginal == 0)
			{
				//TODO maybe remove
				this.overviewLeftSideLengthOriginal = 1;
			}
			
			var bottom = this.overviewTopOriginal + this.overviewLeftSideLengthOriginal;
			
			overviewMapRegionRightTop = this.overviewTopOriginal;
			overviewMapRegionBottomTop = bottom;
			
			var overviewMapRegionTopLeft = "";
			var overviewMapRegionLeftLeft = "";
			var overviewMapRegionRightLeft = "";
			var overviewMapRegionBottomLeft = "";
			 
			overviewMapRegionTopLeft = this.overviewLeftOriginal;
			overviewMapRegionLeftLeft = this.overviewLeftOriginal;

			var right = this.overviewLeftOriginal + this.overviewTopSideLengthOriginal;
			var bottomLeft = this.overviewLeftOriginal + borderWeight;
			
			overviewMapRegionRightLeft = right;
			overviewMapRegionBottomLeft = bottomLeft;	
			
			this.trimOverviewDivExtents("overviewMapRegionTop", 	this.overviewTopSideLengthOriginal, 	borderWeight, 							overviewMapRegionTopTop, overviewMapRegionTopLeft, "red");
			this.trimOverviewDivExtents("overviewMapRegionLeft", 	borderWeight, 							this.overviewLeftSideLengthOriginal, 	overviewMapRegionLeftTop, overviewMapRegionLeftLeft, "red");
			this.trimOverviewDivExtents("overviewMapRegionRight", 	borderWeight , 							this.overviewLeftSideLengthOriginal, 	overviewMapRegionRightTop, overviewMapRegionRightLeft, "red");
			this.trimOverviewDivExtents("overviewMapRegionBottom", 	this.overviewTopSideLengthOriginal, 	borderWeight, 							overviewMapRegionBottomTop, overviewMapRegionBottomLeft, "red");
		}
	},
	
	writeOvDiv: function( divNameToWrite, width, height, top, left, colour)
	{
		var currentDiv = OpenLayers.Util.getElement(divNameToWrite);
		currentDiv.style.width = width + "px";
		currentDiv.style.height = height + "px";
   		currentDiv.style.top = top + "px";
   		currentDiv.style.left = left + "px";
		currentDiv.style.backgroundColor = colour;
	},
	
	
	//TODO offsetleft in ie reports the correct value BUT and a big BUT
	// i have have left the offsetleft in here as i use it but reduce any impact as it is added and removed, thus neutralising and effect. 
	// ff said offsetleft = 0, offsettop = 6, ie = 3, 6. But it doesn't use it in drawing, see quirksmode
	// REF: this also effect the caloverview extents. 
	trimOverviewDivExtents: function(divNameToWrite, width, height, top, left, colour)
	{
		var ovImageDiv = OpenLayers.Util.getElement("ovmapimage");
		var ovImgOffsetLeft = ovImageDiv.offsetLeft;
		var ovImgOffsetTop = ovImageDiv.offsetTop;
		
		if (divNameToWrite == "overviewMapRegionTop" || divNameToWrite == "overviewMapRegionBottom" )
		{
			if ( (top < ovImgOffsetTop) || (top > (this.height + ovImgOffsetTop) ) )
			{ 
				width = 0;
				height = 0;
				top=0;
				left=0;
			}
			else if (left > (this.width + ovImgOffsetLeft) )
			{
				width = 0;
				height = 0;
				top = 0;
				left = 0;
			}
			else if ((left < ovImgOffsetLeft) && (left + width < (this.width + ovImgOffsetLeft) ))
			{
				if (ovImgOffsetLeft == 0)
				{
					width -= Math.abs(left);
				}
				else
				{
					width -= Math.abs(ovImgOffsetLeft -left);
				}
				left = ovImgOffsetLeft;	
				
			}
			else if((left > ovImgOffsetLeft) && (left + width > (this.width + ovImgOffsetLeft) ) )
			{
				//height -= (this.height + ovImgOffsetTop) - (top + height);
				width -= (left  + width) - (this.width + ovImgOffsetLeft) ;	
				
			}
			this.writeOvDiv(divNameToWrite, width, height, top, left, colour);

		}
		if (divNameToWrite == "overviewMapRegionLeft" || divNameToWrite == "overviewMapRegionRight" )
		{
			
			if ( (left < ovImgOffsetLeft) || (left > (this.width + ovImgOffsetLeft)))
			{ 
				width = 0;
				height = 0;
				top = 0;
				left = 0;
			}
			else if (top > (this.height + ovImgOffsetTop))
			{
				width = 0;
				height = 0;
				top = 0;
				left = 0;
			}
			else if ((top < ovImgOffsetTop) && (top + height < (this.height + ovImgOffsetTop )))
			{
				if (ovImgOffsetTop == 0)
				{
					height -= Math.abs(top);
				}
				else
				{
					height -= Math.abs(ovImgOffsetTop - top);
				} 
				top = ovImgOffsetTop;	
				
			}
			else if ((top > ovImgOffsetTop) && (top + height > (this.height + ovImgOffsetTop)) )
			{
				height -= (top + height) - (this.height + ovImgOffsetTop);
			}
			this.writeOvDiv(divNameToWrite, width, height, top, left, colour);
			
		}
	},
   	
   	/**
   	 * utility to convert clikc on overview map to real world coords
   	 */
   	overViewMapClick: function(evt)
   	{
   		var inputImageHeight = this.height;
   		var inputImageWidth = this.width;

		// -----------------------------------------------
		// calculate the real world x coordinates per pixel
		var xExtent = this.ovMaxX - this.ovMinX;
		var xPerPixel = xExtent / inputImageWidth;
		// -----------------------------------------------	    
		// calculate the real world y coordinates per pixel  
		var yExtent = this.ovMaxY - this.ovMinY;
		var yPerPixel = yExtent / inputImageHeight;
		// -----------------------------------------------
		
		var clickX = evt.xy.x;
		var clickY = evt.xy.y;
		
		var realX = (xPerPixel * clickX ) + this.ovMinX;
		// the click coordinates are from a top left origin, not the top left web html element origin
		var realY = this.ovMaxY - (yPerPixel * clickY ); 
		// -----------------------------------------------
		// return the real world coordinates their mouse click
		
		var realWorldClickCentrePixel = new OpenLayers.Pixel( realX, realY );
		var requestCenter = new OpenLayers.LonLat(realX, realY);
		map.setCenter(requestCenter,map.getZoom());
		requestCenter = null;
   	},
   	
   
    calculateOverviewExtent: function()
	{
		// ------------------------------------------------------------
		// calculate the size in pixels of the overview map region.  we will 
		// only calculate from the x values as the region is assumed to be square
		// n.b. enhanced as now not square but rectangular 
		
		var ovImageDiv = OpenLayers.Util.getElement("ovmapimage");
		var ovImgOffsetLeft = ovImageDiv.offsetLeft;
		var ovImgOffsetTop = ovImageDiv.offsetTop;
				
		var overviewMapXExtent = this.ovMaxX - this.ovMinX;
    	var overviewMapYExtent = this.ovMaxY - this.ovMinY;
		var mapBounds = map.getExtent();
		
		var xExtentPerPixel = overviewMapXExtent / this.width;
		var yExtentPerPixel = overviewMapYExtent / this.height;
		
		//the top side length
		var mainMapXextent = mapBounds.right - mapBounds.left;
		var overviewMapPixels = ( mainMapXextent / xExtentPerPixel );		
		this.overviewTopSideLengthOriginal = Math.round( overviewMapPixels );
		
		//the left side length
		var mainMapYextent = mapBounds.top - mapBounds.bottom;
		var overviewLeftSideMapPixels = ( mainMapYextent / yExtentPerPixel );		
		this.overviewLeftSideLengthOriginal = Math.round( overviewLeftSideMapPixels );
		
		// ------------------------------------------------------------
		// find the main map minx on the overview map
		var extentInOnOverviewMap = mapBounds.left - this.ovMinX;
		
		//NB offsetleft ie bug so removed.
		
		//var overviewMapPixelsIn = (extentInOnOverviewMap / xExtentPerPixel) + ovImgOffsetLeft;
		var overviewMapPixelsIn = (extentInOnOverviewMap / xExtentPerPixel);
		this.overviewLeftOriginal = Math.round( overviewMapPixelsIn );	
		
		// ------------------------------------------------------------
		// find the main map maxy on the overview map
		var extentDownOnOverviewMap = this.ovMaxY - mapBounds.top;
		var overviewMapPixelsDown = (extentDownOnOverviewMap / yExtentPerPixel) + ovImgOffsetTop;
		
		this.overviewTopOriginal = Math.round( overviewMapPixelsDown );
		
	},
	
	redraw: function(evt) 
   	{
		this.calculateOverviewExtent();
       	this.drawOvMapDiv();
    },  

    CLASS_NAME: 'WiybyOverViewControl'
});

