/*
 * 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/image_sampler.hpp"
#include "rive/shapes/paint/stroke_cap.hpp"
#include "rive/shapes/paint/stroke_join.hpp"
#include "utils/lite_rtti.hpp"
#include "rive/math/raw_path.hpp"
#include <stdio.h>
#include <cstdint>

namespace rive
{
class Vec2D;

// 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);

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;)
};

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;
    virtual void feather(float value) {} // Not supported on all renderers.
    virtual void blendMode(BlendMode value) = 0;
    virtual void shader(rcp<RenderShader>) = 0;
    virtual void invalidateStroke() = 0;
};

#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.
    }

    virtual void addRawPath(const RawPath& path) = 0;
};

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;
    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;

    // 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;

    // 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
