/**
 * \class ImageGraphicsScene
 *
 *
 * \brief Displays the rectangles and work on the image.
 *
 * This class is essential. When the user wants to draw, modify or annotate a rectangle, ImageGraphicsScene allows
 * him to proceed so.
 *
 * \note The following
 * \author $Author: David Carmona-Moreno $
 *
 * \version $Revision: 1.0 $
 *
 * \date $Date: 2016/01/11 14:00:00 $
 * \bug When the user wants to modify one rectangle, its height and weight cannot be negative.
 *
 * Contacts: nikolaos.arvanitopoulos@epfl.ch and david.carmona-moreno@epfl.ch
 *
 * Created on: Mon Jan 12 14:00:00 2016
 *
 */

#ifndef DRAWRECTANGLE
#define DRAWRECTANGLE

#include <QGraphicsScene>
#include <QPoint>
#include <QMouseEvent>
#include <QDebug>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QPixmap>
#include <QGraphicsRectItem>
#include <QPointF>
#include <QGraphicsView>
#include <QCursor>

#include "filewriter.h"
#include "filewritterXML.h"
#include "createfileabstraction.h"
#include "rectangledraw.h"
#include "rectanglewindow.h"
#include "removeconfirmationwindow.h"
#include "filereader.h"
#include "removeconfirmationwindow.h"

class ImageGraphicsScene:public QGraphicsScene
{
    Q_OBJECT

private:

    // The pixmap of the image the user wants to work with
    QPixmap *pixmap;

    // The pixmap representing the mouse cursor when the erase button is activated
    QPixmap *erase_pixmap;

    // The pixmap representing the mouse when the modify button is activated
    QPixmap *modify_pixmap;

    // The size of the application scene
    QRectF sceneRectangle;

    // The rectangles which are going to be drawn by the user
    RectangleDraw *rect;

    // The rectangle ID
    int id;

    // Corner top-left point
    QPointF origPoint;
    QList<RectangleDraw*> list;

    // User's click on a rectangle in order to open the dialog window
    QPointF UserPoint;

    // The object which is going to write all the rectangles information
    // in the text file
    FileWriter *filewriter;

    // The text file associated to the image
    CreateFileAbstraction *createfileabstraction;

    // Check the state of the mouse's left button
    bool mouseLeftPressed;

    // Window corresponding to the rectangle
    RectangleWindow* window;

    // DrawButton state
    bool drawButton;

    // EraseButton state
    bool eraseButton;

    // Check if the user has double-clicked on the rectangle
    bool doubleClick;

    // DragButton state
    bool dragButton;

    // State of the modify button
    bool modifyButton;

    // Check if one of the rectangles is selected
    bool isSelected;

    // Check of the mouse is on one of the rectangle's corners
    bool isOnCorner;

    // Check if the mouse is pressed on one of the corners
    bool isOnTopLeftCornerPressed;
    bool isOnTopRightCornerPressed;
    bool isOnBottomLeftCornerPressed;
    bool isOnBottomRightCornerPressed;

    // The rectangle modification can take place
    bool startModifying;

    // Te rectangle which is going to be modified by the user
    RectangleDraw* rectModified;

    // The view containing the scene
    QGraphicsView *view;

    // The erase cursor
    QCursor *erase_cursor;

    // The modify cursor
    QCursor *modify_cursor;

    // The confirmation window when the user wants to remove a rectangle
    RemoveConfirmationWindow *remove;

public:

    /** @brief The constructor of the ImageGraphicsScene class
     *  @param view_1 The QGraphicsView where the image is displayed
     *  @param pixmap_1 The image we want to work with
     *  @param sceneRectangle_1 The size of the ImageGraphicsScene
     *  @param cfa_1 The text file which is associated to the image
     */
    ImageGraphicsScene(QGraphicsView *view_1,QPixmap *pixmap_1,QRectF sceneRectangle_1,CreateFileAbstraction *cfa_1):
        sceneRectangle(sceneRectangle_1),pixmap(pixmap_1),mouseLeftPressed(false),
        createfileabstraction(cfa_1),rect(NULL),id(0),UserPoint(0,0),window(NULL),drawButton(false),eraseButton(false),
        dragButton(false),doubleClick(true),view(view_1),modifyButton(false),isSelected(false),
        rectModified(NULL),isOnCorner(false),isOnTopLeftCornerPressed(false),isOnTopRightCornerPressed(false),
        isOnBottomLeftCornerPressed(false),isOnBottomRightCornerPressed(false),startModifying(false),remove(NULL)
    {
        // Create the file writer
        filewriter=new FileWriter(createfileabstraction);


        // Create the file readr
        //filereader=new FileReader(createfileabstraction);

        // The size of the GraphicsScene must be equal to the image size
        this->setSceneRect(sceneRectangle);

        // Display the image
        this->addPixmap(*pixmap);

        // Erase pixmap
        erase_pixmap=new QPixmap("../Icons/cursor_erase.png");

        // Modidy pixmap
        modify_pixmap=new QPixmap("../Icons/pencil.png");

        // Instatiate the mouse cursor
        erase_cursor=new QCursor(*erase_pixmap);

        // Modify cursor
        modify_cursor=new QCursor(*modify_pixmap);
    }
    
