/*
    Copyright (c) 2006, SpatialPoint, LLC.
    
    All rights reserved.
    
    http://www.spatialpoint.com
*/

var circleRadiusDisplay;

function SpatialPoint_ShapeInput(init)
{
    /* Private */
    
    // Owner of this instance.
    var owner = null;
    
    /* Public */
    
    // Constants.
    this.SHAPE_RECTANGLE = 0;
    this.SHAPE_CIRCLE = 1;

    // Parent of the shape instance.
    this.shapeParent = null;
    
    // Active shape.
    this.shapeElement = null;
    this.shape = null;
    
    // Active shape type.  
    this.shapeType = null;

    // The control ID events are allowed from.
    this.srcEventId = null;
    
	// Set if we're capturing mouse events. (Shape control is active.)
	this.mouseCapturing = false;
	
	// Anchor points for the rectangle being drawn.
    this.shapeAnchor = { x : 0, y : 0 };

    // Events to hook into.
    this.onStartShapeInput = null;
    this.onEndShapeInput = null;
    this.onShapeResize = null;
    
    if (init)
    {
        if (init.owner)
        {
            owner = init.owner;
        }

        if (init.shapeParent)
        {
            this.shapeParent = init.shapeParent;
        }
        
        if (init.srcEventId)
        {
            this.srcEventId = init.srcEventId;
        }
        
        if (init.onStartShapeInput)
        {
            this.onStartShapeInput = init.onStartShapeInput;
        }

        if (init.onEndShapeInput)
        {
            this.onEndShapeInput = init.onEndShapeInput;
        }

        if (init.onShapeResize)
        {
            this.onShapeResize = init.onShapeResize;
        }
    }
    
    this.setShapeType = function(shapeType)
    {
        switch (shapeType)
        {
            case this.SHAPE_RECTANGLE:
                this.createRectangle();
                break;
                
            case this.SHAPE_CIRCLE:
                this.createCircle();
                break;
                
            default:
                alert("Invalid Shape Type.  Valid values are: SHAPE_RECTANGLE, SHAPE_CIRCLE.");
                return;
        }
        
        this.shapeType = shapeType;
    }
    
    this.getOwner = function()
    {
        return owner;
    }
}

SpatialPoint_ShapeInput.prototype.createRectangle = function()
{
    var element = document.createElement("span");
    
    element.className = "ShapeInput_Rectangle";
    element.visibility = "hidden";
    
    this.shapeElement = this.shapeParent.appendChild(element);
    this.shape = this.shapeElement.style;
}

SpatialPoint_ShapeInput.prototype.setVisible = function(visible)
{
    if (visible)
    {
        this.shape.visiblility = "visible";
        
        this.shape.zIndex = 30;

        this.shape.left = this.shapeAnchor.x + "px";
        this.shape.top = this.shapeAnchor.y + "px";
        this.shape.width = 0 + "px";
        this.shape.height = 0 + "px";
    }
    else
    {
        this.shape.visiblility = "hidden";
        
        this.shape.zIndex = -10;

        this.shape.top = 1 + "px";
        this.shape.left = 1 + "px";
        this.shape.width = 0 + "px";
        this.shape.height = 0 + "px";
    }
}

SpatialPoint_ShapeInput.prototype.setMouseCapturing = function(active, event)
{
    if (active)
    {
	    if (this.onStartShapeInput)
	    {
	        this.onStartShapeInput(event);
	    }
	    
        this.shapeAnchor = this.getEventOffsetXYCoordinates(event);
    
        this.mouseCapturing = true;

        if (this.shapeType == this.SHAPE_RECTANGLE)
        {
            document.onmousemove = this.rectangleMouseMove;
        }
        else
        if (this.shapeType == this.SHAPE_CIRCLE)
        {
            document.onmousemove = this.circleMouseMove;

            //circleRadiusDisplay.style.visibility = "visible";
            //circleRadiusDisplay.innerText = "";
        }

        // "this" is an instance of ShapeInput.
        document.shapeInput = this;

        document.onmouseup = this.mouseUp;
    }
    else
    {
        if (this.onEndShapeInput)
        {
            this.onEndShapeInput(document.shapeInput);
        }

        document.shapeInput = null;
        document.onmousemove = null;
        document.onmouseup = null;
        
        this.mouseCapturing = false;

        //this.shapeParent.onmousemove = null;
        //this.shapeParent.onmouseup = null;
        
        //circleRadiusDisplay.style.visibility = "hidden";
        //circleRadiusDisplay.innerText = "";
    }

    this.setVisible(active);
    this.cancelEvent(event);
    return false;
}

SpatialPoint_ShapeInput.prototype.mouseDown = function(event)
{
    var e = event || window.event;
    
    var scrElement = e.target || e.srcElement;
    
    //if (scrElement.id == 'driveToLink')
    //{
    //    return;
    //}
    
    if (scrElement.tagName != 'INPUT')
    {
        return;
    }
    
    if ((e.button == 0) || (e.button == 1))
    {
        this.shapeInput.setMouseCapturing(true, e);
    }
    else
    {
        return false;
    }
}

