/*
* 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 "SkParticleEffect.h"

#include "Resources.h"
#include "SkAnimTimer.h"
#include "SkCanvas.h"
#include "SkColorData.h"
#include "SkPaint.h"
#include "SkParticleAffector.h"
#include "SkParticleDrawable.h"
#include "SkReflected.h"
#include "SkRSXform.h"

void SkParticleEffectParams::visitFields(SkFieldVisitor* v) {
    v->visit("MaxCount", fMaxCount);
    v->visit("Duration", fEffectDuration);
    v->visit("Rate", fRate);
    v->visit("Life", fLifetime);

    v->visit("Drawable", fDrawable);

    v->visit("Spawn", fSpawnAffectors);
    v->visit("Update", fUpdateAffectors);
}

SkParticleEffect::SkParticleEffect(sk_sp<SkParticleEffectParams> params, const SkRandom& random)
        : fParams(std::move(params))
        , fRandom(random)
        , fLooping(false)
        , fSpawnTime(-1.0)
        , fCount(0)
        , fLastTime(-1.0)
        , fSpawnRemainder(0.0f) {
    this->setCapacity(fParams->fMaxCount);
}

void SkParticleEffect::start(const SkAnimTimer& timer, bool looping) {
    fCount = 0;
    fLastTime = fSpawnTime = timer.secs();
    fSpawnRemainder = 0.0f;
    fLooping = looping;
}

void SkParticleEffect::update(const SkAnimTimer& timer) {
    if (!timer.isRunning() || !this->isAlive() || !fParams->fDrawable) {
        return;
    }

    double now = timer.secs();
    float deltaTime = static_cast<float>(now - fLastTime);
    if (deltaTime < 0.0f) {
        return;
    }
    fLastTime = now;

    // Handle user edits to fMaxCount
    if (fParams->fMaxCount != fCapacity) {
        this->setCapacity(fParams->fMaxCount);
    }

    float effectAge = static_cast<float>((now - fSpawnTime) / fParams->fEffectDuration);
    effectAge = fLooping ? fmodf(effectAge, 1.0f) : SkTPin(effectAge, 0.0f, 1.0f);

    SkParticleUpdateParams updateParams;
    updateParams.fDeltaTime = deltaTime;
    updateParams.fEffectAge = effectAge;

    // During spawn, values that refer to kAge_Source get the *effect* age
    updateParams.fAgeSource = SkParticleValue::kEffectAge_Source;

    // Advance age for existing particles, and remove any that have reached their end of life
    for (int i = 0; i < fCount; ++i) {
        fParticles[i].fAge += fParticles[i].fInvLifetime * deltaTime;
        if (fParticles[i].fAge > 1.0f) {
            // NOTE: This is fast, but doesn't preserve drawing order. Could be a problem...
            fParticles[i]     = fParticles[fCount - 1];
            fStableRandoms[i] = fStableRandoms[fCount - 1];
            --i;
            --fCount;
        }
    }

    // Spawn new particles
    float desired = fParams->fRate * deltaTime + fSpawnRemainder;
    int numToSpawn = sk_float_round2int(desired);
    fSpawnRemainder = desired - numToSpawn;
    numToSpawn = SkTPin(numToSpawn, 0, fParams->fMaxCount - fCount);
    if (numToSpawn) {
        const int spawnBase = fCount;

        for (int i = 0; i < numToSpawn; ++i) {
            // Mutate our SkRandom so each particle definitely gets a different stable generator
            fRandom.nextU();
            fParticles[fCount].fAge = 0.0f;
            fParticles[fCount].fPose.fPosition = { 0.0f, 0.0f };
            fParticles[fCount].fPose.fHeading = { 0.0f, -1.0f };
            fParticles[fCount].fPose.fScale = 1.0f;
            fParticles[fCount].fVelocity.fLinear = { 0.0f, 0.0f };
            fParticles[fCount].fVelocity.fAngular = 0.0f;
            fParticles[fCount].fColor = { 1.0f, 1.0f, 1.0f, 1.0f };
            fParticles[fCount].fFrame = 0.0f;
            fParticles[fCount].fRandom = fStableRandoms[fCount] = fRandom;
            fCount++;
        }

        // Apply spawn affectors
        for (auto affector : fParams->fSpawnAffectors) {
            if (affector) {
                affector->apply(updateParams, fParticles + spawnBase, numToSpawn);
            }
        }

        // Now compute particle lifetimes (so the curve can refer to spawn-computed source values)
        for (int i = spawnBase; i < fCount; ++i) {
            fParticles[i].fInvLifetime =
                sk_ieee_float_divide(1.0f, fParams->fLifetime.eval(updateParams, fParticles[i]));
        }
    }

    // Restore all stable random generators so update affectors get consistent behavior each frame
    for (int i = 0; i < fCount; ++i) {
        fParticles[i].fRandom = fStableRandoms[i];
    }

    // During update, values that refer to kAge_Source get the *particle* age
    updateParams.fAgeSource = SkParticleValue::kParticleAge_Source;

    // Apply update rules
    for (auto affector : fParams->fUpdateAffectors) {
        if (affector) {
            affector->apply(updateParams, fParticles, fCount);
        }
    }

    // Do fixed-function update work (integration of position and orientation)
    for (int i = 0; i < fCount; ++i) {
        fParticles[i].fPose.fPosition += fParticles[i].fVelocity.fLinear * deltaTime;

        SkScalar c, s = SkScalarSinCos(fParticles[i].fVelocity.fAngular * deltaTime, &c);
        SkVector oldHeading = fParticles[i].fPose.fHeading;
        fParticles[i].fPose.fHeading = { oldHeading.fX * c - oldHeading.fY * s,
                                         oldHeading.fX * s + oldHeading.fY * c };
    }

    // Mark effect as dead if we've reached the end (and are not looping)
    if (!fLooping && (now - fSpawnTime) > fParams->fEffectDuration) {
        fSpawnTime = -1.0;
    }
}

void SkParticleEffect::draw(SkCanvas* canvas) {
    if (this->isAlive() && fParams->fDrawable) {
        SkPaint paint;
        paint.setFilterQuality(SkFilterQuality::kMedium_SkFilterQuality);
        fParams->fDrawable->draw(canvas, fParticles.get(), fCount, &paint);
    }
}

void SkParticleEffect::setCapacity(int capacity) {
    fParticles.realloc(capacity);
    fStableRandoms.realloc(capacity);

    fCapacity = capacity;
    fCount = SkTMin(fCount, fCapacity);
}

constexpr SkFieldVisitor::EnumStringMapping gValueSourceMapping[] = {
    { SkParticleValue::kAge_Source,          "Age" },
    { SkParticleValue::kRandom_Source,       "Random" },
    { SkParticleValue::kParticleAge_Source,  "ParticleAge" },
    { SkParticleValue::kEffectAge_Source,    "EffectAge" },
    { SkParticleValue::kPositionX_Source,    "PositionX" },
    { SkParticleValue::kPositionY_Source,    "PositionY" },
    { SkParticleValue::kHeadingX_Source,     "HeadingX" },
    { SkParticleValue::kHeadingY_Source,     "HeadingY" },
    { SkParticleValue::kScale_Source,        "Scale" },
    { SkParticleValue::kVelocityX_Source,    "VelocityX" },
    { SkParticleValue::kVelocityY_Source,    "VelocityY" },
    { SkParticleValue::kRotation_Source,     "Rotation" },
    { SkParticleValue::kColorR_Source,       "ColorR" },
    { SkParticleValue::kColorG_Source,       "ColorG" },
    { SkParticleValue::kColorB_Source,       "ColorB" },
    { SkParticleValue::kColorA_Source,       "ColorA" },
    { SkParticleValue::kSpriteFrame_Source,  "SpriteFrame" },
};

constexpr SkFieldVisitor::EnumStringMapping gValueTileModeMapping[] = {
    { SkParticleValue::kClamp_TileMode,  "Clamp" },
    { SkParticleValue::kRepeat_TileMode, "Repeat" },
    { SkParticleValue::kMirror_TileMode, "Mirror" },
};

static bool source_needs_frame(int source) {
    switch (source) {
        case SkParticleValue::kHeadingX_Source:
        case SkParticleValue::kHeadingY_Source:
        case SkParticleValue::kVelocityX_Source:
        case SkParticleValue::kVelocityY_Source:
            return true;
        default:
            return false;
    }
}

void SkParticleValue::visitFields(SkFieldVisitor* v) {
    v->visit("Source", fSource, gValueSourceMapping, SK_ARRAY_COUNT(gValueSourceMapping));
    if (source_needs_frame(fSource)) {
        v->visit("Frame", fFrame, gParticleFrameMapping, SK_ARRAY_COUNT(gParticleFrameMapping));
    }
    v->visit("TileMode", fTileMode, gValueTileModeMapping, SK_ARRAY_COUNT(gValueTileModeMapping));
    v->visit("Left", fLeft);
    v->visit("Right", fRight);

    // Re-compute cached evaluation parameters
    fScale = sk_float_isfinite(1.0f / (fRight - fLeft)) ? 1.0f / (fRight - fLeft) : 0;
    fBias = -fLeft * fScale;
}

float SkParticleValue::getSourceValue(const SkParticleUpdateParams& params,
                                      SkParticleState& ps) const {
    switch ((kAge_Source == fSource) ? params.fAgeSource : fSource) {
        // Do all the simple (non-frame-dependent) sources first:
        case kRandom_Source:      return ps.fRandom.nextF();
        case kParticleAge_Source: return ps.fAge;
        case kEffectAge_Source:   return params.fEffectAge;

        case kPositionX_Source:   return ps.fPose.fPosition.fX;
        case kPositionY_Source:   return ps.fPose.fPosition.fY;
        case kScale_Source:       return ps.fPose.fScale;
        case kRotation_Source:    return ps.fVelocity.fAngular;

        case kColorR_Source:      return ps.fColor.fR;
        case kColorG_Source:      return ps.fColor.fG;
        case kColorB_Source:      return ps.fColor.fB;
        case kColorA_Source:      return ps.fColor.fA;
        case kSpriteFrame_Source: return ps.fFrame;
    }

    SkASSERT(source_needs_frame(fSource));
    SkVector frameUp = ps.getFrameHeading(static_cast<SkParticleFrame>(fFrame));
    SkVector frameRight = { -frameUp.fY, frameUp.fX };

    switch (fSource) {
        case kHeadingX_Source:  return ps.fPose.fHeading.dot(frameRight);
        case kHeadingY_Source:  return ps.fPose.fHeading.dot(frameUp);
        case kVelocityX_Source: return ps.fVelocity.fLinear.dot(frameRight);
        case kVelocityY_Source: return ps.fVelocity.fLinear.dot(frameUp);
    }

    SkDEBUGFAIL("Unreachable");
    return 0.0f;
}

float SkParticleValue::eval(const SkParticleUpdateParams& params, SkParticleState& ps) const {
    float v = this->getSourceValue(params, ps);
    v = (v * fScale) + fBias;

    switch (fTileMode) {
        case kClamp_TileMode:
            v = SkTPin(v, 0.0f, 1.0f);
            break;
        case kRepeat_TileMode:
            v = sk_float_mod(v, 1.0f);
            if (v < 0) {
                v += 1.0f;
            }
            break;
        case kMirror_TileMode:
            v = sk_float_mod(v, 2.0f);
            if (v < 0) {
                v += 2.0f;
            }
            v = 1.0f - sk_float_abs(v - 1.0f);
            break;
    }

    return v;
}