    /** @brief Class destructor
     */
    virtual ~ImageGraphicsScene(){}

    /** @brief Checks if the user is pressing on one rectangle
     *  @param rectangle A rectangle
     *  @param param The mouse pointer coordinates
     *  @return True if the user is pressing on one rectangle ,False if not
     */
    virtual bool Iscontaining(RectangleDraw *rectangle,QPointF point)const;

    /** @brief Sets the state of the draw icon
     *  @param True if the user is still drawing, False if he has finished
     */
    virtual void setDrawButton(bool value);

    /** @brief Returns the state of the draw icon
     *  @return True if it is pressed by the user, False if it is not
     */
    virtual bool getDrawButton()const;

    /** @brief Sets the state of the erase icon
     *  @param True if the user is still erasing, False if he has finished
     */
    virtual void setEraseButton(bool value);

    /** @brief Returns the state of the erase icon
     *  @return True if it is presed by the user, False if it is ot
     */
    virtual bool getEraseButton()const;

    /** @brief Deprecated. Will be removed in a future release
     */
    virtual void setDoubleClick(bool value);

    /** @brief Deprecated method. Will be removed in the future release.
     */
    virtual bool getDoubleClick()const;

    /** @brief Sets the state of the drag icon
     *  @param True if the user is still dragging False if he has finished
     */
    virtual void setDragButton(bool value);

    /** @brief Returns the state of the drag icon
     *  @return True if it is pressed by the user,False if it is not
     */
    virtual bool getDragButton()const;

    /** @brief Returns the shape of the erase cursor
     *  @return The cursor shape
     */
    virtual QCursor* getEraseCursor()const;

    /** @brief Returns the shape of the Modify cursor
     *  @return The cursor shape
     */
    virtual QCursor* getModifyCursor()const;

    /** @brief Returns a list of all the rectangles in the scene
     *  @return The list of all the rectangles in the scene
     */
    virtual QList<RectangleDraw*> getList()const;

    /** @brief Sets the list of the rectangles drawn in th scene
     *  @param list_1 The rectangles list
     */
    virtual void setList(QList<RectangleDraw*> list_1);

    /** @brief Sets the rectangle ID
     *  @param id The automatically computed ID
     */
    virtual void setId(int id);

    /** @brief Returns the FileWriter object
     *  @return The FileWriter object
     */
    virtual FileWriter* getFileWriter()const;

    /** @brief Sets the FielWriter object
     *  @param filewriter_1 The FileWriter object
     */


    /** @brief Sets the FielWriter object
     *  @param filewriter_1 The FileWriter object
     */
    virtual void setFileWriter(FileWriter *filewriter_1);

    /** @brief Checks if the mouse is around one of the rectangle corners when we are in the "Modify" mode
     *  @param point The mouse pointer coordinates
     *  @return Always returns 0
     */
    virtual int checkMouseMove(QPointF point);

    /** @brief Checks if the mouse is pressing one of the rectangle corners when we are in the "Modify" mode
     *  @param point The mouse pointer coordinates
     *  @return Always returns 0
     */
    virtual int checkMousePress(QPointF point);

    /** @brief Deprecated. Will be removed in a future release
     */
    virtual void setIsSelected(bool state);

    /** @brief Checks if we are in the "Modify" mode or not
     *  @return True if we are in the "Modify" mode, False if we are not
     */
    virtual bool checkModify()const;

    /** @brief Deprecated. Will be remove in a future release.
     */
    virtual void setModify(bool state);

    /** @brief Returns the text file
     *  @return The text file
     */
    virtual CreateFileAbstraction* getCreateFileAbstraction()const;

    /** @brief Sets the text file associated to the image
     *  @param createfileabstraction_1 The text file associated to the image
     */
    virtual void setCreateFileAbstraction(CreateFileAbstraction *createfileabstraction_1);

protected:

    /** @brief Detects when the user presses one button of the mouse
     *  @return Void.
     */
    void mousePressEvent(QGraphicsSceneMouseEvent *event);

    /** @brief Detects when the user releases one button of the mouse
     *  @return Void.
     */
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

    /** @brief Detects when the user moves his mouse all around the scene
     *  @return Void.
     */
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);

    /** @brief Deprecated. Will be removed in a future release
     *  @return Void.
     */
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event);

signals:

    /** @brief Deprecated signal. Will be deleted in a future release.
     *  @return Void.
     */
    void changeCursor(bool value);
};

#endif // DRAWRECTANGLE

