/*
* 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, SkScalar x) {
    SkScalar 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, SkScalar 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];
    }
}

SkScalar SkCurveSegment::eval(SkScalar x, SkScalar t, bool negate) const {
    SkScalar 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]);
        }
    }
}

SkScalar 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;
        }
    }

    SkScalar rangeMin = (i == 0) ? 0.0f : fXValues[i - 1];
    SkScalar rangeMax = (i == fXValues.count()) ? 1.0f : fXValues[i];
    SkScalar segmentX = (x - rangeMin) / (rangeMax - rangeMin);
    if (!SkScalarIsFinite(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.
    SkScalar 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(SkScalar x, SkScalar 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;
        }
    }

    SkScalar rangeMin = (i == 0) ? 0.0f : fXValues[i - 1];
    SkScalar rangeMax = (i == fXValues.count()) ? 1.0f : fXValues[i];
    SkScalar segmentX = (x - rangeMin) / (rangeMax - rangeMin);
    if (!SkScalarIsFinite(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);
    }
}
