/*
* Copyright 2019 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "modules/particles/include/SkCurve.h"

#include "include/utils/SkRandom.h"
#include "modules/particles/include/SkParticleData.h"
#include "modules/particles/include/SkReflected.h"

constexpr SkFieldVisitor::EnumStringMapping gCurveSegmentTypeMapping[] = {
    { kConstant_SegmentType, "Constant" },
    { kLinear_SegmentType,   "Linear" },
    { kCubic_SegmentType,    "Cubic" },
};

static SkColor4f operator+(SkColor4f c1, SkColor4f c2) {
    return { c1.fR + c2.fR, c1.fG + c2.fG, c1.fB + c2.fB, c1.fA + c2.fA };
}

static SkColor4f operator-(SkColor4f c1, SkColor4f c2) {
    return { c1.fR - c2.fR, c1.fG - c2.fG, c1.fB - c2.fB, c1.fA - c2.fA };
}

template <typename T>
static T eval_cubic(const T* pts, float x) {
    float ix = (1 - x);
    return pts[0]*(ix*ix*ix) + pts[1]*(3*ix*ix*x) + pts[2]*(3*ix*x*x) + pts[3]*(x*x*x);
}

template <typename T>
static T eval_segment(const T* pts, float x, int type) {
    switch (type) {
        case kLinear_SegmentType:
            return pts[0] + (pts[3] - pts[0]) * x;
        case kCubic_SegmentType:
            return eval_cubic(pts, x);
        case kConstant_SegmentType:
        default:
            return pts[0];
    }
}

float SkCurveSegment::eval(float x, float t, bool negate) const {
    float result = eval_segment(fMin, x, fType);
    if (fRanged) {
        result += (eval_segment(fMax, x, fType) - result) * t;
    }
    if (fBidirectional && negate) {
        result = -result;
    }
    return result;
}

void SkCurveSegment::visitFields(SkFieldVisitor* v) {
    v->visit("Type", fType, gCurveSegmentTypeMapping, SK_ARRAY_COUNT(gCurveSegmentTypeMapping));
    v->visit("Ranged", fRanged);
    v->visit("Bidirectional", fBidirectional);
    v->visit("A0", fMin[0]);
    if (fType == kCubic_SegmentType) {
        v->visit("B0", fMin[1]);
        v->visit("C0", fMin[2]);
    }
    if (fType != kConstant_SegmentType) {
        v->visit("D0", fMin[3]);
    }
    if (fRanged) {
        v->visit("A1", fMax[0]);
        if (fType == kCubic_SegmentType) {
            v->visit("B1", fMax[1]);
            v->visit("C1", fMax[2]);
        }
        if (fType != kConstant_SegmentType) {
            v->visit("D1", fMax[3]);
        }
    }
}

float SkCurve::eval(const SkParticleUpdateParams& params, SkParticleState& ps) const {
    SkASSERT(fSegments.count() == fXValues.count() + 1);

    float x = fInput.eval(params, ps);

    int i = 0;
    for (; i < fXValues.count(); ++i) {
        if (x <= fXValues[i]) {
            break;
        }
    }

    float rangeMin = (i == 0) ? 0.0f : fXValues[i - 1];
    float rangeMax = (i == fXValues.count()) ? 1.0f : fXValues[i];
    float segmentX = (x - rangeMin) / (rangeMax - rangeMin);
    if (!sk_float_isfinite(segmentX)) {
        segmentX = rangeMin;
    }
    SkASSERT(0.0f <= segmentX && segmentX <= 1.0f);

    // Always pull t and negate here, so that the stable generator behaves consistently, even if
    // our segments use an inconsistent feature-set.
    float t = ps.fRandom.nextF();
    bool negate = ps.fRandom.nextBool();
    return fSegments[i].eval(segmentX, t, negate);
}

void SkCurve::visitFields(SkFieldVisitor* v) {
    v->visit("Input", fInput);
    v->visit("XValues", fXValues);
    v->visit("Segments", fSegments);

    // Validate and fixup
    if (fSegments.empty()) {
        fSegments.push_back().setConstant(0.0f);
    }
    fXValues.resize_back(fSegments.count() - 1);
    for (int i = 0; i < fXValues.count(); ++i) {
        fXValues[i] = SkTPin(fXValues[i], i > 0 ? fXValues[i - 1] : 0.0f, 1.0f);
    }
}

SkColor4f SkColorCurveSegment::eval(float x, float t) const {
    SkColor4f result = eval_segment(fMin, x, fType);
    if (fRanged) {
        result = result + (eval_segment(fMax, x, fType) - result) * t;
    }
    return result;
}

void SkColorCurveSegment::visitFields(SkFieldVisitor* v) {
    v->visit("Type", fType, gCurveSegmentTypeMapping, SK_ARRAY_COUNT(gCurveSegmentTypeMapping));
    v->visit("Ranged", fRanged);
    v->visit("A0", fMin[0]);
    if (fType == kCubic_SegmentType) {
        v->visit("B0", fMin[1]);
        v->visit("C0", fMin[2]);
    }
    if (fType != kConstant_SegmentType) {
        v->visit("D0", fMin[3]);
    }
    if (fRanged) {
        v->visit("A1", fMax[0]);
        if (fType == kCubic_SegmentType) {
            v->visit("B1", fMax[1]);
            v->visit("C1", fMax[2]);
        }
        if (fType != kConstant_SegmentType) {
            v->visit("D1", fMax[3]);
        }
    }
}

SkColor4f SkColorCurve::eval(const SkParticleUpdateParams& params, SkParticleState& ps) const {
    SkASSERT(fSegments.count() == fXValues.count() + 1);

    float x = fInput.eval(params, ps);

    int i = 0;
    for (; i < fXValues.count(); ++i) {
        if (x <= fXValues[i]) {
            break;
        }
    }

    float rangeMin = (i == 0) ? 0.0f : fXValues[i - 1];
    float rangeMax = (i == fXValues.count()) ? 1.0f : fXValues[i];
    float segmentX = (x - rangeMin) / (rangeMax - rangeMin);
    if (!sk_float_isfinite(segmentX)) {
        segmentX = rangeMin;
    }
    SkASSERT(0.0f <= segmentX && segmentX <= 1.0f);
    return fSegments[i].eval(segmentX, ps.fRandom.nextF());
}

void SkColorCurve::visitFields(SkFieldVisitor* v) {
    v->visit("Input", fInput);
    v->visit("XValues", fXValues);
    v->visit("Segments", fSegments);

    // Validate and fixup
    if (fSegments.empty()) {
        fSegments.push_back().setConstant(SkColor4f{ 1.0f, 1.0f, 1.0f, 1.0f });
    }
    fXValues.resize_back(fSegments.count() - 1);
    for (int i = 0; i < fXValues.count(); ++i) {
        fXValues[i] = SkTPin(fXValues[i], i > 0 ? fXValues[i - 1] : 0.0f, 1.0f);
    }
}
