"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var getTimelineMaxTime_1 = require("./helpers/getTimelineMaxTime");
var SimpleEventEmitter_1 = require("./helpers/SimpleEventEmitter");
var assign_1 = require("./vendor/assign");
var NUMBER = 'number';
var DEFAULT_OPTIONS = {
    loop: true,
};
var HaikuTimeline = (function () {
    function HaikuTimeline(component, name, descriptor, options) {
        SimpleEventEmitter_1.default.create(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;
    }
    HaikuTimeline.prototype.assignOptions = function (options) {
        this.options = assign_1.default(this.options || {}, DEFAULT_OPTIONS, options || {});
        return this;
    };
    HaikuTimeline.prototype.ensureClockIsRunning = function () {
        var clock = this._component.getClock();
        if (!clock.isRunning()) {
            clock.start();
        }
        return this;
    };
    HaikuTimeline.prototype.setComponent = function (component) {
        this._component = component;
        return this;
    };
    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()) {
            this.shout('tick');
        }
        this.shout('update');
        return this;
    };
    HaikuTimeline.prototype.resetMaxDefinedTimeFromDescriptor = function (descriptor) {
        this._maxExplicitlyDefinedTime = getTimelineMaxTime_1.default(descriptor);
        return this;
    };
    HaikuTimeline.prototype.isTimeControlled = function () {
        return typeof this.getControlledTime() === NUMBER;
    };
    HaikuTimeline.prototype.controlTime = function (controlledTimeToSet, updatedGlobalClockTime) {
        this._localExplicitlySetTime = parseInt(controlledTimeToSet || 0, 10);
        this.updateInternalProperties(updatedGlobalClockTime);
        return this;
    };
    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;
        return this;
    };
    HaikuTimeline.prototype.getRepeat = function () {
        return !!this.options.loop;
    };
    HaikuTimeline.prototype.freeze = function () {
        this.options.freeze = true;
        return this;
    };
    HaikuTimeline.prototype.unfreeze = function () {
        this.options.freeze = false;
        return this;
    };
    HaikuTimeline.prototype.shout = function (key) {
        var frame = this.getFrame();
        var time = Math.round(this.getTime());
        var name = this.getName();
        this.emit(key, frame, time);
        this._component.emit('timeline:' + key, name, frame, time);
        return this;
    };
    HaikuTimeline.prototype.start = function (maybeGlobalClockTime, descriptor) {
        this._localElapsedTime = 0;
        this._isPlaying = true;
        this._globalClockTime = maybeGlobalClockTime || 0;
        this._maxExplicitlyDefinedTime = getTimelineMaxTime_1.default(descriptor);
        this.shout('start');
        return this;
    };
    HaikuTimeline.prototype.stop = function (maybeGlobalClockTime, descriptor) {
        this._isPlaying = false;
        this._maxExplicitlyDefinedTime = getTimelineMaxTime_1.default(descriptor);
        this.shout('stop');
        return this;
    };
    HaikuTimeline.prototype.pause = function () {
        var time = this._component.getClock().getTime();
        var descriptor = this._component._getTimelineDescriptor(this._name);
        this.stop(time, descriptor);
        this.shout('pause');
        return this;
    };
    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.shout('play');
        return this;
    };
    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.shout('seek');
        return this;
    };
    HaikuTimeline.prototype.gotoAndPlay = function (ms) {
        this.ensureClockIsRunning();
        this.seek(ms);
        this.play(null);
        return this;
    };
    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 this;
    };
    return HaikuTimeline;
}());
exports.default = HaikuTimeline;
//# sourceMappingURL=HaikuTimeline.js.map