/**
 *
 * @file src/render/vulkan/Render_vulkan.hpp
 *
 * @copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @author Camille Ordronneau
 * @author Johnny Jazeix
 * @author Nolan Bredel
 * @author Lucas Guedon
 * @author Augustin Gauchet
 *
 * @date 2024-07-17
 */
#ifndef RENDER_VULKAN_HPP
#define RENDER_VULKAN_HPP

#include <vector>
#include "interface/Interface_graphic.hpp"
#include "render/Render_abstract.hpp"
#include "render/vulkan/Vulkan_window.hpp"
#include "render/vulkan/Vulkan_window_renderer.hpp"
#include <QWidget>

class Render_vulkan : public Render_abstract
{

private:
    QWidget *_container;
    Vulkan_window _window;
    Vulkan_window_renderer *_window_renderer;
    std::vector<Vertex> _container_vertices;
    std::vector<Vertex> _state_vertices;
    std::vector<Vertex> _ruler;
    std::vector<Vertex> _counters;

    Element_col _r;
    Element_col _g;
    Element_col _b;

    bool _draw_container;
    bool _draw_states;
    bool _draw_ruler;
    bool _draw_counter;

public:
    VkDeviceMemory buf_mem_vertex = VK_NULL_HANDLE;

    Render_vulkan(Interface_graphic *interface_graphic);

    void set_window_renderer(Vulkan_window_renderer *wr);

    void start_draw() override;

    void end_draw() override;

    void start_draw_containers() override;

    void end_draw_containers() override;

    void start_draw_states() override;

    void draw_state(const Element_pos,
                    const Element_pos,
                    const Element_pos,
                    const Element_pos,
                    const Element_pos,
                    EntityValue *) override;

    void end_draw_states() override;

    void start_draw_arrows() override;

    void draw_arrow(const Element_pos,
                    const Element_pos,
                    const Element_pos,
                    const Element_pos,
                    const Element_col,
                    const Element_col,
                    const Element_col,
                    EntityValue *) override;

    void end_draw_arrows() override;

    void start_draw_counter() override;

    void end_draw_counter() override;

    void start_draw_events() override;

    void draw_event(const Element_pos,
                    const Element_pos,
                    const Element_pos,
                    EntityValue *) override;

    void end_draw_events() override;

    void start_ruler() override;

    void end_ruler() override;

    /***********************************
     *
     * Displaying functions.
     *
     **********************************/

    void set_color(float r, float g, float b) override;

    void draw_text(const Element_pos x,
                   const Element_pos y,
                   const Element_pos z,
                   const std::string &s) override;

    void draw_text_value(long int id,
                         double text,
                         double y) override;

    void draw_quad(Element_pos x,
                   Element_pos y,
                   Element_pos z,
                   Element_pos w,
                   Element_pos h) override;

    void draw_triangle(Element_pos x,
                       Element_pos y,
                       Element_pos size,
                       Element_pos r) override;

    void draw_line(Element_pos x1,
                   Element_pos y1,
                   Element_pos x2,
                   Element_pos y2,
                   Element_pos z) override;

    void draw_circle(Element_pos x,
                     Element_pos y,
                     Element_pos z,
                     Element_pos r) override;

    void set_vertical_line(Element_pos l) override;

    void draw_vertical_line() override;

    void call_ruler() override;

    void update_vertical_line() override;

    /**
     * \brief Get the widget associated to the renderer to display in the window
     * @return
     */
    QWidget *get_render_widget() override;

    /**
     * Get the last frame displayed and save it on a QT image
     * @return
     */
    QImage grab_frame_buffer() override;

    /*!
     * \brief This function draws the trace.
     */
    bool build() override;

    /*!
     * \brief This function releases the trace.
     */
    bool unbuild() override;

    void release() override;

    void show_minimap() override;

    /**
     * \brief Updates the widget
     */
    void update_render() override;
};

#endif
