/*
 * Copyright 2022 Rive
 */

#ifndef _RIVE_RENDERER_HPP_
#define _RIVE_RENDERER_HPP_

#include "rive/enums.hpp"
#include "rive/shapes/paint/color.hpp"
#include "rive/command_path.hpp"
#include "rive/layout.hpp"
#include "rive/refcnt.hpp"
#include "rive/math/aabb.hpp"
#include "rive/math/mat2d.hpp"
#include "rive/shapes/paint/blend_mode.hpp"
#include "rive/shapes/paint/layer_mask_mode.hpp"
#include "rive/shapes/paint/image_sampler.hpp"
#include "rive/shapes/paint/stroke_cap.hpp"
#include "rive/shapes/paint/stroke_join.hpp"
#include "rive/shapes/paint/stroke_position.hpp"
#include "utils/lite_rtti.hpp"
#include "rive/math/raw_path.hpp"
#include "rive/span.hpp"
#include <stdio.h>
#include <cstdint>
#include <vector>

namespace rive
{
class Vec2D;
class RenderImage;

// Helper that computes a matrix to "align" content (source) to fit inside frame
// (destination).
Mat2D computeAlignment(Fit,
                       Alignment,
                       const AABB& frame,
                       const AABB& content,
                       const float scaleFactor = 1.0f);

// Common parameters to describe a path's stroke.
struct StrokeParams
{
    float thickness = 1.0f;
    StrokeJoin join = StrokeJoin::miter;
    StrokeCap cap = StrokeCap::butt;
    StrokePosition position = StrokePosition::center;

    bool operator==(const StrokeParams& other) const
    {
        return memcmp(this, &other, sizeof(StrokeParams)) == 0;
    }

