/***************************** LICENSE START ***********************************

 Copyright 2021 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#ifndef MVQFEATURECOMMAND_H
#define MVQFEATURECOMMAND_H

#include <QList>

#include "MvRequest.h"

#include "MvQFeatureItem.h"

class QLabel;
class QMouseEvent;
class QGraphicsItem;
class QPlainTextEdit;
class QUndoStack;
class MgQLayoutItem;
class MvQFeatureCommandTarget;
class MvQFeatureCurveBaseItem;
class MvQFeatureItem;
class MvQFeatureSelector;
class MvQPlotView;
class MvQFeatureHandler;
class MvQFeatureRibbonEditor;
class MvQFeatureTextItem;
class MvQFeatureTextEditor;

class MvQFeatureHandler
{
public:
    MvQFeatureHandler(MvQPlotView* view);
    void setUndoStack(QUndoStack *s);
    void setRibbonEditor(MvQFeatureRibbonEditor*);
    void setInfoWidget(QPlainTextEdit*);

    void clearSelection();
    void checkSelection();
    void adjustSelection();

    void currentLayout(MvQFeatureItem* item, MgQLayoutItem **layoutItem) const;

    void add(QString name, QPoint pos);
    bool add(MvQFeatureItem* item, const QPointF& scPos);
    void notifyAdded(QList<MvQFeatureItem*> item);
    void performRemove(QList<MvQFeatureItem*> item);
    void fromClipboard(const QPointF& scenePos);
    void runCommand(const MvQFeatureCommandTarget& sel, QString cmd);

    MvQFeatureSelector* selector() const {return selector_;}
    const QList<MvQFeatureItem*>& features() const {return features_;}
    void swapByZValue(MvQFeatureItem *item, float z);

    void updateStyle(MvQFeatureItem* item, const MvRequest& req, MvQFeatureItem::StyleEditInfo info=MvQFeatureItem::StandardStyleEdit);

    void setText(MvQFeatureItem* item, QString text);
    void editText(MvQFeatureTextItem* item);
    bool checkMousePressForTextEditor(const QPointF& scenePos);
    void checkMouseMove(QMouseEvent* viewEvent);
    void dragTextEditor(MvQFeatureTextEditor*);

    void moveNode(MvQFeatureCurveBaseItem* curve, const QPointF& pp, int nodeIndex, bool start);
    void moveBy(QList<MvQFeatureItem*> items, const QPointF& delta, bool start);
    void resize(QList<MvQFeatureItem*> items, const QRectF& newRect, const QRectF& oriRect, bool start);

    void resetBegin();
    void resetEnd();

    bool canAcceptMouseEvent() const;

    // should handle the cursor setting for all the features
    void setDragCursor() const;
    void setCurvePointCursor() const;
    void resetCursor() const;

protected:
    QGraphicsItem* rootItem() const;
    void makeSelector();
    MgQLayoutItem* layoutItemAt(const QPointF& scPos) const;
    bool isOutOfView(const QPointF& scPos, MgQLayoutItem *layoutItem) const;
    bool canBeAddedToScene(MvQFeatureItem* item, const QPointF& scPos, MgQLayoutItem **layoutItem) const;
    bool canBePastedToScene(MvQFeatureItem* item, const QPointF& scPos, MgQLayoutItem **layoutItem) const;
    void removeTextEditor();
    void paste(QList<MvQFeatureItem*> items, const QPointF& scPos);
    void handleItemCommand(MvQFeatureItem *targetItem, QString cmd, int nodeIndex,
                                          const QPointF& scenePos);
    void handleSelectorCommand(QString cmd, const QPointF& scenePos);
    void updateFeatureInfo(MvQFeatureItem*);

    MvQPlotView* view_{nullptr};
    MvQFeatureSelector* selector_{nullptr};
    QList<MvQFeatureItem*> features_;
    QUndoStack* undoStack_{nullptr};
    MvQFeatureRibbonEditor* ribbonEditor_{nullptr};
    MvQFeatureTextEditor* textEditor_{nullptr};
    QPlainTextEdit* infoWidget_{nullptr};
};

#endif // MVQFEATURECOMMAND_H
