/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Interpolator.h"

#include <algorithm>

#include <log/log.h>

#include "utils/MathUtils.h"

namespace android {
namespace uirenderer {

Interpolator* Interpolator::createDefaultInterpolator() {
    return new AccelerateDecelerateInterpolator();
}

float AccelerateDecelerateInterpolator::interpolate(float input) {
    return (float)(cosf((input + 1) * M_PI) / 2.0f) + 0.5f;
}

float AccelerateInterpolator::interpolate(float input) {
    if (mFactor == 1.0f) {
        return input * input;
    } else {
        return pow(input, mDoubleFactor);
    }
}

float AnticipateInterpolator::interpolate(float t) {
    return t * t * ((mTension + 1) * t - mTension);
}

static float a(float t, float s) {
    return t * t * ((s + 1) * t - s);
}

static float o(float t, float s) {
    return t * t * ((s + 1) * t + s);
}

float AnticipateOvershootInterpolator::interpolate(float t) {
    if (t < 0.5f)
        return 0.5f * a(t * 2.0f, mTension);
    else
        return 0.5f * (o(t * 2.0f - 2.0f, mTension) + 2.0f);
}

static float bounce(float t) {
    return t * t * 8.0f;
}

float BounceInterpolator::interpolate(float t) {
    t *= 1.1226f;
    if (t < 0.3535f)
        return bounce(t);
    else if (t < 0.7408f)
        return bounce(t - 0.54719f) + 0.7f;
    else if (t < 0.9644f)
        return bounce(t - 0.8526f) + 0.9f;
    else
        return bounce(t - 1.0435f) + 0.95f;
}

float CycleInterpolator::interpolate(float input) {
    return sinf(2 * mCycles * M_PI * input);
}

float DecelerateInterpolator::interpolate(float input) {
    float result;
    if (mFactor == 1.0f) {
        result = 1.0f - (1.0f - input) * (1.0f - input);
    } else {
        result = 1.0f - pow((1.0f - input), 2 * mFactor);
    }
    return result;
}

float OvershootInterpolator::interpolate(float t) {
    t -= 1.0f;
    return t * t * ((mTension + 1) * t + mTension) + 1.0f;
}

float PathInterpolator::interpolate(float t) {
    if (t <= 0) {
        return 0;
    } else if (t >= 1) {
        return 1;
    }
    // Do a binary search for the correct x to interpolate between.
    size_t startIndex = 0;
    size_t endIndex = mX.size() - 1;

    while (endIndex > startIndex + 1) {
        int midIndex = (startIndex + endIndex) / 2;
        if (t < mX[midIndex]) {
            endIndex = midIndex;
        } else {
            startIndex = midIndex;
        }
    }

    float xRange = mX[endIndex] - mX[startIndex];
    if (xRange == 0) {
        return mY[startIndex];
    }

    float tInRange = t - mX[startIndex];
    float fraction = tInRange / xRange;

    float startY = mY[startIndex];
    float endY = mY[endIndex];
    return startY + (fraction * (endY - startY));
}

LUTInterpolator::LUTInterpolator(float* values, size_t size) : mValues(values), mSize(size) {}

LUTInterpolator::~LUTInterpolator() {}

float LUTInterpolator::interpolate(float input) {
    // lut position should only be at the end of the table when input is 1f.
    float lutpos = input * (mSize - 1);
    if (lutpos >= (mSize - 1)) {
        return mValues[mSize - 1];
    }

    float ipart, weight;
    weight = modff(lutpos, &ipart);

    int i1 = (int)ipart;
    int i2 = std::min(i1 + 1, (int)mSize - 1);

    LOG_ALWAYS_FATAL_IF(
            i1 < 0 || i2 < 0,
            "negatives in interpolation!"
            " i1=%d, i2=%d, input=%f, lutpos=%f, size=%zu, values=%p, ipart=%f, weight=%f",
            i1, i2, input, lutpos, mSize, mValues.get(), ipart, weight);

    float v1 = mValues[i1];
    float v2 = mValues[i2];

    return MathUtils::lerp(v1, v2, weight);
}

} /* namespace uirenderer */
} /* namespace android */
