﻿function AGMouseManager()
{
}

AGMouseManager.doubleClickCount = 0;
AGMouseManager.mouseDownEvent = null;
AGMouseManager.iMouseMoveCount = 0;

//over
var oOverlayBelowMouse = null;

AGMouseManager.getMouseCoords = function(e)
{
    e = e || window.event;
    if(e.pageX || e.pageY)
    {      
        if(e.type == "DOMMouseScroll")
        {   
            if(AGBrowser.BROWSER=="Firefox" && AGBrowser.VERSION < 3)
                return new AGPoint(e.pageX/15, e.pageY/15);
            else
                return new AGPoint(e.pageX, e.pageY);
        }
        else
            return new AGPoint(e.pageX, e.pageY);
    }
    else if (e.clientX || e.clientY)  
    {
        var posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
        var posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
        return new AGPoint(posx , posy);
    }
    return null;
};

AGMouseManager.isRightButton = function(e) 
{
    var rightclick = false;
    e = e || window.event;
    
    if (e.which) 
        rightclick = (e.which == 3);
    else if (e.button) 
        rightclick = (e.button == 2);
    
    return rightclick;
};

AGMouseManager.handleRightButtonClick = function() 
{
    var oAGMap = AGMouseManager.mouseDownEvent.data;
    if(AGMouseManager.doubleClickCount >= 2 )
    {   
        if(oAGMap.zoomOnDblClickEnabled()) 
            oAGMap.zoomOut();
    }  
    else if( AGMouseManager.doubleClickCount % 2 == 1 )
    {
        if(oAGMap.contextMenuEnabled())
        {
            var divContainer = oAGMap.getContainer();
            var oPointForContextMenu = AGMouseManager.getMouseOffset(AGMouseManager.mouseDownEvent, divContainer);
            AGContextMenuMouseManager.showContextMenu(oAGMap,oPointForContextMenu);
        }
    }

    AGMouseManager.doubleClickCount = 0;
    return false;
};

AGMouseManager.getMouseOffset = function(e, oHtmlBase)
{
	e = e || window.event;

	var docPos    = AGMouseManager.getPosition(oHtmlBase);
	var mousePos  = AGMouseManager.getMouseCoords(e);

    return new AGPoint((mousePos.x - docPos.x),(mousePos.y - docPos.y));
};

AGMouseManager.getPosition = function(e)
{
	var iLeft = 0;
	var iTop  = 0;

	while (e.offsetParent)
	{
		iLeft += e.offsetLeft;
		iTop  += e.offsetTop;
		e = e.offsetParent;
	}

	iLeft += e.offsetLeft;
	iTop  += e.offsetTop;
	
	return new AGPoint(iLeft , iTop);
};

AGMouseManager.doubleClickHandler = function(e)
{
    var oAGMap = e.data;
    
    // hide context menu
    if(oAGMap.contextMenuEnabled())
        AGContextMenuMouseManager.hideContextMenu(oAGMap);
    
    var divMapContainer = oAGMap.getPane(AGPanes.MAP_CONTAINER);
    var oPointMapContainerClickedOn = AGMouseManager.getMouseOffset(e, divMapContainer);
    var oClickedOverlay = oAGMap.getClickableOverlayAtPosition(oPointMapContainerClickedOn);
    var oClickedLatLng = oAGMap.getCoordFromMap(oPointMapContainerClickedOn);
    
    // fire dblclick event on map
    AGEvent.trigger(oAGMap, "ondblclick", oClickedOverlay, oClickedLatLng);
    
    if(oClickedOverlay != null && oClickedOverlay instanceof AGMarker)
    {
        // fire click event of that overlay
        AGEvent.trigger(oClickedOverlay, "ondblclick", oClickedLatLng);
        return false;
    }
    
    if(oAGMap.zoomOnDblClickEnabled())
    {   
        var iCurrentZoomLevel = oAGMap.getZoomLevel();
        if(iCurrentZoomLevel < oAGMap.getMaxZoomLevel())
        {
            var iNextZoomLevel = iCurrentZoomLevel+1;
            var base = oAGMap.getContainer();
            var oPointClicked = AGMouseManager.getMouseOffset(e, base);
            var oLatLngClicked = oAGMap.getCoordFromVisibleArea(oPointClicked);
            oAGMap.centreAndScale(oLatLngClicked,  iNextZoomLevel);
            
        }
    }
    
    return false;
};

