/*
* 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 SkParticleEffect_DEFINED
#define SkParticleEffect_DEFINED

#include "include/core/SkColor.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTemplates.h"
#include "modules/particles/include/SkParticleData.h"

#include <memory>

class SkCanvas;
class SkFieldVisitor;
class SkParticleBinding;
class SkParticleDrawable;
class SkParticleExternalValue;

namespace skresources {
    class ResourceProvider;
}

namespace SkSL {
    class ByteCode;
}

class SkParticleEffectParams : public SkRefCnt {
public:
    SkParticleEffectParams();

    // Maximum number of particles per instance of the effect
    int   fMaxCount;

    // What is drawn for each particle? (Image, shape, sprite sheet, etc.)
    // See SkParticleDrawable::Make*
    sk_sp<SkParticleDrawable> fDrawable;

    // Particle behavior is driven by two chunks of SkSL code. Effect functions are defined in
    // fEffectCode, and get a mutable Effect struct:
    //
    // struct Effect {
    //   float age;       // Normalized age of the effect
    //   float lifetime;  // Effect's duration, in seconds - script should set this in effectSpawn
    //   int   loop;      // Number of loops that have elapsed (0 on initial spawn)
    //   float rate;      // Rate to generate new particles (particles / second)
    //   int   burst;     // Number of particles to emit in a single update
    //                    // Set during spawn to emit that many at once on each loop
    //
    //   // Everything below this line controls the state of the effect, which is also the
    //   // default values for new particles.
    //   float2 pos   = { 0, 0 };        // Local position
    //   float2 dir   = { 0, -1 };       // Heading. Should be a normalized vector.
    //   float  scale = 1;               // Size, normalized relative to the drawable's native size
    //   float2 vel   = { 0, 0 };        // Linear velocity, in (units / second)
    //   float  spin  = 0;               // Angular velocity, in (radians / second)
    //   float4 color = { 1, 1, 1, 1 };  // RGBA color
    //   float  frame = 0;               // Normalized sprite index for multi-frame drawables
    //   uint   flags = 0;               // Arbitrary state for use by script
    //   uint   seed  = 0;               // Random seed, used with rand() (see below)
    // };
    //
    // Particle functions are defined in fParticleCode, and get a mutable Particle struct, as well
    // as a uniform copy of the current Effect, named 'effect'.
    //
    // struct Particle {
    //   float  age;
    //   float  lifetime;
    //   float2 pos;
    //   float2 dir;
    //   float  scale;
    //   float2 vel;
    //   float  spin;
    //   float4 color;
    //   float  frame;
    //   uint   flags;
    //   uint   seed;
    // };
    //
    // All functions have access to a global function named 'rand'. It takes a uint seed value,
    // which it uses and updates (using a linear congruential RNG). It returns a random floating
    // point value in [0, 1]. Typical usage is to pass the particle or effect's seed value to rand.
    // For particle functions, the seed is rewound after each update, so calls to 'rand(p.seed)'
    // will return consistent values from one update to the next.
    //
    // Finally, there is one global uniform values available, 'dt'. This is a floating point
    // number of seconds that have elapsed since the last update.
    //
    // Effect code should define two functions:
    //
    // 'void effectSpawn(inout Effect e)' is called when an instance of the effect is first
    // created, and again at every loop point (if the effect is played with the looping flag).
    //
    // 'void effectUpdate(inout Effect e)' is called once per update to adjust properties of the
    // effect (ie emitter).
    //
    // Particle code should also define two functions:
    //
    // 'void spawn(inout Particle p)' is called once for each particle when it is first created,
    // to set initial values. At a minimum, this should set 'lifetime' to the number of seconds
    // that the particle will exist. Other parameters will get default values from the effect.
    //
    // 'void update(inout Particle p)' is called for each particle on every call to the running
    // SkParticleEffect's update() method. It can animate any of the particle's values. Note that
    // the 'lifetime' field has a different meaning in 'update', and should not be used or changed.

    SkString fEffectCode;
    SkString fParticleCode;

    // External objects accessible by the effect's SkSL code. Each binding is a name and particular
    // kind of object. See SkParticleBinding::Make* for details.
    SkTArray<sk_sp<SkParticleBinding>> fBindings;

    void visitFields(SkFieldVisitor* v);

    // Load/compute cached resources
    void prepare(const skresources::ResourceProvider*);

private:
    friend class SkParticleEffect;

    // Cached
    struct Program {
        std::unique_ptr<SkSL::ByteCode> fByteCode;
        SkTArray<std::unique_ptr<SkParticleExternalValue>> fExternalValues;
    };

    Program fEffectProgram;
    Program fParticleProgram;
};

class SkParticleEffect : public SkRefCnt {
public:
    SkParticleEffect(sk_sp<SkParticleEffectParams> params);

    // Start playing this effect, specifying initial values for the emitter's properties
    void start(double now, bool looping, SkPoint position, SkVector heading, float scale,
               SkVector velocity, float spin, SkColor4f color, float frame, uint32_t flags,
               uint32_t seed);

    // Start playing this effect, with default values for the emitter's properties
    void start(double now, bool looping) {
        this->start(now, looping,
                    { 0.0f, 0.0f },              // position
                    { 0.0f, -1.0f },             // heading
                    1.0f,                        // scale
                    { 0.0f, 0.0f },              // velocity
                    0.0f,                        // spin
                    { 1.0f, 1.0f, 1.0f, 1.0f },  // color
                    0.0f,                        // sprite frame
                    0,                           // flags
                    0);                          // seed
    }

    void update(double now);
    void draw(SkCanvas* canvas);

    bool isAlive(bool includeSubEffects = true) const {
        return (fState.fAge >= 0 && fState.fAge <= 1)
            || (includeSubEffects && !fSubEffects.empty());
    }
    int getCount() const { return fCount; }

    float     getRate()     const { return fState.fRate;     }
    int       getBurst()    const { return fState.fBurst;    }
    SkPoint   getPosition() const { return fState.fPosition; }
    SkVector  getHeading()  const { return fState.fHeading;  }
    float     getScale()    const { return fState.fScale;    }
    SkVector  getVelocity() const { return fState.fVelocity; }
    float     getSpin()     const { return fState.fSpin;     }
    SkColor4f getColor()    const { return fState.fColor;    }
    float     getFrame()    const { return fState.fFrame;    }
    uint32_t  getFlags()    const { return fState.fFlags;    }

    void setRate    (float     r) { fState.fRate     = r; }
    void setBurst   (int       b) { fState.fBurst    = b; }
    void setPosition(SkPoint   p) { fState.fPosition = p; }
    void setHeading (SkVector  h) { fState.fHeading  = h; }
    void setScale   (float     s) { fState.fScale    = s; }
    void setVelocity(SkVector  v) { fState.fVelocity = v; }
    void setSpin    (float     s) { fState.fSpin     = s; }
    void setColor   (SkColor4f c) { fState.fColor    = c; }
    void setFrame   (float     f) { fState.fFrame    = f; }
    void setFlags   (uint32_t  f) { fState.fFlags    = f; }

    const SkSL::ByteCode* effectCode() const { return fParams->fEffectProgram.fByteCode.get(); }
    const SkSL::ByteCode* particleCode() const { return fParams->fParticleProgram.fByteCode.get(); }

    float* effectUniforms() { return fEffectUniforms.data(); }
    float* particleUniforms() { return fParticleUniforms.data(); }

    static void RegisterParticleTypes();

private:
    void setCapacity(int capacity);

    // Helpers to break down update
    void advanceTime(double now);

    void processEffectSpawnRequests(double now);
    void runEffectScript(double now, const char* entry);

    void processParticleSpawnRequests(double now, int start);
    void runParticleScript(double now, const char* entry, int start, int count);

    sk_sp<SkParticleEffectParams>        fParams;

    bool   fLooping;
    int    fCount;
    double fLastTime;
    float  fSpawnRemainder;

    // C++ version of the SkSL Effect struct. This is the inout parameter to per-effect scripts,
    // and provided as a uniform (named 'effect') to the per-particle scripts.
    struct EffectState {
        float fAge;
        float fLifetime;
        int   fLoopCount;
        float fRate;
        int   fBurst;

        // Properties that determine default values for new particles
        SkPoint   fPosition;
        SkVector  fHeading;
        float     fScale;
        SkVector  fVelocity;
        float     fSpin;
        SkColor4f fColor;
        float     fFrame;
        uint32_t  fFlags;
        uint32_t  fRandom;
    };
    EffectState fState;

    SkParticles          fParticles;
    SkAutoTMalloc<float> fStableRandoms;

    // Cached
    int fCapacity;
    SkTArray<float, true> fEffectUniforms;
    SkTArray<float, true> fParticleUniforms;

    // Private interface used by SkEffectBinding and SkEffectExternalValue to spawn sub effects
    friend class SkEffectExternalValue;
    struct SpawnRequest {
        SpawnRequest(int index, bool loop, sk_sp<SkParticleEffectParams> params)
            : fIndex(index)
            , fLoop(loop)
            , fParams(std::move(params)) {}

        int fIndex;
        bool fLoop;
        sk_sp<SkParticleEffectParams> fParams;
    };
    void addSpawnRequest(int index, bool loop, sk_sp<SkParticleEffectParams> params) {
        fSpawnRequests.emplace_back(index, loop, std::move(params));
    }
    SkTArray<SpawnRequest> fSpawnRequests;

    SkTArray<sk_sp<SkParticleEffect>> fSubEffects;
};

#endif // SkParticleEffect_DEFINED
