/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
 * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for th
 * full text of the license. */

/**
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Feature/Vector.js
 */

/**
 * Class: OpenLayers.Control.Measure
 * Allows for drawing of features for measurements.
 *
 * Inherits from:
 *  - <OpenLayers.Control>
 */
OpenLayers.Control.Measure = OpenLayers.Class(OpenLayers.Control, {

    /**
     * APIProperty: handlerOptions
     * {Object} Used to set non-default properties on the control's handler
     */
    handlerOptions: null,
    
    /**
     * APIProperty: onMeasure
     * {Function} After a geometry is drawn, onMeasure is called with three
     *     arguments: the geometry, its length, and its area.
     */
    onMeasure: function() {},
    
    /**
     * Property: callbacks
     * {Object} The functions that are sent to the handler for callback
     */
    callbacks: null,
    
    /**
     * Property: displayUnits
     * {String} Units for output.  Must be one of 'in', 'ft', 'mi', 'm', 'km',
     *     or 'dd'.  If null, displayUnits will be assumed to be the same as
     *     map units.
     */
    displayUnits: null,

    /**
     * Constructor: OpenLayers.Control.Measure
     * 
     * Parameters:
     * handler - {<OpenLayers.Handler>} 
     * options - {Object} 
     */
    initialize: function(handler, options) {
        OpenLayers.Control.prototype.initialize.apply(this, [options]);
        this.callbacks = OpenLayers.Util.extend(
            {done: this.measureGeometry, point: this.partialMeasure},
            this.callbacks
        );
        this.handler = new handler(this, this.callbacks, this.handlerOptions);
    },

    /**
     * Method: measureGeometry
     */
    measureGeometry: function(geometry) {
        var area = this.getArea(geometry);
        var length = this.getLength(geometry);
        this.onMeasure(geometry, length, area, this.displayUnits);
    },
    
    /**
     * Method: getArea
     */
    getArea: function(geometry) {
        var area = geometry.getArea();
        var inPerDisplayUnit = OpenLayers.INCHES_PER_UNIT[this.displayUnits];
        if(inPerDisplayUnit) {
            var inPerMapUnit = OpenLayers.INCHES_PER_UNIT[this.map.units];
            area *= Math.pow((inPerMapUnit / inPerDisplayUnit), 2);
        }
        return area;
    },
    
    /**
     * Method: getLength
     */
    getLength: function(geometry) {
        var length = geometry.getLength();
        var inPerDisplayUnit = OpenLayers.INCHES_PER_UNIT[this.displayUnits];
        if(inPerDisplayUnit) {
            var inPerMapUnit = OpenLayers.INCHES_PER_UNIT[this.map.units];
            length *= (inPerMapUnit / inPerDisplayUnit);
        }
        return length;
    },

    CLASS_NAME: "OpenLayers.Control.Measure"
});
