/*
 ** This file is part of the ViTE project.
 **
 ** This software is governed by the CeCILL-A license under French law
 ** and abiding by the rules of distribution of free software. You can
 ** use, modify and/or redistribute the software under the terms of the
 ** CeCILL-A license as circulated by CEA, CNRS and INRIA at the following
 ** URL: "http://www.cecill.info".
 **
 ** As a counterpart to the access to the source code and rights to copy,
 ** modify and redistribute granted by the license, users are provided
 ** only with a limited warranty and the software's author, the holder of
 ** the economic rights, and the successive licensors have only limited
 ** liability.
 **
 ** In this respect, the user's attention is drawn to the risks associated
 ** with loading, using, modifying and/or developing or reproducing the
 ** software by the user in light of its specific status of free software,
 ** that may mean that it is complicated to manipulate, and that also
 ** therefore means that it is reserved for developers and experienced
 ** professionals having in-depth computer knowledge. Users are therefore
 ** encouraged to load and test the software's suitability as regards
 ** their requirements in conditions enabling the security of their
 ** systems and/or data to be ensured and, more generally, to use and
 ** operate it in the same conditions as regards security.
 **
 ** The fact that you are presently reading this means that you have had
 ** knowledge of the CeCILL-A license and that you accept its terms.
 **
 **
 ** ViTE developers are (for version 0.* to 1.0):
 **
 **        - COULOMB Kevin
 **        - FAVERGE Mathieu
 **        - JAZEIX Johnny
 **        - LAGRASSE Olivier
 **        - MARCOUEILLE Jule
 **        - NOISETTE Pascal
 **        - REDONDY Arthur
 **        - VUCHENER Clément
 **
 */
/*!
 *\file Render.hpp
 */

#ifndef RENDER_HPP
#define RENDER_HPP

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:

    /*!
     * \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