AGMouseManager.bDrag = false;
AGMouseManager.oPointLastMousePosition = null;

AGMouseManager.oDragZoomAreaMarker = null;
AGMouseManager.oPointDragStart = null;  // point w.r.to map container
AGMouseManager.oPointDragStop = null;   // point w.r.to map container

AGMouseManager.mouseDownHandler = function(e)
{
    var oAGMap = e.data;
    oAGMap.disablePanAnimation();  // disable pan animation for any kind of mouse operation

    AGMouseManager.mouseDownEvent = e;
   
    if(AGMouseManager.isRightButton(e))
    {
        AGMouseManager.doubleClickCount ++;
        setTimeout("AGMouseManager.handleRightButtonClick();",250);
        return false;
    }
    
    
    // if left click, hide context menu
    if(oAGMap.contextMenuEnabled())
        AGContextMenuMouseManager.hideContextMenu(oAGMap);
    
    // overlay
    var divMapContainer = oAGMap.getPane(AGPanes.MAP_CONTAINER);
    var oPointMapContainerClickedOn = AGMouseManager.getMouseOffset(e, divMapContainer);
    var oClickedOverlay = oAGMap.getClickableOverlayAtPosition(oPointMapContainerClickedOn);
    if(oClickedOverlay != null && oClickedOverlay instanceof AGMarker)
    {
        // fire click event of that overlay
        var oClickedLatLng = oAGMap.getCoordFromMap(oPointMapContainerClickedOn);
        AGEvent.trigger(oClickedOverlay, "onmousedown", oClickedLatLng);
        return false;
    }
    
    // Drag zoom
    if(oAGMap.dragZoomEnabled())
    {
        AGMouseManager.bDrag = true;
        var divContainer = oAGMap.getContainer();
        AGMouseManager.oPointDragStart = AGMouseManager.getMouseOffset(e, divContainer);
        AGMouseManager.oDragZoomAreaMarker = oAGMap.getDragZoomArea();
        return false;
    }
    
    // normal drag
    if(oAGMap.dragPanEnabled())
    {
        AGMouseManager.bDrag = true;
        AGMouseManager.oPointLastMousePosition = AGMouseManager.getMouseCoords(e);
        //AGEvent.trigger(oAGMap, "ondragstart");
        AGMouseManager.iMouseMoveCount = 0;
    }
    
    return false;
};

