/**
 *
 * @file src/render/Hook_event.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 Francois Trahay
 * @author Thibault Soucarre
 * @author Lucas Guedon
 * @author Olivier Lagrasse
 * @author Augustin Degomme
 *
 * @date 2024-07-17
 */
/*!
 *\file Hook_event.hpp
 */

#ifndef HOOK_EVENT_HPP
#define HOOK_EVENT_HPP
#include "render/Render_windowed.hpp"
#include "render/Render_abstract.hpp"

/*!
 * \brief Structure used to store selection coordinate information.
 */
struct Selection_
{
    /*!
     * \brief x scale.
     */
    Element_pos x_scale;

    /*!
     * \brief y scale.
     */
    Element_pos y_scale;

    /*!
     * \brief x translation.
     */
    Element_pos x_translate;

    /*!
     * \brief y translation.
     */
    Element_pos y_translate;
};

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

protected:
    /*!
     * \brief Contains container text coordinates.
     */
    std::list<Element_pos> _text_pos;

    /*!
     * \brief Contains container strings.
     */
    std::list<std::string> _text_value;

    /*!
     * \brief Contains the previous selection coordinates.
     */
    std::stack<Selection_> _previous_selection;

    /*!
     * \brief Contains the OpenGL render instance.
     */
    Render *_render_instance;

    /*!
     * \brief timer to check whether we launched a double click event or a single click event
     */
    QTimer *_timer;

    /*!
     * \briefcheck if the timer has already been launched and the signal connected to the slot
     */
    bool _connected;

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

    /*!
     * \brief State when there is no file opened.
     */
    static const int DRAWING_STATE_WAITING;

    /*!
     * \brief State when the application is drawing traces.
     */
    static const int DRAWING_STATE_DRAWING;

    /*!
     * \brief Contains the kind of state for the render area (drawing, waiting, etc.).
     */
    int _state;

    /*!
     * \brief Indicated if mouse is pressed or not.
     */
    bool _mouse_pressed;

    /*!
     * \brief Indicated if mouse is pressed inside the container area.
     */
    bool _mouse_pressed_inside_container;

    /*!
     * \brief Indicated if mouse is pressed inside the ruler area.
     */
    bool _mouse_pressed_inside_ruler;

    /*!
     * \brief Used to store the mouse last x position.
     */
    qreal _mouse_x;

    /*!
     * \brief Used to store the mouse last y position.
     */
    qreal _mouse_y;

    /*!
     * \brief Used to store the mouse current x position.
     */
    qreal _new_mouse_x;

    /*!
     * \brief Used to store the mouse current y position.
     */
    qreal _new_mouse_y;

    /*!
     * \brief Define the minimum width and height to draw the selection rectangle (avoid bas manipulations).
     */
    Element_pos _minimum_distance_for_selection;

    /*!
     * \brief Define the scrolling factor when CTRL key is pressed.
     */
    static const int _ctrl_scroll_factor;

    /*!
     * \brief Define the scrolling factor when CTRL key is pressed.
     */
    static const int _ctrl_zoom_factor;

    /***********************************
     *
     * Default QWidget functions.
     *
     **********************************/

    /*!
     * \brief This functions receives all mouse press events.
     * \param event The event triggered by mouse.
     */
    void mousePressEvent(QMouseEvent *event) override;

    /*!
     * \brief This functions receives all mouse double click events.
     * \param event The event triggered by mouse.
     */
    void mouseDoubleClickEvent(QMouseEvent *event) override;

    /*!
     * \brief If user press, this functions receives all mouse move events until user release mouse.
     * \param event The event triggered by mouse.
     */
    void mouseMoveEvent(QMouseEvent *event) override;

    /*!
     * \brief This functions receives all mouse release events.
     * \param event The event triggered by mouse.
     */
    void mouseReleaseEvent(QMouseEvent *event) override;

    /*!
     * \brief This functions receives all mouse wheel events.
     * \param event The event triggered by the mouse wheel.
     */
    void wheelEvent(QWheelEvent *event) override;

    /*!
     * \brief This functions receives all keyboard events.
     * \param event The event triggered by the keyboard event.
     */
    void keyPressEvent(QKeyEvent *event) override;

    /*!
     * \brief This functions receives all keyboard release events.
     * \param event The event triggered by a keyboard release.
     */
    void keyReleaseEvent(QKeyEvent *event) override;

public:
    /***********************************
     *
     * Constructor and destructor.
     *
     **********************************/

    /*!
     * \brief The constructor.
     * \param render_instance The instance of a drawing class.
     */
    Hook_event(Render *render_instance, Interface_graphic *interface_graphic, const QGLFormat &format);

    /*!
     * \brief The destructor
     */
    ~Hook_event() override;

    void update_render() override;
};

#endif
