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

#include "include/core/SkContourMeasure.h"
#include "include/core/SkImage.h"
#include "include/core/SkPath.h"
#include "include/private/SkTPin.h"
#include "include/utils/SkParsePath.h"
#include "include/utils/SkTextUtils.h"
#include "modules/particles/include/SkReflected.h"
#include "modules/skresources/include/SkResources.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkVM.h"
#include "src/shaders/SkShaderBase.h"
#include "src/sksl/SkSLCompiler.h"

void SkParticleBinding::visitFields(SkFieldVisitor* v) {
    v->visit("Name", fName);
}

namespace {
    struct PosNrm { SkPoint pos; SkVector nrm; };
    using LinearizedPath = std::vector<PosNrm>;
}  // namespace

static LinearizedPath linearize_path(const SkPath& path) {
    LinearizedPath lin;
    SkContourMeasureIter iter(path, false);
    while (auto contour = iter.next()) {
        for (SkScalar x = 0; x < contour->length(); x++) {
            SkPoint pos;
            SkVector tan;
            SkAssertResult(contour->getPosTan(x, &pos, &tan));
            lin.push_back({pos, {tan.fY, -tan.fX}});
        }
    }
    return lin;
}

// Exposes an SkPath as an external, callable function. p(x) returns a float4 { pos.xy, normal.xy }
class SkPathExternalFunction : public SkParticleExternalFunction {
public:
    SkPathExternalFunction(const char* name,
                           SkSL::Compiler& compiler,
                           const LinearizedPath& path,
                           skvm::Uniforms* uniforms,
                           SkArenaAlloc* alloc)
            : SkParticleExternalFunction(
                      name, compiler, *compiler.context().fTypes.fFloat4, uniforms, alloc)
            , fPath(path) {}

    int callParameterCount() const override { return 1; }
    void getCallParameterTypes(const SkSL::Type** outTypes) const override {
        outTypes[0] = fCompiler.context().fTypes.fFloat.get();
    }

    void call(skvm::Builder* builder,
              skvm::F32* arguments,
              skvm::F32* outResult,
              skvm::I32 mask) const override {
        if (fPath.empty()) {
            return;
        }

        skvm::Uniform ptr = fUniforms->pushPtr(fPath.data());
        skvm::I32 index = trunc(clamp(arguments[0] * fPath.size(), 0, fPath.size() - 1));

        outResult[0] = builder->gatherF(ptr, (index<<2)+0);
        outResult[1] = builder->gatherF(ptr, (index<<2)+1);
        outResult[2] = builder->gatherF(ptr, (index<<2)+2);
        outResult[3] = builder->gatherF(ptr, (index<<2)+3);
    }

private:
    const LinearizedPath& fPath;
};

class SkPathBinding : public SkParticleBinding {
public:
    SkPathBinding(const char* name = "", const char* pathPath = "", const char* pathName = "")
            : SkParticleBinding(name)
            , fPathPath(pathPath)
            , fPathName(pathName) {}

    REFLECTED(SkPathBinding, SkParticleBinding)

    void visitFields(SkFieldVisitor* v) override {
        SkParticleBinding::visitFields(v);
        v->visit("PathPath", fPathPath);
        v->visit("PathName", fPathName);
    }

    std::unique_ptr<SkParticleExternalFunction> toFunction(SkSL::Compiler& compiler,
                                                           skvm::Uniforms* uniforms,
                                                           SkArenaAlloc* alloc) override {
        return std::make_unique<SkPathExternalFunction>(fName.c_str(), compiler, fData, uniforms,
                                                        alloc);
    }

    void prepare(const skresources::ResourceProvider* resourceProvider) override {
        if (auto pathData = resourceProvider->load(fPathPath.c_str(), fPathName.c_str())) {
            SkPath path;
            if (0 != path.readFromMemory(pathData->data(), pathData->size())) {
                fData = linearize_path(path);
            }
        }
    }

private:
    SkString fPathPath;
    SkString fPathName;

    // Cached
    LinearizedPath fData;
};

class SkTextBinding : public SkParticleBinding {
public:
    SkTextBinding(const char* name = "", const char* text = "", SkScalar fontSize = 96)
            : SkParticleBinding(name)
            , fText(text)
            , fFontSize(fontSize) {}

    REFLECTED(SkTextBinding, SkParticleBinding)

    void visitFields(SkFieldVisitor* v) override {
        SkParticleBinding::visitFields(v);
        v->visit("Text", fText);
        v->visit("FontSize", fFontSize);
    }

    std::unique_ptr<SkParticleExternalFunction> toFunction(SkSL::Compiler& compiler,
                                                           skvm::Uniforms* uniforms,
                                                           SkArenaAlloc* alloc) override {
        return std::make_unique<SkPathExternalFunction>(fName.c_str(), compiler, fData, uniforms,
                                                        alloc);
    }

