/**
 *
 * @file src/render/Render_abstract.hpp
 *
 * @copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @author Camille Ordronneau
 * @author Johnny Jazeix
 * @author Lucas Guedon
 *
 * @date 2024-07-17
 */

#ifndef RENDER_ABSTRACT_HPP
#define RENDER_ABSTRACT_HPP
#include "render/Geometry.hpp"
#include "render/Render_windowed.hpp"
#include "render/RenderLayout.hpp"
#include "core/Core.hpp"

/*!
 * \brief This class redefined the OpenGL widget - QGLWidget - to display the trace.
 */
class Render_abstract : public Geometry, public Render_windowed
{
    // Q_OBJECT

protected:
    /*!
     * \brief Contains the main_window.
     */
    Interface_graphic *_interface_graphic;

    /*!
     * \brief Contains the layout in which the render is
     */
    RenderLayout *_layout;

    int _scroll_margin_x; /* Control the x margin of the trace.*/
    int _scroll_margin_y; /* Control the y margin of the trace.*/

    /***********************************
     *
     * Render area state attributes.
     *
     **********************************/

    /*!
     * \brief Indicate if the scroll was asked by key capture in openGL render area.
     */
    bool _key_scrolling;

    /*!
     * \brief Alpha color of the selection rectangle.
     */
    double _selection_rectangle_alpha;

    /*!
     * \brief Scale the current view to the zoom box shape.
     * \param x_min the x minimum position.
     * \param x_max the x maximum position.
     * \param y_min the y minimum position.
     * \param y_max the y maximum position.
     * \return true if the zoom box has been applied, false otherwise
     */
    bool apply_zoom_box(Element_pos x_min, Element_pos x_max, Element_pos y_min, Element_pos y_max);

public:
    /*!
     * \brief Max zoom value above which the app has a risk to stop working
     * There are 25 graduations on the ruler
     * Each graduation must be larger than floating precision with 23 bits
     * This value is 2^23 / 25 -> rounded down to 200000
     */
    static const int _MAX_ZOOM_VALUE = 200000; // Max value above which the application stops working

    /*!
     * \brief Minimum x scale factor
     * The value is set in Render_abstract.cpp because of cpp specification
     * related to static const definitions
     * Only static const int and enum can be declared inside the class definition.
     */
    static const float _MIN_X_ZOOM_VALUE;

    /***********************************
     *
     * Constructor and destructor.
     *
     **********************************/

    /*!
     * \brief The constructor.
     * \param render_instance The instance of a drawing class.
     */
    Render_abstract(Interface_graphic *interface_graphic);

    /***********************************
     *
     * Scaling and scrolling functions.
     *
     **********************************/

    /*!
     * \brief Change the scale of state drawing.
     * \param scale_coeff The new coefficient scale value to add to the current scale.
     */
    void change_scale_x(const Element_pos &scale_coeff) override;

    /*!
     * \brief Change the scale of the y state drawing.
     * \param scale_coeff The new coefficient scale value to add to the current scale.
     */
    void change_scale_y(const Element_pos &scale_coeff) override;

    /*!
     * \brief Replace the current scale by a new scale. (horizontally)
     * \param new_scale The new scale value to replace the current scale.
     */
    void replace_scale_x(Element_pos new_scale) override;

    /*!
     * \brief Replace the current scale by a new scale. (vertically)
     * \param new_scale The new scale value to replace the current scale.
     */
    void replace_scale_y(const Element_pos &new_scale) override;

    /*!
     * \brief Change the x position of camera view for state drawing area.
     * \param translate The new position.
     */
    void change_translate_x(const Element_pos &translate); /* temporary -> to change the translate to view states */

    /*!
     * \brief Change the y position of camera view for state drawing area.
     * \param translate The new position.
     */
    void change_translate_y(const Element_pos &translate); /* temporary -> to change the translate to view states */

    /*!
     * \brief Replace the current x translate by a new translate.
     * \param new_translate The new translate value to replace the current translate.
     */
    void replace_translate_x(const Element_pos &new_translate) override;

    /*!
     * \brief Replace the current y translate by a new translate.
     * \param new_translate The new translate value to replace the current translate.
     */
    void replace_translate_y(const Element_pos &new_translate) override;

    /*!
     * \brief Pre registered translation values (for x or y translate).
     * \param id The pre registered translation id.
     */
    void registered_translate(int id) override;

    /*!
     * \brief Refresh scroll bar positions when shortcuts execute movements
     */
    void refresh_scroll_bars() override;

    /*!
     * \brief Change the percentage taken by container display in the render area.
     * \param view_size The new percentage (between 0 to 100).
     */
    void change_container_scale_x(const int &view_size) override; /* temporary -> to change the size of container view */

    /*!
     * \brief Zoom along the x axis between two values
     * \param begin The beginning time of the interval
     * \param end The end time of the interval
     */
    void apply_zoom_on_interval(const Element_pos &begin, const Element_pos &end) override;

    /**
     * \brief Set the RenderLayout in which the render is
     * \param layout new layout pointer value
     */
    void set_layout(RenderLayout *layout) override;

    /*!
     * \brief Getter for scroll_margin_x
     */
    const int &get_scroll_margin_x() const override;

    /*!
     * \brief Getter for scroll_margin_y
     */
    const int &get_scroll_margin_y() const override;
};

#endif
