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

#ifndef SkCurve_DEFINED
#define SkCurve_DEFINED

#include "SkColor.h"
#include "SkParticleData.h"
#include "SkScalar.h"
#include "SkTArray.h"

class SkFieldVisitor;

/**
 * SkCurve implements a keyframed 1D function, useful for animating values over time. This pattern
 * is common in digital content creation tools. An SkCurve might represent rotation, scale, opacity,
 * or any other scalar quantity.
 *
 * An SkCurve has a logical domain of [0, 1], and is made of one or more SkCurveSegments.
 * Each segment describes the behavior of the curve in some sub-domain. For an SkCurve with N
 * segments, there are (N - 1) intermediate x-values that subdivide the domain. The first and last
 * x-values are implicitly 0 and 1:
 *
 * 0    ...    x[0]    ...    x[1]   ...      ...    1
 *   Segment_0      Segment_1     ...     Segment_N-1
 *
 * Each segment describes a function over [0, 1] - x-values are re-normalized to the segment's
 * domain when being evaluated. The segments are cubic polynomials, defined by four values (fMin).
 * These are the values at x=0 and x=1, as well as control points at x=1/3 and x=2/3.
 *
 * For segments with fConstant == true, only the first value is used (fMin[0]).
 *
 * Each segment has two additional features for creating interesting (and varied) animation:
 *   - A segment can be ranged. Ranged segments have two sets of coefficients, and a random value
 *     taken from the particle's SkRandom is used to lerp betwen them. Typically, the SkRandom is
 *     in the same state at each call, so this value is stable. That causes a ranged SkCurve to
 *     produce a single smooth cubic function somewhere within the range defined by fMin and fMax.
 *   - A segment can be bidirectional. In that case, after a value is computed, it will be negated
 *     50% of the time.
 */

enum SkCurveSegmentType {
    kConstant_SegmentType,
    kLinear_SegmentType,
    kCubic_SegmentType,
};

struct SkCurveSegment {
    SkScalar eval(SkScalar x, SkScalar t, bool negate) const;
    void visitFields(SkFieldVisitor* v);

    void setConstant(SkScalar c) {
        fType   = kConstant_SegmentType;
        fRanged = false;
        fMin[0] = c;
    }

    SkScalar fMin[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
    SkScalar fMax[4] = { 0.0f, 0.0f, 0.0f, 0.0f };

    int  fType          = kConstant_SegmentType;
    bool fRanged        = false;
    bool fBidirectional = false;
};

struct SkCurve {
    SkCurve(SkScalar c = 0.0f) {
        fSegments.push_back().setConstant(c);
    }

    SkScalar eval(const SkParticleUpdateParams& params, SkParticleState& ps) const;
    void visitFields(SkFieldVisitor* v);

    // Parameters that determine our x-value during evaluation
    SkParticleValue                fInput;

    // It should always be true that (fXValues.count() + 1) == fSegments.count()
    SkTArray<SkScalar, true>       fXValues;
    SkTArray<SkCurveSegment, true> fSegments;
};

/**
 * SkColorCurve is similar to SkCurve, but keyframes 4D values - specifically colors. Because
 * negative colors rarely make sense, SkColorCurves do not support bidirectional segments, but
 * support all other features (including cubic interpolation).
 */

struct SkColorCurveSegment {
    SkColorCurveSegment() {
        for (int i = 0; i < 4; ++i) {
            fMin[i] = { 1.0f, 1.0f, 1.0f, 1.0f };
            fMax[i] = { 1.0f, 1.0f, 1.0f, 1.0f };
        }
    }

    SkColor4f eval(SkScalar x, SkScalar t) const;
    void visitFields(SkFieldVisitor* v);

    void setConstant(SkColor4f c) {
        fType   = kConstant_SegmentType;
        fRanged = false;
        fMin[0] = c;
    }

    SkColor4f fMin[4];
    SkColor4f fMax[4];

    int  fType   = kConstant_SegmentType;
    bool fRanged = false;
};

struct SkColorCurve {
    SkColorCurve(SkColor4f c = { 1.0f, 1.0f, 1.0f, 1.0f }) {
        fSegments.push_back().setConstant(c);
    }

    SkColor4f eval(const SkParticleUpdateParams& params, SkParticleState& ps) const;
    void visitFields(SkFieldVisitor* v);

    SkParticleValue                     fInput;
    SkTArray<SkScalar, true>            fXValues;
    SkTArray<SkColorCurveSegment, true> fSegments;
};

#endif // SkCurve_DEFINED