AGMouseManager.mouseMoveHandler = function(e)
{   
    var oAGMap = e.data;
    
    // overlay
    var divMapContainer = oAGMap.getPane(AGPanes.MAP_CONTAINER);
    var oPointMapContainerClickedOn = AGMouseManager.getMouseOffset(e, divMapContainer);
    var oClickedOverlay = oAGMap.getClickableOverlayAtPosition(oPointMapContainerClickedOn);
    var oClickedLatLng = oAGMap.getCoordFromMap(oPointMapContainerClickedOn);
    
    // fire mouse over and mouse out
    if(oClickedOverlay != null && oOverlayBelowMouse == null)
    {
        AGEvent.trigger(oClickedOverlay, "onmouseover", oClickedLatLng);
    }
    else if (oOverlayBelowMouse != null && oClickedOverlay != oOverlayBelowMouse)
    {
        AGEvent.trigger(oOverlayBelowMouse, "onmouseout", oClickedLatLng);
    }    
    oOverlayBelowMouse = oClickedOverlay;
    
    //fire mouse move on map
    AGEvent.trigger(oAGMap, "onmousemove", oClickedLatLng);
    
    if(AGMouseManager.bDrag)
    {   
        // drag zoom
        if(oAGMap.dragZoomEnabled())
        {   
            var divContainer = oAGMap.getContainer();
            var oPointDragCurrent = AGMouseManager.getMouseOffset(e, divContainer);
            
            
            var iWidth = Math.abs(AGMouseManager.oPointDragStart.x - oPointDragCurrent.x);
            var iHeight = Math.abs(AGMouseManager.oPointDragStart.y - oPointDragCurrent.y);
            
            var iLeft = (AGMouseManager.oPointDragStart.x <= oPointDragCurrent.x) ? AGMouseManager.oPointDragStart.x : oPointDragCurrent.x;
            var iTop = (AGMouseManager.oPointDragStart.y <= oPointDragCurrent.y) ? AGMouseManager.oPointDragStart.y : oPointDragCurrent.y;
            var oLatLngTopLeft = oAGMap.getCoordFromVisibleArea(new AGPoint(iLeft, iTop));
            AGMouseManager.oDragZoomAreaMarker.reset(oLatLngTopLeft, new AGSize(iWidth, iHeight));
            
            return false;
        }
        
        // normal drag
        var oPointCurrentMousePos = AGMouseManager.getMouseCoords(e);
        var panX = oPointCurrentMousePos.x - AGMouseManager.oPointLastMousePosition.x;
        var panY = oPointCurrentMousePos.y - AGMouseManager.oPointLastMousePosition.y;
        oAGMap.moveMapContainer(new AGPoint(panX,panY));
        AGMouseManager.oPointLastMousePosition = oPointCurrentMousePos;
        
        AGMouseManager.iMouseMoveCount ++;
        if(AGMouseManager.iMouseMoveCount == 1) // first time
            AGEvent.trigger(oAGMap, "ondragstart");
        
        AGEvent.trigger(oAGMap, "ondrag");
        return false;
    }
    
    // fire mouse move on overlay, Clicked overlay has been identified before
    //if(oClickedOverlay != null)
    if(oClickedOverlay != null && oClickedOverlay instanceof AGMarker )
    {
        // fire click event of that overlay
        AGEvent.trigger(oClickedOverlay, "onmousemove", oClickedLatLng);
        return false;
    }
    
    return false;
};

AGMouseManager.mouseUpHandler = function(e, bCalledFromMouseOut)
{   
    if(typeof bCalledFromMouseOut != "boolean")
        bCalledFromMouseOut = false;
    
    var oAGMap = e.data;

    if(AGMouseManager.bDrag)
    {   
        AGMouseManager.bDrag = false;
        
        // ondrag zoom
        if(oAGMap.dragZoomEnabled())
        {
            AGMouseManager.oDragZoomAreaMarker.hide();
            
            if(bCalledFromMouseOut) // if called from mouse out function, don't zoom out
                return;
            
            var divContainer = oAGMap.getContainer();
            AGMouseManager.oPointDragStop = AGMouseManager.getMouseOffset(e, divContainer);
            
            // don't zoom for just a click or no range selection
            if(AGMouseManager.oPointDragStart.equals(AGMouseManager.oPointDragStop))
                return false;
            
            // find latlng of both points and construct bounds
            var oCoordStart = oAGMap.getCoordFromVisibleArea(AGMouseManager.oPointDragStart);
            var oCoordStop = oAGMap.getCoordFromVisibleArea(AGMouseManager.oPointDragStop);
            var oLatLngBoundsSelected = new AGBoundingBox(oCoordStart, oCoordStop);
            var iZoomLevel = oAGMap.getBoundingBoxZoomLevel(oLatLngBoundsSelected);
            
            // // sometimes map gets zoomed out, which should not happen. so by force it is restricted.
            iZoomLevel = (iZoomLevel > oAGMap.getZoomLevel() ) ? iZoomLevel : oAGMap.getZoomLevel();
            
            // zoom to the bounds' center and zoomLevel
            oAGMap.centreAndScale(oLatLngBoundsSelected.getCentre(), iZoomLevel);
            return false;
            
        }
        
        // normal drag
        var oPointCurrentMousePos = AGMouseManager.getMouseCoords(e);
        var panX = oPointCurrentMousePos.x - AGMouseManager.oPointLastMousePosition.x;
        var panY = oPointCurrentMousePos.y - AGMouseManager.oPointLastMousePosition.y;
        
        oAGMap.moveMapContainer(new AGPoint(panX,panY));
        
        // stationary
        oAGMap.setPanStatus(AGPanStatus.DRAG);
        oAGMap.handleOverlays(AGOperations.PAN);
        oAGMap.handleControls(AGOperations.PAN);
        oAGMap.setPanStatus(AGPanStatus.DEFAULT);
        
        if(AGMouseManager.iMouseMoveCount > 0)
        {
            AGMouseManager.iMouseMoveCount = 0;
            AGEvent.trigger(oAGMap, "ondragend");
        }
        return false;
    }
    
    // overlay
    var divMapContainer = oAGMap.getPane(AGPanes.MAP_CONTAINER);
    var oPointMapContainerClickedOn = AGMouseManager.getMouseOffset(e, divMapContainer);
    var oClickedOverlay = oAGMap.getClickableOverlayAtPosition(oPointMapContainerClickedOn);
    //if(oClickedOverlay != null)
    if(oClickedOverlay != null && oClickedOverlay instanceof AGMarker)
    {
        // fire click event of that overlay
        var oClickedLatLng = oAGMap.getCoordFromMap(oPointMapContainerClickedOn);
        AGEvent.trigger(oClickedOverlay, "onmouseup", oClickedLatLng);
        return false;
    }
    
    return false;
};

