o: ActiveSupport::Cache::Entry	:@compressedF:@expires_in0:@created_atf1361185922.143122:@value"c[{I"
class:EFI"ProcessedAsset;�FI"logical_path;�FI",DynamicScene/DynamicPositionProperty.js;�TI"
pathname;�FI"d/Users/bwrona/www/engines/cesium/app/assets/javascripts/DynamicScene/DynamicPositionProperty.js;�TI"content_type;�FI"application/javascript;�FI"
mtime;�FI"2013-02-11T17:47:50+01:00;�FI"length;�FiXI"digest;�F"%53703584c654bd484faaa9e0e60b5032I"source;�FI"X/*global define*/

define([
        '../Core/DeveloperError',
        '../Core/Ellipsoid',
        '../Core/JulianDate',
        '../Core/TimeInterval',
        '../Core/TimeIntervalCollection',
        '../Core/Iso8601',
        '../Core/Cartesian3',
        '../Core/Cartographic',
        '../Core/Matrix3',
        '../Core/ReferenceFrame',
        '../Core/Transforms',
        './CzmlCartesian3',
        './CzmlCartographic',
        './DynamicProperty'
    ], function(
        DeveloperError,
        Ellipsoid,
        JulianDate,
        TimeInterval,
        TimeIntervalCollection,
        Iso8601,
        Cartesian3,
        Cartographic,
        Matrix3,
        ReferenceFrame,
        Transforms,
        CzmlCartesian3,
        CzmlCartographic,
        DynamicProperty) {
    "use strict";

    var scratchMatrix3 = new Matrix3();
    var wgs84 = Ellipsoid.WGS84;
    var potentialTypes = [CzmlCartesian3, CzmlCartographic];

    /**
     * A dynamic property which stores both Cartesian and Cartographic data
     * and can convert and return the desired type of data for a desired time.
     * Rather than creating instances of this object directly, it's typically
     * created and managed via loading CZML data into a DynamicObjectCollection.
     * Instances of this type are exposed via DynamicObject and it's sub-objects
     * and are responsible for interpreting and interpolating the data for visualization.
     *
     * @alias DynamicPositionProperty
     * @constructor
     *
     * @see DynamicObject
     * @see DynamicProperty
     * @see ReferenceProperty
     * @see DynamicMaterialProperty
     * @see DynamicDirectionsProperty
     * @see DynamicVertexPositionsProperty
     */
    var DynamicPositionProperty = function() {
        this._dynamicProperties = [];
        this._propertyIntervals = new TimeIntervalCollection();
        this._cachedTime = undefined;
        this._cachedInterval = undefined;
    };

    /**
     * Processes the provided CZML interval or intervals into this property.
     *
     * @memberof DynamicPositionProperty
     *
     * @param {Object} czmlIntervals The CZML data to process.
     * @param {TimeInterval} [constrainedInterval] Constrains the processing so that any times outside of this interval are ignored.
     */
    DynamicPositionProperty.prototype.processCzmlIntervals = function(czmlIntervals, constrainedInterval) {
        if (Array.isArray(czmlIntervals)) {
            for ( var i = 0, len = czmlIntervals.length; i < len; i++) {
                this._addCzmlInterval(czmlIntervals[i], constrainedInterval);
            }
        } else {
            this._addCzmlInterval(czmlIntervals, constrainedInterval);
        }
    };

    /**
     * Retrieves the value of the object at the supplied time as a Cartographic.
     * @memberof DynamicPositionProperty
     *
     * @param {JulianDate} time The time for which to retrieve the value.
     * @param {Cartographic} [result] The object to store the result onto, if undefined a new instance will be created.
     * @returns The modified result property, or a new instance if result was undefined.
     */
    DynamicPositionProperty.prototype.getValueCartographic = function(time, result) {
        if (typeof time === 'undefined') {
            throw new DeveloperError('time is required.');
        }

        var interval = this._cachedInterval;
        if (this._cachedTime !== time) {
            this._cachedTime = time;
            if (typeof interval === 'undefined' || !interval.contains(time)) {
                interval = this._propertyIntervals.findIntervalContainingDate(time);
                this._cachedInterval = interval;
            }
        }

        if (typeof interval === 'undefined') {
            return undefined;
        }
        var property = interval.data;
        var valueType = property.valueType;
        if (valueType === CzmlCartographic) {
            return property.getValue(time, result);
        }
        result = interval.cachedValue = property.getValue(time, interval.cachedValue);
        if (typeof result !== 'undefined') {
            if (interval.referenceFrame === ReferenceFrame.INERTIAL) {
                var icrfToFixed = Transforms.computeIcrfToFixedMatrix(time, scratchMatrix3);
                if (typeof icrfToFixed === 'undefined') {
                    return undefined;
                }
                result = icrfToFixed.multiplyByVector(result, result);
            }
            result = wgs84.cartesianToCartographic(result);
        }
        return result;
    };

    /**
     * Retrieves the value of the object at the supplied time as a Cartesian3.
     * @memberof DynamicPositionProperty
     *
     * @param {JulianDate} time The time for which to retrieve the value.
     * @param {Cartesian3} [result] The object to store the result onto, if undefined a new instance will be created.
     * @returns The modified result property, or a new instance if result was undefined.
     */
    DynamicPositionProperty.prototype.getValueCartesian = function(time, result) {
        if (typeof time === 'undefined') {
            throw new DeveloperError('time is required.');
        }

        var interval = this._cachedInterval;
        if (this._cachedTime !== time) {
            this._cachedTime = time;
            if (typeof interval === 'undefined' || !interval.contains(time)) {
                interval = this._propertyIntervals.findIntervalContainingDate(time);
                this._cachedInterval = interval;
            }
        }

        if (typeof interval === 'undefined') {
            return undefined;
        }
        var property = interval.data;
        var valueType = property.valueType;
        if (valueType === CzmlCartesian3) {
            result = property.getValue(time, result);
            if (interval.referenceFrame === ReferenceFrame.INERTIAL) {
                var icrfToFixed = Transforms.computeIcrfToFixedMatrix(time, scratchMatrix3);
                if (typeof icrfToFixed === 'undefined') {
                    return undefined;
                }
                return icrfToFixed.multiplyByVector(result, result);
            }
            return result;
        }
        result = interval.cachedValue = property.getValue(time, interval.cachedValue);
        if (typeof result !== 'undefined') {
            result = wgs84.cartographicToCartesian(result);
        }
        return result;
    };

    /**
     * Retrieves all values in the provided time range.  Rather than sampling, this
     * method returns the actual data points used in the source data, with the exception
     * of start, stop and currentTime parameters, which will be sampled.
     *
     * @param {JulianDate} start The first time to retrieve values for.
     * @param {JulianDate} stop The last time to retrieve values for .
     * @param {JulianDate} [currentTime] If provided, causes the algorithm to always sample the provided time, assuming it is between start and stop.
     * @param {Array} [result] The array into which to store the result.
     * @returns The modified result array or a new instance if one was not provided.
     */
    DynamicPositionProperty.prototype.getValueRangeCartesian = function(start, stop, currentTime, result) {
        if (typeof start === 'undefined') {
            throw new DeveloperError('start is required');
        }

        if (typeof stop === 'undefined') {
            throw new DeveloperError('stop is required');
        }

        if (typeof result === 'undefined') {
            result = [];
        }

        var propertyIntervals = this._propertyIntervals;

        var startIndex = typeof start === 'undefined' ? 0 : propertyIntervals.indexOf(start);
        var stopIndex = typeof stop === 'undefined' ? propertyIntervals.length - 1 : propertyIntervals.indexOf(stop);
        if (startIndex < 0) {
            startIndex = ~startIndex;
        }

        if (startIndex === propertyIntervals.getLength()) {
            result.length = 0;
            return result;
        }

        if (stopIndex < 0) {
            stopIndex = ~stopIndex;
            if (stopIndex !== propertyIntervals.getLength()) {
                result.length = 0;
                return result;
            }
            stopIndex -= 1;
        }

        var r = 0;
        //Always step exactly on start (but only use it if it exists.)
        var tmp;
        tmp = this.getValueCartesian(start, result[r]);
        if (typeof tmp !== 'undefined') {
            result[r++] = tmp;
        }

        var scratchCartographic;
        var steppedOnNow = typeof currentTime === 'undefined' || currentTime.lessThan(start) || currentTime.greaterThan(stop);
        for ( var i = startIndex; i < stopIndex + 1; i++) {
            var current;
            var interval = propertyIntervals.get(i);
            var nextInterval = propertyIntervals.get(i + 1);
            var loopStop = stop;
            if (typeof nextInterval !== 'undefined' && stop.greaterThan(nextInterval.start)) {
                loopStop = nextInterval.start;
            }
            var property = interval.data;
            var valueType = property.valueType;
            var currentInterval = property._intervals.get(0);
            var times = currentInterval.data.times;
            if (typeof times !== 'undefined') {
                //Iterate over all interval times and add the ones that fall in our
                //time range.  Note that times can contain data outside of
                //the intervals range.  This is by design for use with interpolation.
                var t;
                if (valueType === CzmlCartesian3) {
                    for (t = 0; t < times.length; t++) {
                        current = times[t];
                        if (!steppedOnNow && current.greaterThanOrEquals(currentTime)) {
                            tmp = property.getValue(currentTime, result[r]);
                            if (typeof tmp !== 'undefined') {
                                result[r++] = tmp;
                            }
                            steppedOnNow = true;
                        }
                        if (current.greaterThan(start) && current.lessThan(loopStop)) {
                            tmp = property.getValue(current, result[r]);
                            if (typeof tmp !== 'undefined') {
                                result[r++] = tmp;
                            }
                        }
                    }
                } else {
                    for (t = 0; t < times.length; t++) {
                        current = times[t];
                        if (!steppedOnNow && current.greaterThanOrEquals(currentTime)) {
                            scratchCartographic = property.getValue(currentTime, scratchCartographic);
                            result[r++] = wgs84.cartographicToCartesian(scratchCartographic);
                            steppedOnNow = true;
                        }
                        if (current.greaterThan(start) && current.lessThan(loopStop)) {
                            scratchCartographic = property.getValue(current, scratchCartographic);
                            result[r++] = wgs84.cartographicToCartesian(scratchCartographic);
                        }
                    }
                }
            } else {
                //If times is undefined, it's because the interval contains a single position
                //at which it stays for the duration of the interval.
                current = interval.start;

                //We don't need to actually step on now in this case, since the next value
                //will be the same; but we do still need to check for it.
                steppedOnNow = steppedOnNow || current.greaterThanOrEquals(currentTime);

                //Finally, get the value at this non-sampled interval.
                if (current.lessThan(loopStop)) {
                    if (valueType === CzmlCartesian3) {
                        tmp = property.getValue(current, result[r]);
                        if (typeof tmp !== 'undefined') {
                            result[r++] = tmp;
                        }
                    } else {
                        scratchCartographic = property.getValue(current, scratchCartographic);
                        result[r++] = wgs84.cartographicToCartesian(scratchCartographic);
                    }
                }
            }
        }

        //Always step exactly on stop (but only use it if it exists.)
        tmp = this.getValueCartesian(stop, result[r]);
        if (typeof tmp !== 'undefined') {
            result[r++] = tmp;
        }

        result.length = r;
        return result;
    };

    DynamicPositionProperty.prototype._addCzmlInterval = function(czmlInterval, constrainedInterval) {
        this._cachedTime = undefined;
        this._cachedInterval = undefined;

        var iso8601Interval = czmlInterval.interval, property, valueType, unwrappedInterval;
        if (typeof iso8601Interval === 'undefined') {
            iso8601Interval = Iso8601.MAXIMUM_INTERVAL.clone();
        } else {
            iso8601Interval = TimeInterval.fromIso8601(iso8601Interval);
        }

        if (typeof constrainedInterval !== 'undefined') {
            iso8601Interval = iso8601Interval.intersect(constrainedInterval);
        }

        //See if we already have data at that interval.
        var thisIntervals = this._propertyIntervals;
        var existingInterval = thisIntervals.findInterval(iso8601Interval.start, iso8601Interval.stop);

        if (typeof existingInterval !== 'undefined') {
            //If so, see if the new data is the same type.
            property = existingInterval.data;
            if (typeof property !== 'undefined') {
                valueType = property.valueType;
                unwrappedInterval = valueType.unwrapInterval(czmlInterval);
            }
        } else {
            //If not, create it.
            existingInterval = iso8601Interval;
            existingInterval.referenceFrame = ReferenceFrame.FIXED;
            thisIntervals.addInterval(existingInterval);
        }

        //If the new data was a different type, unwrapping fails, look for a valueType for this type.
        if (typeof unwrappedInterval === 'undefined') {
            for ( var i = 0, len = potentialTypes.length; i < len; i++) {
                valueType = potentialTypes[i];
                unwrappedInterval = valueType.unwrapInterval(czmlInterval);
                if (typeof unwrappedInterval !== 'undefined') {
                    property = new DynamicProperty(valueType);
                    this._dynamicProperties.push(property);
                    existingInterval.data = property;
                    break;
                }
            }
        }

        //We could handle the data, add it to the property.
        if (typeof unwrappedInterval !== 'undefined') {
            if (typeof czmlInterval.referenceFrame !== 'undefined') {
                existingInterval.referenceFrame = ReferenceFrame[czmlInterval.referenceFrame];
            }
            property._addCzmlIntervalUnwrapped(iso8601Interval.start, iso8601Interval.stop, unwrappedInterval, czmlInterval.epoch, czmlInterval.interpolationAlgorithm, czmlInterval.interpolationDegree);
        }
    };

    DynamicPositionProperty.prototype._getReferenceFrame = function() {
        var propertyIntervals = this._propertyIntervals;
        if (propertyIntervals.getLength() > 0) {
            return propertyIntervals.get(0).referenceFrame;
        }
        return undefined;
    };

    DynamicPositionProperty.prototype._getValueInReferenceFrame = function(time, referenceFrame, result) {
        if (typeof time === 'undefined') {
            throw new DeveloperError('time is required.');
        }

        var interval = this._cachedInterval;
        if (this._cachedTime !== time) {
            this._cachedTime = time;
            if (typeof interval === 'undefined' || !interval.contains(time)) {
                interval = this._propertyIntervals.findIntervalContainingDate(time);
                this._cachedInterval = interval;
            }
        }

        if (typeof interval === 'undefined') {
            return undefined;
        }
        var property = interval.data;
        var valueType = property.valueType;
        if (valueType === CzmlCartesian3) {
            result = property.getValue(time, result);
        } else {
            result = interval.cachedValue = property.getValue(time, interval.cachedValue);
            if (typeof result !== 'undefined') {
                result = wgs84.cartographicToCartesian(result);
            }
        }

        if (interval.referenceFrame !== referenceFrame) {
            if (referenceFrame === ReferenceFrame.FIXED) {
                var icrfToFixed = Transforms.computeIcrfToFixedMatrix(time, scratchMatrix3);
                if (typeof icrfToFixed === 'undefined') {
                    return undefined;
                }
                return icrfToFixed.multiplyByVector(result, result);
            }
            if (referenceFrame === ReferenceFrame.INERTIAL) {
                var fixedToIcrf = Transforms.computeFixedToIcrfMatrix(time, scratchMatrix3);
                if (typeof fixedToIcrf === 'undefined') {
                    return undefined;
                }
                return fixedToIcrf.multiplyByVector(result, result);
            }
        }
        return result;
    };

    DynamicPositionProperty.prototype._getValueRangeInReferenceFrame = function(start, stop, currentTime, referenceFrame, result) {
        if (typeof start === 'undefined') {
            throw new DeveloperError('start is required');
        }

        if (typeof stop === 'undefined') {
            throw new DeveloperError('stop is required');
        }

        if (typeof result === 'undefined') {
            result = [];
        }

        var propertyIntervals = this._propertyIntervals;

        var startIndex = typeof start === 'undefined' ? 0 : propertyIntervals.indexOf(start);
        var stopIndex = typeof stop === 'undefined' ? propertyIntervals.length - 1 : propertyIntervals.indexOf(stop);
        if (startIndex < 0) {
            startIndex = ~startIndex;
        }

        if (startIndex === propertyIntervals.getLength()) {
            result.length = 0;
            return result;
        }

        if (stopIndex < 0) {
            stopIndex = ~stopIndex;
            if (stopIndex !== propertyIntervals.getLength()) {
                result.length = 0;
                return result;
            }
            stopIndex -= 1;
        }

        var r = 0;
        //Always step exactly on start (but only use it if it exists.)
        var tmp;
        tmp = this._getValueInReferenceFrame(start, referenceFrame, result[r]);
        if (typeof tmp !== 'undefined') {
            result[r++] = tmp;
        }

        var steppedOnNow = typeof currentTime === 'undefined' || currentTime.lessThan(start) || currentTime.greaterThan(stop);
        for ( var i = startIndex; i < stopIndex + 1; i++) {
            var current;
            var interval = propertyIntervals.get(i);
            var nextInterval = propertyIntervals.get(i + 1);
            var loopStop = stop;
            if (typeof nextInterval !== 'undefined' && stop.greaterThan(nextInterval.start)) {
                loopStop = nextInterval.start;
            }
            var property = interval.data;
            var currentInterval = property._intervals.get(0);
            var times = currentInterval.data.times;
            if (typeof times !== 'undefined') {
                //Iterate over all interval times and add the ones that fall in our
                //time range.  Note that times can contain data outside of
                //the intervals range.  This is by design for use with interpolation.
                var t;
                for (t = 0; t < times.length; t++) {
                    current = times[t];
                    if (!steppedOnNow && current.greaterThanOrEquals(currentTime)) {
                        tmp = this._getValueInReferenceFrame(currentTime, referenceFrame, result[r]);
                        if (typeof tmp !== 'undefined') {
                            result[r++] = tmp;
                        }
                        steppedOnNow = true;
                    }
                    if (current.greaterThan(start) && current.lessThan(loopStop)) {
                        tmp = this._getValueInReferenceFrame(current, referenceFrame, result[r]);
                        if (typeof tmp !== 'undefined') {
                            result[r++] = tmp;
                        }
                    }
                }
            } else {
                //If times is undefined, it's because the interval contains a single position
                //at which it stays for the duration of the interval.
                current = interval.start;

                //We don't need to actually step on now in this case, since the next value
                //will be the same; but we do still need to check for it.
                steppedOnNow = steppedOnNow || current.greaterThanOrEquals(currentTime);

                //Finally, get the value at this non-sampled interval.
                if (current.lessThan(loopStop)) {
                    tmp = this._getValueInReferenceFrame(current, referenceFrame, result[r]);
                    if (typeof tmp !== 'undefined') {
                        result[r++] = tmp;
                    }
                }
            }
        }

        //Always step exactly on stop (but only use it if it exists.)
        tmp = this._getValueInReferenceFrame(stop, referenceFrame, result[r]);
        if (typeof tmp !== 'undefined') {
            result[r++] = tmp;
        }

        result.length = r;
        return result;
    };

    return DynamicPositionProperty;
});
;�FI"dependency_digest;�F"%0f256eb2f066e9758d3d470b9f9fd535I"required_paths;�F[I"d/Users/bwrona/www/engines/cesium/app/assets/javascripts/DynamicScene/DynamicPositionProperty.js;�TI"dependency_paths;�F[{I"	path;�FI"d/Users/bwrona/www/engines/cesium/app/assets/javascripts/DynamicScene/DynamicPositionProperty.js;�TI"
mtime;�FI"2013-02-11T17:47:50+01:00;�FI"digest;�F"%25072e70af4a50f50dd23ea5e7ad6a2dI"
_version;�F"%6776f581a4329e299531e1d52aa59832