/*
* 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/SkColorSpace.h"
#include "include/core/SkContourMeasure.h"
#include "include/core/SkFont.h"
#include "include/core/SkImage.h"
#include "include/core/SkPath.h"
#include "include/private/base/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/SkSLBuiltinTypes.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);
        SkOverrideDeviceMatrixProvider 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, 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 {
        SkASSERT(resourceProvider);
        if (auto asset = resourceProvider->loadImageAsset(fImagePath.c_str(), fImageName.c_str(),
                                                          nullptr)) {
            SkASSERT(asset);
            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);
}