/*
    Returns an XYCoordinates object with x and y properties set to the
    appropriate current offsetX and offsetY values, accounting for Firefox
    (and possibly other) browser differences.
*/
SpatialPoint_ShapeInput.prototype.getEventOffsetXYCoordinates = function(event)
{
    var e = event || window.event;
    
    var element = e.target;
    
    // Can we short-circuit this?
    if (!element)
    {
        // We're probably in IE.
        return { x : e.offsetX, y : e.offsetY };
    }
    
    var calculatedTotalOffsetLeft = 0;
    var calculatedTotalOffsetTop = 0;
    
    while (element.offsetParent)
    {
        calculatedTotalOffsetLeft += element.offsetLeft;
        calculatedTotalOffsetTop += element.offsetTop;
        
        element = element.offsetParent;
    }
    
    return { x : e.pageX - calculatedTotalOffsetLeft, y : e.pageY - calculatedTotalOffsetTop };
}

SpatialPoint_ShapeInput.prototype.rectangleMouseMove = function(event)
{
    var e = event || window.event;
    var srcElement = e.target || e.srcElement;
    
    if (!this.shapeInput.mouseCapturing)
    {
        return true;
    }

    if (!e.target && (srcElement.id != this.shapeInput.srcEventId)) // IE.
    {
        return true;
    }

    var coords = null;

    // Can we short-circuit this?
    if (!e.target)
    {
        // We're probably in IE.
        coords = { x : e.offsetX, y : e.offsetY };
    }
    else
    {
        var calculatedTotalOffsetLeft = 0;
        var calculatedTotalOffsetTop = 0;
        
        var element = this.shapeInput.shapeParent;
        
        while (element)
        {
            calculatedTotalOffsetLeft += element.offsetLeft;
            calculatedTotalOffsetTop += element.offsetTop;
            
            element = element.offsetParent;
        }
        
        coords = { x : e.pageX - calculatedTotalOffsetLeft, y : e.pageY - calculatedTotalOffsetTop };
    }
            
    var x = coords.x;
    var y = coords.y;

    // Normal start top,left
    if ((x > this.shapeInput.shapeAnchor.x) && (y > this.shapeInput.shapeAnchor.y))
    {
        this.shapeInput.shape.left = this.shapeInput.shapeAnchor.x;
        this.shapeInput.shape.top = this.shapeInput.shapeAnchor.y;
        this.shapeInput.shape.width = (x  - this.shapeInput.shapeAnchor.x) + "px";
        this.shapeInput.shape.height = (y - this.shapeInput.shapeAnchor.y) + "px";
    }
    else
    // Start:  bottom, right
    if ((x < this.shapeInput.shapeAnchor.x) && (y < this.shapeInput.shapeAnchor.y))
    {
        this.shapeInput.shape.left = x + "px";
        this.shapeInput.shape.top = y + "px";
        this.shapeInput.shape.width = (this.shapeInput.shapeAnchor.x - x) + "px";
        this.shapeInput.shape.height = (this.shapeInput.shapeAnchor.y - y) + "px";
    }
    else
    // Start:  bottom, left
    if ((x > this.shapeInput.shapeAnchor.x) && (y < this.shapeInput.shapeAnchor.y))
    {
        this.shapeInput.shape.left = this.shapeInput.shapeAnchor.x + "px";
        this.shapeInput.shape.top = y + "px";
        this.shapeInput.shape.width = (x - this.shapeInput.shapeAnchor.x) + "px";
        this.shapeInput.shape.height = (this.shapeInput.shapeAnchor.y - y) + "px";
    }
    else
    // Start:  top, right
    if ((x < this.shapeInput.shapeAnchor.x) && (y > this.shapeInput.shapeAnchor.y))
    {
        this.shapeInput.shape.left = x + "px";
        this.shapeInput.shape.top = this.shapeInput.shapeAnchor.y + "px";
        this.shapeInput.shape.width = (this.shapeInput.shapeAnchor.x - x) + "px";
        this.shapeInput.shape.height = (y - this.shapeInput.shapeAnchor.y) + "px";
    }
}

SpatialPoint_ShapeInput.prototype.circleMouseMove = function(event)
{
    var e = event || window.event;
    
    var scrElement = e.target || e.srcElement;
    
    if (!this.mouseCapturing || ((scrElement.id != "mapImage") && (scrElement.id != "shapeCircle")))
    {
        return true;
    }
        
    var x;
    
    if (e.x)
    {
        x = e.x;
    }
    else
        if (e.layerX)
        {
            x = e.layerX;
        }

    /* Worked in IE
    var radiusPixels = Math.abs(shapeAnchorX - eventObj.x);
    */
    var radiusPixels = Math.abs(this.shapeAnchor.x - x);
    
    //circleRadiusDisplay.innerHTML = getRadiusInMiles(radiusPixels).toFixed(2) + " miles";
    
    /* Worked in IE
    shape.pixelWidth = radiusPixels * 2;
    shape.pixelHeight = shape.pixelWidth;
    shape.pixelLeft = shapeAnchorX - radiusPixels;
    shape.pixelTop = shapeAnchorY - radiusPixels;
    */

    this.shape.left = this.shapeAnchor.x - radiusPixels;
    this.shape.top = this.shapeAnchor.y - radiusPixels;
    this.shape.height = this.shape.width = radiusPixels * 2;
}

SpatialPoint_ShapeInput.prototype.mouseUp = function(event)
{
    var e = event || window.event;
        
    this.shapeInput.setMouseCapturing(false, e);
}

SpatialPoint_ShapeInput.prototype.cancelEvent = function(event)
{
    var e = event || window.event;
    
    if (e.stopPropagation)
    {
        e.stopPropagation();
    }
    else
    {
        e.cancelBubble = true;
    }
}
