"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var HaikuBase_1 = require("./HaikuBase");
var getTimelineMaxTime_1 = require("./helpers/getTimelineMaxTime");
var assign_1 = require("./vendor/assign");
var NUMBER = 'number';
var DEFAULT_OPTIONS = {
    loop: true,
};
var HaikuTimeline = (function (_super) {
    __extends(HaikuTimeline, _super);
    function HaikuTimeline(component, name, descriptor, options) {
        var _this = _super.call(this) || this;
        _this.component = component;
        _this._name = name;
        _this._descriptor = descriptor;
        _this.assignOptions(options || {});
        _this._globalClockTime = 0;
        _this._localElapsedTime = 0;
        _this._localExplicitlySetTime = null;
        _this._maxExplicitlyDefinedTime = getTimelineMaxTime_1.default(descriptor);
        _this._isPlaying = false;
        return _this;
    }
    HaikuTimeline.prototype.assignOptions = function (options) {
        this.options = assign_1.default(this.options || {}, DEFAULT_OPTIONS, options || {});
    };
    HaikuTimeline.prototype.ensureClockIsRunning = function () {
        var clock = this.component.getClock();
        if (!clock.isRunning()) {
            clock.start();
        }
    };
    HaikuTimeline.prototype.setComponent = function (component) {
        this.component = component;
    };
    HaikuTimeline.prototype.updateInternalProperties = function (updatedGlobalClockTime) {
        var previousGlobalClockTime = this._globalClockTime;
        var deltaGlobalClockTime = updatedGlobalClockTime - previousGlobalClockTime;
        this._globalClockTime = updatedGlobalClockTime;
        if (this.isTimeControlled()) {
            this._localElapsedTime = this._localExplicitlySetTime;
        }
        else {
            if (this.options.loop &&
                this._localElapsedTime > this._maxExplicitlyDefinedTime) {
                this._localElapsedTime =
                    0 + this._maxExplicitlyDefinedTime - this._localElapsedTime;
            }
            this._localElapsedTime += deltaGlobalClockTime;
        }
        if (this.isFinished()) {
            this._isPlaying = false;
        }
    };
    HaikuTimeline.prototype.doUpdateWithGlobalClockTime = function (globalClockTime) {
        if (this.isFrozen()) {
            this.updateInternalProperties(this._globalClockTime);
        }
        else {
            this.updateInternalProperties(globalClockTime);
        }
        if (this.isPlaying()) {
            var frame = this.getFrame();
            this.component.routeEventToHandlerAndEmit(HaikuBase_1.GLOBAL_LISTENER_KEY, "timeline:" + this.getName() + ":" + frame, [frame, Math.round(this.getTime())]);
            this.emit('frame', frame);
        }
    };
    HaikuTimeline.prototype.resetMaxDefinedTimeFromDescriptor = function (descriptor) {
        this._maxExplicitlyDefinedTime = getTimelineMaxTime_1.default(descriptor);
    };
    HaikuTimeline.prototype.isTimeControlled = function () {
        return typeof this.getControlledTime() === NUMBER;
    };
    HaikuTimeline.prototype.controlTime = function (controlledTimeToSet, updatedGlobalClockTime) {
        this._localExplicitlySetTime = parseInt(controlledTimeToSet || 0, 10);
        this.updateInternalProperties(updatedGlobalClockTime);
    };
    HaikuTimeline.prototype.getName = function () {
        return this._name;
    };
    HaikuTimeline.prototype.getMaxTime = function () {
        return this._maxExplicitlyDefinedTime;
    };
    HaikuTimeline.prototype.getClockTime = function () {
        return this._globalClockTime;
    };
    HaikuTimeline.prototype.getElapsedTime = function () {
        return this._localElapsedTime;
    };
    HaikuTimeline.prototype.getControlledTime = function () {
        return this._localExplicitlySetTime;
    };
    HaikuTimeline.prototype.getBoundedTime = function () {
        var max = this.getMaxTime();
        var elapsed = this.getElapsedTime();
        if (elapsed > max) {
            return max;
        }
        return elapsed;
    };
    HaikuTimeline.prototype.getTime = function () {
        return this.getBoundedTime();
    };
    HaikuTimeline.prototype.getBoundedFrame = function () {
        var time = this.getBoundedTime();
        var timeStep = this.component.getClock().getFrameDuration();
        return Math.round(time / timeStep);
    };
    HaikuTimeline.prototype.getUnboundedFrame = function () {
        var time = this.getElapsedTime();
        var timeStep = this.component.getClock().getFrameDuration();
        return Math.round(time / timeStep);
    };
    HaikuTimeline.prototype.getFrame = function () {
        return this.getBoundedFrame();
    };
    HaikuTimeline.prototype.isPlaying = function () {
        return !!this._isPlaying;
    };
    HaikuTimeline.prototype.isFrozen = function () {
        return !!this.options.freeze;
    };
    HaikuTimeline.prototype.isFinished = function () {
        if (this.options.loop || this.isTimeControlled()) {
            return false;
        }
        return ~~this.getElapsedTime() > this.getMaxTime();
    };
    HaikuTimeline.prototype.duration = function () {
        return this.getMaxTime() || 0;
    };
    HaikuTimeline.prototype.getDuration = function () {
        return this.duration();
    };
    HaikuTimeline.prototype.setRepeat = function (bool) {
        this.options.loop = bool;
    };
    HaikuTimeline.prototype.getRepeat = function () {
        return !!this.options.loop;
    };
    HaikuTimeline.prototype.freeze = function () {
        this.options.freeze = true;
    };
    HaikuTimeline.prototype.unfreeze = function () {
        this.options.freeze = false;
    };
    HaikuTimeline.prototype.start = function (maybeGlobalClockTime, descriptor) {
        this._localElapsedTime = 0;
        this._isPlaying = true;
        this._globalClockTime = maybeGlobalClockTime || 0;
        this._maxExplicitlyDefinedTime = getTimelineMaxTime_1.default(descriptor);
        this.emit('start');
    };
    HaikuTimeline.prototype.stop = function (maybeGlobalClockTime, descriptor) {
        this._isPlaying = false;
        this._maxExplicitlyDefinedTime = getTimelineMaxTime_1.default(descriptor);
        this.emit('stop');
    };
    HaikuTimeline.prototype.pause = function () {
        var time = this.component.getClock().getTime();
        var descriptor = this.component.getTimelineDescriptor(this._name);
        this.stop(time, descriptor);
        this.emit('pause');
    };
    HaikuTimeline.prototype.play = function (requestedOptions) {
        var options = requestedOptions || {};
        this.ensureClockIsRunning();
        var time = this.component.getClock().getTime();
        var descriptor = this.component.getTimelineDescriptor(this._name);
        var local = this._localElapsedTime;
        this.start(time, descriptor);
        if (this._localExplicitlySetTime !== null) {
            this._localElapsedTime = this._localExplicitlySetTime;
            this._localExplicitlySetTime = null;
        }
        else {
            this._localElapsedTime = local;
        }
        if (!options.skipMarkForFullFlush) {
            this.component._markForFullFlush();
        }
        this.emit('play');
    };
    HaikuTimeline.prototype.seek = function (ms) {
        this.ensureClockIsRunning();
        var clockTime = this.component.getClock().getTime();
        this.controlTime(ms, clockTime);
        var descriptor = this.component.getTimelineDescriptor(this._name);
        this.start(clockTime, descriptor);
        this.component._markForFullFlush();
        this.emit('seek', ms);
    };
    HaikuTimeline.prototype.gotoAndPlay = function (ms) {
        this.ensureClockIsRunning();
        this.seek(ms);
        this.play(null);
    };
    HaikuTimeline.prototype.gotoAndStop = function (ms) {
        this.ensureClockIsRunning();
        this.seek(ms);
        if (this.component && this.component._context && this.component._context.tick) {
            this.component._context.tick();
        }
        this.pause();
    };
    return HaikuTimeline;
}(HaikuBase_1.default));
exports.default = HaikuTimeline;
//# sourceMappingURL=HaikuTimeline.js.map