    void prepare(const skresources::ResourceProvider*) override {
        if (fText.isEmpty()) {
            return;
        }

        SkFont font(nullptr, fFontSize);
        SkPath path;
        SkTextUtils::GetPath(fText.c_str(), fText.size(), SkTextEncoding::kUTF8, 0, 0, font, &path);
        fData = linearize_path(path);
    }

private:
    SkString fText;
    SkScalar fFontSize;

    // Cached
    LinearizedPath fData;
};

// Exposes an SkShader as an external, callable function. p(xy) returns a float4
class SkShaderExternalFunction : public SkParticleExternalFunction {
public:
    SkShaderExternalFunction(const char* name,
                             SkSL::Compiler& compiler,
                             sk_sp<SkShader> shader,
                             skvm::Uniforms* uniforms,
                             SkArenaAlloc* alloc)
            : SkParticleExternalFunction(
                      name, compiler, *compiler.context().fTypes.fFloat4, uniforms, alloc)
            , fShader(std::move(shader)) {}

    int callParameterCount() const override { return 1; }
    void getCallParameterTypes(const SkSL::Type** outTypes) const override {
        outTypes[0] = fCompiler.context().fTypes.fFloat2.get();
    }

    void call(skvm::Builder* builder,
              skvm::F32* arguments,
              skvm::F32* outResult,
              skvm::I32 mask) const override {
        skvm::Coord coord = {arguments[0], arguments[1]};
        skvm::F32 zero = builder->splat(0.0f);
        SkSimpleMatrixProvider matrixProvider(SkMatrix::I());
        SkColorInfo colorInfo(kRGBA_8888_SkColorType, kPremul_SkAlphaType, /*cs=*/nullptr);

        skvm::Color result = as_SB(fShader)->program(
                builder, /*device=*/coord, /*local=*/coord, /*paint=*/{zero, zero, zero, zero},
                matrixProvider, /*localM=*/nullptr, kLow_SkFilterQuality, colorInfo, fUniforms,
                fAlloc);
        SkASSERT(result);
        outResult[0] = result.r;
        outResult[1] = result.g;
        outResult[2] = result.b;
        outResult[3] = result.a;
    }

private:
    sk_sp<SkShader> fShader;
};

class SkImageBinding : public SkParticleBinding {
public:
    SkImageBinding(const char* name = "", const char* imagePath = "", const char* imageName = "")
            : SkParticleBinding(name)
            , fImagePath(imagePath)
            , fImageName(imageName) {}

    REFLECTED(SkImageBinding, SkParticleBinding)

    void visitFields(SkFieldVisitor* v) override {
        SkParticleBinding::visitFields(v);
        v->visit("ImagePath", fImagePath);
        v->visit("ImageName", fImageName);
    }

    std::unique_ptr<SkParticleExternalFunction> toFunction(SkSL::Compiler& compiler,
                                                           skvm::Uniforms* uniforms,
                                                           SkArenaAlloc* alloc) override {
        return std::make_unique<SkShaderExternalFunction>(fName.c_str(), compiler, fShader,
                                                          uniforms, alloc);
    }

    void prepare(const skresources::ResourceProvider* resourceProvider) override {
        if (auto asset = resourceProvider->loadImageAsset(fImagePath.c_str(), fImageName.c_str(),
                                                          nullptr)) {
            if (auto image = asset->getFrame(0)) {
                SkMatrix normalize = SkMatrix::Scale(1.0f / image->width(), 1.0f / image->height());
                fShader = image->makeShader(SkSamplingOptions(SkFilterMode::kLinear), &normalize);
                return;
            }
        }

        fShader = SkShaders::Color(SK_ColorWHITE);
    }

private:
    SkString fImagePath;
    SkString fImageName;

    // Cached
    sk_sp<SkShader> fShader;
};

sk_sp<SkParticleBinding> SkParticleBinding::MakeImage(const char* name, const char* imagePath,
                                                      const char* imageName) {
    return sk_sp<SkParticleBinding>(new SkImageBinding(name, imagePath, imageName));
}

sk_sp<SkParticleBinding> SkParticleBinding::MakePath(const char* name, const char* pathPath,
                                                     const char* pathName) {
    return sk_sp<SkParticleBinding>(new SkPathBinding(name, pathPath, pathName));
}

void SkParticleBinding::RegisterBindingTypes() {
    REGISTER_REFLECTED(SkParticleBinding);
    REGISTER_REFLECTED(SkImageBinding);
    REGISTER_REFLECTED(SkPathBinding);
    REGISTER_REFLECTED(SkTextBinding);
}