AGMouseManager.mouseOutHandler = function(e)
{
    var oAGMap = e.data;
    var divMapContainer = oAGMap.getPane(AGPanes.MAP_CONTAINER);
    var oPointMapContainerClickedOn = AGMouseManager.getMouseOffset(e, divMapContainer);
    var oClickedLatLng = oAGMap.getCoordFromMap(oPointMapContainerClickedOn);
    
    // fire mouseout on overlay
    if(oOverlayBelowMouse != null)
    {
        AGEvent.trigger(oOverlayBelowMouse, "onmouseout", oClickedLatLng);
        oOverlayBelowMouse = null;
    }
    
    // fire mouseout event on map
    AGEvent.trigger(oAGMap, "onmouseout", oClickedLatLng);
    
    AGMouseManager.mouseUpHandler(e,true);
    return false;
};

AGMouseManager.mouseScrollHandler = function(e)
{
    var iScrollDirection = 0;
    var oAGMap = e.data;
    
    // hide context menu
    if(oAGMap.contextMenuEnabled())
        AGContextMenuMouseManager.hideContextMenu(oAGMap);
    
    if(oAGMap.mouseWheelZoomEnabled())
    {
        if (e.wheelDelta)
        {
            iScrollDirection = e.wheelDelta/120;
            var bOperaOlderVersion = AGBrowser.BROWSER=="Opera" && AGBrowser.VERSION <= 9.02;
            if (bOperaOlderVersion)
                iScrollDirection = -iScrollDirection;
        }
        else if (e.detail) 
            iScrollDirection = -e.detail/3;
     
        var iCurrentZoomLevel = oAGMap.getZoomLevel(); 
     
        var divContainer = oAGMap.getContainer();
        
        //var oPointToBeScrolled = AGMouseManager.getMouseOffset(e, divContainer);
        var oPointToBeScrolled;
        if(AGBrowser.BROWSER=="Firefox" && AGBrowser.VERSION < 3)
            oPointToBeScrolled = AGMouseManager.getMouseCoords(e);
        else
            oPointToBeScrolled = AGMouseManager.getMouseOffset(e, divContainer);
            
        var oLatLngToBeScrolled = oAGMap.getCoordFromVisibleArea(oPointToBeScrolled);
        
        var oAGSizeCurrentMapSize = oAGMap.getSize();
        var iPointShiftX = parseInt( oPointToBeScrolled.x - oAGSizeCurrentMapSize.width/2);
        var iPointShiftY = parseInt( oPointToBeScrolled.y - oAGSizeCurrentMapSize.height/2);
        
        var oPointShift = new AGPoint(iPointShiftX,iPointShiftY);
     
        if(iScrollDirection < 0)
        {
            if(iCurrentZoomLevel > oAGMap.getMinZoomLevel())
            {
                var oLatLngBoundsCurrent =  AGCoordMapper.getBoundingBoxForZoomAtPoint(oLatLngToBeScrolled, iCurrentZoomLevel-1, oAGSizeCurrentMapSize, oPointShift);
                AGZoomAnimation.zoomOnRedDisplayAnimation(oAGMap,oPointToBeScrolled,0);//0 for zoom out
                oAGMap.centreAndScale(oLatLngBoundsCurrent.getCentre(),iCurrentZoomLevel-1);
                return false;

            }
            else
            {
                return false;
            }
        }
        else
        {
            if(iCurrentZoomLevel < oAGMap.getMaxZoomLevel())
            {
                var oLatLngBoundsCurrent =  AGCoordMapper.getBoundingBoxForZoomAtPoint(oLatLngToBeScrolled, iCurrentZoomLevel+1, oAGSizeCurrentMapSize, oPointShift);
                AGZoomAnimation.zoomOnRedDisplayAnimation(oAGMap,oPointToBeScrolled,1);//1 for zoom in
                oAGMap.centreAndScale(oLatLngBoundsCurrent.getCentre(),iCurrentZoomLevel+1);        
                return false;
            }
            else
            {
                return false;
            }
        }
    }
    else
	{
		return false;
	}
	
	return false;
};

