/**
 *
 * @project     fcmq2009
 * @purpose     DistanceCalculator simple class for selected overlays.
 * @author      Alexandre Dubé - Mapgears inc. (adube@mapgears.com)
 * @copyright
 * <b>Copyright (c) 2009 Mapgears Inc.</b>
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/**
 * Class: DistanceCalculator
 * The class that calculates distances from selected tempOverlays.
 */
function DistanceCalculator(map, main, options) {
    /**
     * Property: bounds
     * {<OpenLayers.Bounds>} The current data bounds
     */

    this.kmValue = null;
    this.milesValue = null;
    this.lengthProperty = null;
    this.lengthUnit = null;
    this.lengthPrecision = null;

    OpenLayers.Util.extend(this, options);

    this.kmDOM = document.getElementById(this.kmValue);
    this.milesDOM = document.getElementById(this.milesValue);
    this.unit = OpenLayers.INCHES_PER_UNIT[this.lengthUnit];

    this.map = map;
    this.main = main;

    GEvent.addListener(this, "alloverlaysunselected",
                       this.onAllTempOverlaysUnselect);
};

/**
 * Method: onTempOverlaySelect
 * Called when a tempOverlay is selected.  Get its lenght and add it to both
 *     'kilometers' and 'miles' totals.
 */
DistanceCalculator.prototype.onTempOverlaySelect = function(
    oOverlay, oDistCalc) {
    var nPrec = oDistCalc.lengthPrecision;
    var fCurrentTotal = oDistCalc.getCurrentTotal();
    var fOverlayLength = oDistCalc.getOverlayLength(oOverlay);

    // Total in this.unit
    var fNewTotal = fCurrentTotal + fOverlayLength;

    // Total in Kilometers
    var fTotalKM = oDistCalc.getKilometers(fNewTotal);
    oDistCalc.kmDOM.innerHTML = "";
    oDistCalc.kmDOM.innerHTML = fTotalKM;

    // Total in Miles
    var fTotalMiles = oDistCalc.getMiles(fNewTotal);
    oDistCalc.milesDOM.innerHTML = "";
    oDistCalc.milesDOM.innerHTML = fTotalMiles;
};

/**
 * Method: onTempOverlayUnselect
 * Called when a tempOverlay is unselected.  Get its lenght and remove it from
 *      both 'kilometers' and 'miles' totals.
 */
DistanceCalculator.prototype.onTempOverlayUnselect = function(
    oOverlay, oDistCalc) {
    var nPrec = oDistCalc.lengthPrecision;
    var fCurrentTotal = oDistCalc.getCurrentTotal();
    var fOverlayLength = oDistCalc.getOverlayLength(oOverlay);

    // Total in this.unit
    var fNewTotal = fCurrentTotal - fOverlayLength;

    // Total in Kilometers
    var fTotalKM = oDistCalc.getKilometers(fNewTotal);
    oDistCalc.kmDOM.innerHTML = "";
    oDistCalc.kmDOM.innerHTML = fTotalKM;

    // Total in Miles
    var fTotalMiles = oDistCalc.getMiles(fNewTotal);
    oDistCalc.milesDOM.innerHTML = "";
    oDistCalc.milesDOM.innerHTML = fTotalMiles;
};

/**
 * Method: onAllTempOverlaysUnselect
 * Called when all tempOverlays are unselected.  Reset both 'kilometers' and
 *     'miles' totals to 0.
 */
DistanceCalculator.prototype.onAllTempOverlaysUnselect = function() {
    this.kmDOM.innerHTML = "0";
    this.milesDOM.innerHTML = "0";
};

/**
 * Method: getOverlayLength
 * Returns the length property value of a given overlay in a specific precision.
 *     The overlay must have a 'length' property.  The name of the property is
 *     configurable in options.js.
 *
 * Parameters:
 * oOverlay - {<GOverlay>} The overlay the get the length property from.
 *
 * Returns:
 * {float} The length value of the overlay 'length' property.
 */
DistanceCalculator.prototype.getOverlayLength = function(oOverlay) {
    var nPrec = this.lengthPrecision;
    var fOverlayLength = oOverlay.properties[this.lengthProperty];
    fOverlayLength = OpenLayers.Util.toFixedFloat(fOverlayLength, nPrec);

    return fOverlayLength;
};

/**
 * Method: getCurrentTotal
 * Look at current KM total value, convert it to this.unit and return it as
 * float.
 *
 * Returns:
 * {float} The current length value in this.unit.
 */
DistanceCalculator.prototype.getCurrentTotal = function() {
    var nPrec = this.lengthPrecision;
    var fTotal = OpenLayers.Util.toFixedFloat(this.kmDOM.innerHTML, nPrec);
    var fKMUnitValue = OpenLayers.INCHES_PER_UNIT['Kilometer'];
    fTotal = fTotal / this.unit * fKMUnitValue;
    
    fTotal = OpenLayers.Util.toFixedFloat(fTotal, nPrec);

    return fTotal;
};

/**
 * Method: getKilometers
 * Return given float length value in kilometers.
 *
 * Parameters:
 * fLength - {float} A length value.
 *
 * Returns:
 * {float} The length value in kilometers.
 */
DistanceCalculator.prototype.getKilometers = function(fLength) {
    var nPrec = this.lengthPrecision;
    var fKMUnitValue = OpenLayers.INCHES_PER_UNIT['Kilometer'];
    var fKilometers = fLength * this.unit / fKMUnitValue;
    fKilometers = OpenLayers.Util.toFixedFloat(fKilometers, nPrec);

    return fKilometers;
};

/**
 * Method: getMiles
 * Return given float length value in miles.
 *
 * Parameters:
 * fLength - {float} A length value.
 *
 * Returns:
 * {float} The length value in miles.
 */
DistanceCalculator.prototype.getMiles = function(fLength) {
    var nPrec = this.lengthPrecision;
    var fMilesUnitValue = OpenLayers.INCHES_PER_UNIT['Mile'];
    var fMiles = fLength * this.unit / fMilesUnitValue;
    fMiles = OpenLayers.Util.toFixedFloat(fMiles, nPrec);

    return fMiles;
};