    bool operator!=(const StrokeParams& other) const
    {
        return !(*this == other);
    }
};

enum class RenderBufferType
{
    index,
    vertex,
};

enum class RenderBufferFlags
{
    none = 0,
    mappedOnceAtInitialization =
        1 << 0, // The client will map the buffer exactly one time, before
                // rendering, and will never update it again.
};

class RenderBuffer : public RefCnt<RenderBuffer>,
                     public ENABLE_LITE_RTTI(RenderBuffer)
{
public:
    RenderBuffer(RenderBufferType, RenderBufferFlags, size_t sizeInBytes);
    virtual ~RenderBuffer();

    RenderBufferType type() const { return m_type; }
    RenderBufferFlags flags() const { return m_flags; }
    size_t sizeInBytes() const { return m_sizeInBytes; }

    void* map();
    void unmap();

protected:
    virtual void* onMap() = 0;
    virtual void onUnmap() = 0;

    // Unset the dirty flag, and return whether it had been set.
    bool checkAndResetDirty()
    {
        assert(m_mapCount == m_unmapCount); // Don't call this while mapped.
        if (m_dirty)
        {
            m_dirty = false;
            return true;
        }
        return false;
    }

private:
    const RenderBufferType m_type;
    const RenderBufferFlags m_flags;
    const size_t m_sizeInBytes;
    bool m_dirty = false;
    RIVE_DEBUG_CODE(size_t m_mapCount = 0;)
    RIVE_DEBUG_CODE(size_t m_unmapCount = 0;)
};

struct ImageMeshInstanceData
{
    Mat2D transform;
    Vec2D uvTranslate = {0.0f, 0.0f};
    Vec2D uvScale = {1.0f, 1.0f};
    float opacity = 1.0f;
    float additiveness = 0.0f;
};

class ImageMeshInstances : public RefCnt<ImageMeshInstances>,
                           public ENABLE_LITE_RTTI(ImageMeshInstances)
{
public:
    ImageMeshInstances(size_t count);
    virtual ~ImageMeshInstances();

    size_t count() const { return m_instanceData.size(); }

    Span<const ImageMeshInstanceData> instanceData() const
    {
        return m_instanceData;
    }

    // These functions are used to begin/end editing of the instance data.
    // Instance data is retained across edits so the entire array doesn't need
    // to be rewritten each edit.
    Span<ImageMeshInstanceData> edit();

    // Sets the number of instances to `count`. Existing elements retain their
    // previous data.
    Span<ImageMeshInstanceData> edit(size_t count);

    void endEdit();

#ifdef DEBUG
    bool isEditing() const { return m_editCount != m_endEditCount; }
    size_t editCount() const { return m_editCount; }
#endif

protected:
    virtual void onEndEdit() {}

private:
    std::vector<ImageMeshInstanceData> m_instanceData;
    RIVE_DEBUG_CODE(size_t m_editCount = 0;)
    RIVE_DEBUG_CODE(size_t m_endEditCount = 0;)
};

enum class RenderPaintStyle
{
    stroke,
    fill
};

/*
 *  Base class for Render objects that specify the src colors.
 *
 *  Shaders are immutable, and sharable between multiple paints, etc.
 *
 *  It is common that a shader may be created with a 'localMatrix'. If this is
 *  not null, then it is applied to the shader's domain before the Renderer's
 * CTM.
 */
class RenderShader : public RefCnt<RenderShader>,
                     public ENABLE_LITE_RTTI(RenderShader)
{
public:
    RenderShader();
    virtual ~RenderShader();
};

class RenderPaint : public RefCnt<RenderPaint>,
                    public ENABLE_LITE_RTTI(RenderPaint)
{
public:
    RenderPaint();
    virtual ~RenderPaint();

    virtual void style(RenderPaintStyle style) = 0;
    virtual void color(ColorInt value) = 0;
    virtual void thickness(float value) = 0;
    virtual void join(StrokeJoin value) = 0;
    virtual void cap(StrokeCap value) = 0;
    // TODO: implement on other backends besides Rive Renderer
    virtual void strokePosition(StrokePosition value) {}
    virtual void feather(float value) {}      // Not supported on all renderers.
    virtual void additiveness(float value) {} // Only used for srcOver
    virtual void blendMode(BlendMode value) = 0;
    virtual void shader(rcp<RenderShader>) = 0;
    virtual void invalidateStroke() = 0;
    virtual void modulatedImage(const RenderImage*, ImageSampler, const Mat2D&)
    {} // TODO: Implement on other backends besides Rive Renderer

    // Set the style to stroke and update all of the stroke parameters with a
    // single update.
    void stroke(const StrokeParams& params)
    {
        style(RenderPaintStyle::stroke);
        thickness(params.thickness);
        join(params.join);
        cap(params.cap);
        strokePosition(params.position);
    }
};

#if defined(__EMSCRIPTEN__)
class RenderImageDelegate
{
public:
    virtual void decodedAsync() = 0;
};
#endif

class RenderImage : public RefCnt<RenderImage>,
                    public ENABLE_LITE_RTTI(RenderImage)
{
protected:
    int m_Width = 0;
    int m_Height = 0;
    Mat2D m_uvTransform;

public:
    RenderImage();
    RenderImage(const Mat2D& uvTransform);
    virtual ~RenderImage();

    int width() const { return m_Width; }
    int height() const { return m_Height; }
    const Mat2D& uvTransform() const { return m_uvTransform; }

#if defined(__EMSCRIPTEN__)
    void delegate(RenderImageDelegate* delegate) { m_delegate = delegate; }
    void decodedAsync() const
    {
        if (m_delegate != nullptr)
        {
            m_delegate->decodedAsync();
        }
    }

private:
    RenderImageDelegate* m_delegate = nullptr;
#endif
};

class RenderPath : public CommandPath, public ENABLE_LITE_RTTI(RenderPath)
{
public:
    RenderPath();
    ~RenderPath() override;

    RenderPath* renderPath() override { return this; }
    const RenderPath* renderPath() const override { return this; }

    void addPath(CommandPath* path, const Mat2D& transform) override
    {
        addRenderPath(path->renderPath(), transform);
    }

    void addPathBackwards(CommandPath* path, const Mat2D& transform)
    {
        addRenderPath(path->renderPath(), transform);
    }

    virtual void addRenderPath(const RenderPath* path,
                               const Mat2D& transform) = 0;
    virtual void addRenderPathBackwards(const RenderPath* path,
                                        const Mat2D& transform)
    {
        // No-op on non rive renderer.
    }

    // The caller is expected to provide a valid path with no zero length
    // segments.
    virtual void addRawPath(const RawPath& path) = 0;

    // Same, but prunes zero length segments first, for paths we did not build
    // like scripted ones.
    void addUntrustedRawPath(const RawPath& path);
};

class Renderer
{
public:
    virtual ~Renderer() {}
    virtual void save() = 0;
    virtual void restore() = 0;
    virtual void transform(const Mat2D& transform) = 0;
    virtual void drawPath(RenderPath* path, RenderPaint* paint) = 0;
    virtual void clipPath(RenderPath* path) = 0;

    // Not implementable on some backends so default to nothing
    virtual void clipStroke(RenderPath*, const StrokeParams&) {}

    virtual void drawImage(const RenderImage*,
                           ImageSampler,
                           BlendMode,
                           float opacity) = 0;
    virtual void drawImageMesh(const RenderImage*,
                               ImageSampler,
                               rcp<RenderBuffer> vertices_f32,
                               rcp<RenderBuffer> uvCoords_f32,
                               rcp<RenderBuffer> indices_u16,
                               uint32_t vertexCount,
                               uint32_t indexCount,
                               BlendMode,
                               float opacity) = 0;