AGMouseManager.clickHandler = function(e)
{
    var oAGMap = e.data;
    
    // handle right button click and show context menu
    if(AGMouseManager.isRightButton(e) && oAGMap.contextMenuEnabled())
    {
        var divContainer = oAGMap.getContainer();
        var oPointForContextMenu = AGMouseManager.getMouseOffset(e, divContainer);
        AGContextMenuMouseManager.showContextMenu(oAGMap,oPointForContextMenu);
        return false;
    }
    
    // if left click, hide context menu
    if(oAGMap.contextMenuEnabled())
        AGContextMenuMouseManager.hideContextMenu(oAGMap);
    
    // overlay click
    var divMapContainer = oAGMap.getPane(AGPanes.MAP_CONTAINER);
    var oPointMapContainerClickedOn = AGMouseManager.getMouseOffset(e, divMapContainer);
    var oClickedOverlay = oAGMap.getClickableOverlayAtPosition(oPointMapContainerClickedOn);
    var oClickedLatLng = oAGMap.getCoordFromMap(oPointMapContainerClickedOn);
    
    // fire click event of map
    AGEvent.trigger(oAGMap, "onclick", oClickedOverlay, oClickedLatLng);
    
    if(oClickedOverlay != null)
    {
        // fire click event of that overlay
        
        AGEvent.trigger(oClickedOverlay, "onclick", oClickedLatLng);
        return false;
    }
};

AGMouseManager.mouseOverHandler = function(e)
{
    var oAGMap = e.data;
    var divMapContainer = oAGMap.getPane(AGPanes.MAP_CONTAINER);
    var oPointMapContainerClickedOn = AGMouseManager.getMouseOffset(e, divMapContainer);
    var oClickedLatLng = oAGMap.getCoordFromMap(oPointMapContainerClickedOn);
    var oClickedOverlay = oAGMap.getClickableOverlayAtPosition(oPointMapContainerClickedOn);
  
    // mouse over and out  
    if(oClickedOverlay != null && oOverlayBelowMouse == null)
    {
        AGEvent.trigger(oClickedOverlay, "onmouseover", oClickedLatLng);
    }
    else if (oOverlayBelowMouse != null && oClickedOverlay != oOverlayBelowMouse)
    {
        AGEvent.trigger(oOverlayBelowMouse, "onmouseout", oClickedLatLng);
    }
    oOverlayBelowMouse = oClickedOverlay;
    
    // fire mouseout event on map
    AGEvent.trigger(oAGMap, "onmouseover", oClickedLatLng);
    return false;
};