// $Id: Ruler.Control.js,v 1.1.2.4 2008/06/22 19:19:18 openwereld Exp $

OpenLayers.Control.Ruler = 
  OpenLayers.Class(OpenLayers.Control.DrawFeature, {
    
    /**
     * Div for output of measure length.
     */
    outputDiv: null,
    
    /**
     * Style to draw ruler in.
     */
    rulerStyleMap: null,
    
    /**
     * Constructor: OpenLayers.Control.LayerSwitcher
     * 
     * Parameters:
     * options - {Object}
     */
    initialize: function(options) {
        // inherit
        if (!options) {
          options = {};
        }
        options.type = OpenLayers.Control.TYPE_TOGGLE;
        options.displayClass = 'olControlRuler';
        options.eventListeners = {'activate': this.trigger
          , 'deactivate': this.trigger
          , 'beforefeatureadded': this.beforeFeatureAdded
          //, 'featureadded': this.featureAdded
        };
        
        this.outputDiv = document.getElementById(options.div);
        
        this.rulerStyleMap = new OpenLayers.StyleMap({strokeWidth: 2, strokeColor: '#EE9900'});
        
        // set non-default properties on the control's handler
        options.handlerOptions = {styleMap: this.rulerStyleMap};
        
        OpenLayers.Control.DrawFeature.prototype.initialize.apply(this, [null, OpenLayers.Handler.Path, options]);
        // own construction
    },

    /**
     * APIMethod: destroy 
     */    
    destroy: function() {
        // own destruction
        
        // inherit
        OpenLayers.Control.DrawFeature.prototype.destroy.apply(this, arguments);
    },
    
    /**
     * Method: draw
     * Called when the control is added to the map.
     */
    draw: function() {
        OpenLayers.Control.DrawFeature.prototype.draw.apply(this, arguments);
        
        // add drawing layer?
        this.layer = new OpenLayers.Layer.Vector('_Ruler_', {'displayInLayerSwitcher': false, 'visibility': false, 'styleMap': this.rulerStyleMap});
        this.map.addLayer(this.layer);
    },
    
    /**
     * Method: trigger
     * Called by a control panel when the button is clicked.
     */
    trigger: function() {
        if (this.active) {
            this.layer.setVisibility(true);
            this.map.events.register('mousemove', this, this.redraw);
        }
        else {
            this.map.events.unregister('mousemove', this, this.redraw);
            this.layer.setVisibility(false);
            this.layer.destroyFeatures();
            this.outputDiv.innerHTML = '';
        }
    },
    
    redraw: function(evt) {
        var dist = this.getDistance();
        if (dist) {
            this.outputDiv.innerHTML = Drupal.t('Distance: ') + dist;
        }
    },
    
    featureAdded: function(feature) {
        // something to do after feature is added?
    },
    
    beforeFeatureAdded: function(feature) {
        this.layer.destroyFeatures();
    },
    
    getDistance: function(evt) {
        var dist = 0;
        if (this.handler.line) {
            if (this.layer.features.length > 0) {
                this.layer.destroyFeatures();
            }
            dist = this.handler.line.geometry.getLength();
            return this.distanceToString(dist);
        }
        return null;
    },
    
    distanceToString: function(totalDistance) {
        if (this.layer.units == 'degrees') {
            //totalDistance *= 6372.797; // average earth radius
            return this.round_sig(totalDistance, 3) + ' degrees';
        }
        var suffix = " m";
        if (totalDistance > 1000) {
            suffix = " km";
            totalDistance /= 1000;
        }
        return this.round_sig(totalDistance, 4) + suffix;
    },
    
    /**
     * Round value to a number of significant digits.
     */
    round_sig: function(val, sig) {
      if (val == 0) {
        return 0;
      }
      var sign = val > 0 ? 1 : -1;
      val = Math.abs(val);
      var exp = Math.floor(Math.log(val)/Math.LN10 + 1);
      var powers = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000];
      var pow10sig = powers[sig];//Math.pow(10, sig);
      var pow10exp = powers[exp];//Math.pow(10, exp);
      //var pow10exp_sig = (exp > sig) ? powers[exp - sig] : 1/powers[sig - exp];
      var significand = val / pow10exp;
      val = Math.round(significand * pow10sig)*pow10exp/pow10sig;
      return sign * val;
    },

    CLASSNAME: "OpenLayers.Control.Ruler"
});