    // Variants with additiveness (0 = normal srcOver, 1 = fully additive).
    // Renderers that don't support it fall back on the plain overloads and
    // render normal srcOver.
    virtual void drawImage(const RenderImage* image,
                           ImageSampler sampler,
                           BlendMode blendMode,
                           float opacity,
                           float additiveness)
    {
        drawImage(image, sampler, blendMode, opacity);
    }
    virtual void drawImageMesh(const RenderImage* image,
                               ImageSampler sampler,
                               rcp<RenderBuffer> vertices_f32,
                               rcp<RenderBuffer> uvCoords_f32,
                               rcp<RenderBuffer> indices_u16,
                               uint32_t vertexCount,
                               uint32_t indexCount,
                               BlendMode blendMode,
                               float opacity,
                               float additiveness)
    {
        drawImageMesh(image,
                      sampler,
                      std::move(vertices_f32),
                      std::move(uvCoords_f32),
                      std::move(indices_u16),
                      vertexCount,
                      indexCount,
                      blendMode,
                      opacity);
    }

    // Draws the same mesh once per entry in `instances`. This is more efficient
    // than making N drawImageMesh calls, but blend modes are not supported.
    //
    // TODO(ben) the default implementation issues one drawImageMesh per
    // instance, and drawImageMesh does not support UV transforms, so non-Rive
    // renderers don't yet support UV transforms.
    virtual void drawImageMeshInstanced(const RenderImage*,
                                        ImageSampler,
                                        rcp<RenderBuffer> vertices_f32,
                                        rcp<RenderBuffer> uvCoords_f32,
                                        rcp<RenderBuffer> indices_u16,
                                        uint32_t vertexCount,
                                        uint32_t indexCount,
                                        rcp<ImageMeshInstances>);

    // Multiplies everything already drawn into the current render target by a
    // factor derived from `mask`, over the rect [0,0,1,1] under the current
    // transform. Premultiplied-correct: all four channels scale, so this is
    // exactly "scale the layer's opacity, per pixel".
    //
    // Must be the last draw issued into the target before it is composited, and
    // `mask` must be the same pixel size as that target -- layer masking
    // rasterizes content and coverage with one shared raster plan precisely so
    // the two correspond texel for texel with no resampling.
    //
    // Luminance is computed on the *premultiplied* mask, which is not an
    // approximation: luma(rgb/a) * a == dot(rgb, coeffs) identically for a > 0,
    // and it stays correct at a == 0 where unmultiplying would be 0/0.
    //
    // Default no-op, so a renderer that cannot express it leaves the layer
    // unmasked -- visible, but not destructive.
    virtual void applyLayerMask(const RenderImage*, ImageSampler, LayerMaskMode)
    {}

    // Modulate the opacity of subsequent draw calls. The opacity is stacked
    // multiplicatively (e.g., modulateOpacity(0.5) followed by
    // modulateOpacity(0.2) = 0.1 effective opacity). The modulated opacity is
    // captured by save() and restored by restore().
    virtual void modulateOpacity(float opacity) = 0;

    // Multiply a color into subsequent draw calls, scoped by save() and
    // restore() like modulateOpacity. With replace the color is set rather
    // than multiplied, so an inner scope can undo an outer one.
    virtual void modulateColor(ColorInt color, bool replace = false) {}

    // Reports the renderer's current transform (CTM) into *out, if the
    // renderer tracks one. Returns false and leaves *out untouched otherwise.
    // Needed when a draw has to be re-issued through a different renderer that
    // does not share this one's state.
    virtual bool currentTransform(Mat2D* out) const { return false; }

    // Reports the opacity accumulated by modulateOpacity() into *out, if the
    // renderer tracks it. Returns false and leaves *out untouched otherwise.
    // The companion to currentTransform(): a draw re-issued through a fresh
    // renderer starts at opacity 1, so an enclosing modulateOpacity() scope
    // (a ScriptedDrawable fading its children, say) has to be carried across
    // by hand or the re-issued draw comes out too opaque.
    virtual bool currentModulatedOpacity(float* out) const { return false; }

    // helpers

    void translate(float x, float y);
    void scale(float sx, float sy);
    void rotate(float radians);

    void align(Fit fit,
               Alignment alignment,
               const AABB& frame,
               const AABB& content,
               const float scaleFactor = 1.0f)
    {
        transform(
            computeAlignment(fit, alignment, frame, content, scaleFactor));
    }
};
} // namespace rive
#endif
