/**
 *
 * @file src/render/Render.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 Mathieu Faverge
 * @author Thibault Soucarre
 * @author Lucas Guedon
 * @author Augustin Gauchet
 * @author Olivier Lagrasse
 *
 * @date 2024-07-17
 */
/*!
 *\file Render.hpp
 */

#ifndef RENDER_HPP
#define RENDER_HPP

#include "common/common.hpp"
#include <QWidget>
#include <QImage>

class EntityValue;

struct Container_text_;
/*template<typename T>

 class CSingleton
 {
 public:
 static T& Instance()
 {
 static T me;
 return me;
 }
 };


 */

/*!
 * \brief Structure used to store arrow information.
 */
struct Arrow_
{
    /*!
     * \brief Coordinates.
     */
    Element_pos start_time, end_time, start_height, end_height;
    /*!
     * \brief Colors.
     */
    Element_col red, green, blue;
};

/*!
 * \brief Structure used to store event information.
 */
struct Event_
{
    /*!
     * \brief Coordinates and radius.
     */
    Element_pos time, height, container_height;
    /*!
     * \brief Colors.
     */
    Element_col red, green, blue;
};

/*!
 * \brief Structure used to store event information.
 */
struct Variable_text_
{
    /*!
     * \brief Coordinates and radius.
     */
    Element_pos y;
    Element_pos value;
};

/*!
 * \brief This class provides an interface for render classes like OpenGL or SVG.
 */
class Render
{

public:
    virtual ~Render() = default;

    /*!
     * \brief Proceeds with the initialization of draw functions.
     */
    virtual void start_draw() = 0;

    /*!
     * \brief Called when all draws are finished.
     */
    virtual void end_draw() = 0;

    /*!
     * \brief Proceeds with the initialization of container draw functions.
     */
    virtual void start_draw_containers() = 0;

    /*!
     * \brief Called when all container draws are finished.
     */
    virtual void end_draw_containers() = 0;

    /*!
     * \brief Proceeds with the initialization of state draw functions.
     */
    virtual void start_draw_states() = 0;

    /*!
     * \brief Draw a state of the trace.
     * TODO: update
     * \param start the beginning time of the state.
     * \param end the ending time of the state.
     * \param base vertical position of the state.
     * \param height the state height.
     * \param r the red color rate of the state.
     * \param g the green color rate of the state.
     * \param b the blue color rate of the state.
     */
    virtual void draw_state(const Element_pos x,
                            const Element_pos y,
                            const Element_pos z,
                            const Element_pos w,
                            const Element_pos h,
                            EntityValue *v)
        = 0;

    /*!
     * \brief Called when all state draws are finished.
     */
    virtual void end_draw_states() = 0;

    /*!
     * \brief Proceeds with the initialization of arrow draw functions.
     */
    virtual void start_draw_arrows() = 0;

    /*!
     * \brief Draw an arrow.
     * \param start_time the beginning time of the arrow.
     * \param end_time the ending time of the arrow.
     * \param start_height vertical position of the begining time of the arrow.
     * \param end_height vertical position of the ending time of the arrow.
     *
     * This function stores all the information of the arrow to display it each time the render area need to be updated.
     */
    virtual void draw_arrow(const Element_pos start_time,
                            const Element_pos end_time,
                            const Element_pos start_height,
                            const Element_pos end_height,
                            const Element_col red,
                            const Element_col green,
                            const Element_col blue,
                            EntityValue *value)
        = 0;

    /*!
     * \brief Called when all arrow draws are finished.
     */
    virtual void end_draw_arrows() = 0;

    /*!
     * \brief Proceeds with the initialization of counter draw functions.
     */
    virtual void start_draw_counter() = 0;

    /*!
     * \brief Called when all counter draws are finished.
     */
    virtual void end_draw_counter() = 0;

    /*!
     \brief initialization for events draws
     */
    virtual void start_draw_events() = 0;

    /*!
     * \brief Draw an event.
     * \param time time when the event occurs.
     * \param height vertical position of the event.
     * \param container_height information to draw event. It corresponds to the
     * container height when they are drawn horizontally.
     */
    virtual void draw_event(const Element_pos time,
                            const Element_pos height,
                            const Element_pos container_height,
                            EntityValue *value)
        = 0;

    /*!
     \brief ending operations for events draws
     */
    virtual void end_draw_events() = 0;

    /*!
     * \brief Called before ruler drawing.
     */
    virtual void start_ruler() = 0;

    /*!
     * \brief Called after ruler drawing.
     */
    virtual void end_ruler() = 0;

    /*!
     * \brief Set the color for the further drawings.
     * \param r the red value. Within [0 ; 1].
     * \param g the green value. Within [0 ; 1].
     * \param b the blue value. Within [0 ; 1].
     */
    virtual void set_color(float r, float g, float b) = 0;

    /*!
     * \brief Draw a text.
     * \param x the horizontal position of the left bottom corner of the text.
     * \param y the vertical position of the left bottom corner of the text.
     * \param z the deep position of the text.
     * \param s the text.
     */
    virtual void draw_text(const Element_pos x,
                           const Element_pos y,
                           const Element_pos z,
                           const std::string &s)
        = 0;

    /*!
     * \brief Draw a text with the value of a variable
     * \param text text to draw.
     * \param y y position of the point.
     */
    virtual void draw_text_value(long int id,
                                 double text,
                                 double y)
        = 0;

    /*!
     * \brief Draw a quad.
     * \param x the horizontal position of the left bottom corner of the quad.
     * \param y the vertical position of the left bottom corner of the quad.
     * \param z the deep position of the quad.
     * \param w the width of the quad.
     * \param h the height of the quad.
     */
    virtual void draw_quad(Element_pos x,
                           Element_pos y,
                           Element_pos z,
                           Element_pos w,
                           Element_pos h)
        = 0;

    /*!
     * \brief Draw a triangle.
     * \param x the horizontal position of the triangle center.
     * \param y the vertical position of the triangle center.
     * \param size the edge size.
     * \param r the rotation of triangle. (clockwise and in degree)
     */
    virtual void draw_triangle(Element_pos x,
                               Element_pos y,
                               Element_pos size,
                               Element_pos r)
        = 0;

    /*!
     * \brief Draw a line.
     * \param x1 the horizontal position of the first point.
     * \param y1 the vertical position of the firt point.
     * \param x2 the horizontal position of the second point.
     * \param y2 the vertical position of the second point.
     * \param z the deep position of the triangle.
     */
    virtual void draw_line(Element_pos x1,
                           Element_pos y1,
                           Element_pos x2,
                           Element_pos y2,
                           Element_pos z)
        = 0;

    /*!
     * \brief Draw a circle.
     * \param x the horizontal position of the circle center.
     * \param y the vertical position of the circle center.
     * \param z the deep position of the circle.
     * \param r the circle radius.
     */
    virtual void draw_circle(Element_pos x,
                             Element_pos y,
                             Element_pos z,
                             Element_pos r)
        = 0;

    /*!
     * \brief set the vertical line offset
     * \param l the line offset.
     */
    virtual void set_vertical_line(Element_pos l) = 0;

    /*!
     * \brief draws the vertical helper line
     */

    virtual void draw_vertical_line() = 0;

    /*!
     * \brief slot connected to the simple click event
     */
    virtual void update_vertical_line() = 0;

    /*!
     * \brief Draw the ruler display list.
     */
    virtual void call_ruler() = 0;
};

#endif
