"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * Copyright (c) Haiku 2016-2018. All rights reserved.
 */
var Interpolate_1 = require("./Interpolate");
var KEYFRAME_MARGIN = 16.666;
function ascendingSort(a, b) {
    return a - b;
}
function numberize(n) {
    return parseInt(n, 10);
}
function sortedKeyframesCached(keyframeGroup) {
    // Cache the output of this on the object since this is very hot
    if (keyframeGroup.__sorted) {
        return keyframeGroup.__sorted;
    }
    var sorted = sortedKeyframes(keyframeGroup);
    // Cache the sorted keys
    keyframeGroup.__sorted = sorted;
    return keyframeGroup.__sorted;
}
function sortedKeyframes(keyframeGroup) {
    var keys = Object.keys(keyframeGroup);
    var sorted = keys.sort(ascendingSort).map(numberize);
    return sorted;
}
// 0:    { value: { ... } }
// 2500: { value: { ... } }
// 5000: { value: { ... } }
function getKeyframesList(keyframeGroup, nowValue) {
    var sorted = sortedKeyframesCached(keyframeGroup);
    for (var i = 0; i < sorted.length; i++) {
        var j = i + 1;
        var current = sorted[i];
        var next = sorted[j];
        if (current <= nowValue) {
            if (next > nowValue) {
                return [current, next];
            }
            if (j >= sorted.length) {
                return [current];
            }
        }
    }
}
function calculateValue(keyframeGroup, nowValue) {
    var keyframesList = getKeyframesList(keyframeGroup, nowValue);
    if (!keyframesList || keyframesList.length < 1) {
        return;
    }
    var currentKeyframe = keyframesList[0];
    var currentTransition = keyframeGroup[currentKeyframe];
    var nextKeyframe = keyframesList[1];
    var nextTransition = keyframeGroup[nextKeyframe];
    var finalValue = getTransitionValue(currentKeyframe, currentTransition, nextKeyframe, nextTransition, nowValue);
    return finalValue;
}
function calculateValueAndReturnUndefinedIfNotWorthwhile(keyframeGroup, nowValue) {
    var keyframesList = getKeyframesList(keyframeGroup, nowValue);
    if (!keyframesList || keyframesList.length < 1) {
        return void 0;
    }
    var currentKeyframe = keyframesList[0];
    var nextKeyframe = keyframesList[1];
    var currentTransition = keyframeGroup[currentKeyframe];
    var nextTransition = keyframeGroup[nextKeyframe];
    // If either this or the next transition came from an expression,
    // we must recalc, since they may be time-dependant
    if ((currentTransition && currentTransition.expression) ||
        (nextTransition && nextTransition.expression)) {
        return getTransitionValue(currentKeyframe, currentTransition, nextKeyframe, nextTransition, nowValue);
    }
    // If no preceding keyframe, check if we need to calculate any values past the initial one
    if (nextKeyframe === undefined) {
        if (nowValue <= currentKeyframe + KEYFRAME_MARGIN) {
            return getTransitionValue(currentKeyframe, currentTransition, nextKeyframe, nextTransition, nowValue);
        }
        return void 0;
    }
    // If there is a next one, check to see if our current time has already exceeded it, and skip if so
    if (nowValue <= nextKeyframe + KEYFRAME_MARGIN) {
        return getTransitionValue(currentKeyframe, currentTransition, nextKeyframe, nextTransition, nowValue);
    }
    return void 0;
}
function getTransitionValue(currentKeyframe, currentTransition, nextKeyframe, nextTransition, nowValue) {
    var currentValue = currentTransition.value;
    if (!currentTransition.curve) {
        return currentValue;
    } // No curve indicates immediate transition
    if (!nextTransition) {
        return currentValue;
    } // We have gone past the final transition
    var finalValue = Interpolate_1.default.interpolate(nowValue, currentTransition.curve, currentKeyframe, nextKeyframe, currentValue, nextTransition.value);
    return finalValue;
}
exports.default = {
    calculateValue: calculateValue,
    calculateValueAndReturnUndefinedIfNotWorthwhile: calculateValueAndReturnUndefinedIfNotWorthwhile,
    sortedKeyframes: sortedKeyframes,
};
//# sourceMappingURL=Transitions.js.map