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

 Copyright 2012 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 MvQPlaceMark_H
#define MvQPlaceMark_H

#include <QGraphicsItem>
#include <QIcon>
#include <QPixmap>

#include "MvQPlotItem.h"

class MgQLayoutItem;
class MvQMagnifier;

using namespace std;


/*class MvQPlaceMark
{
public:
	MvQPlaceMarkNode();
	QString name() {return name_;}
	QPointF coordinates() {return coordinates_;}	
	bool highlighted() {return highlighted_;};

	void setName(QString name) {name_=name;}
	void setCoordinates(QPointF &); 
	void setScenePosition(QPointF &);
	void setHighlighted(bool);

protected:
	QString name_;
	QPointF coordinates_;	
	QPixmap 	 pix_;
	QList<QStringList> layerData_;
};*/


class MvQPlaceMarkNode
{
public:
    enum Type
    {
        FolderType,
        ItemType
    };
    enum View
    {
        MapView,
        CartesianView
    };

    MvQPlaceMarkNode(Type type = ItemType);
    ~MvQPlaceMarkNode() { clear(); }

    void clear()
    {
        foreach (MvQPlaceMarkNode* n, children())
            delete n;
        children_.clear();
    }

    QString name() { return name_; }
    QPointF coordinates() { return coordinates_; }
    QString description() { return description_; }
    bool isVisible() { return visible_; }
    bool isOutOfPlot() { return outOfPlot_; }
    Type type() { return type_; }
    QIcon icon();
    QPixmap pixmap() { return pix_; }

    void setName(QString name) { name_ = name; }
    void setCoordinates(QPointF&);
    void setDescription(QString d) { description_ = d; }
    void setVisible(bool);
    void setOutOfPlot(bool);
    void setPixmap(QPixmap pix) { pix_ = pix; }
    void setPixmap(QString pixPath) { pix_ = QPixmap(pixPath); }

    const QList<QStringList>& layerData() { return layerData_; }
    void setLayerData(QList<QStringList> d) { layerData_ = d; }
    void clearLayerData() { layerData_.clear(); }

    void addChild(MvQPlaceMarkNode* node)
    {
        children_ << node;
        node->setParent(this);
    }
    void removeChild(MvQPlaceMarkNode* node);
    void removeChild(int);
    QList<MvQPlaceMarkNode*> children() { return children_; }
    //bool findByNode(MvQOgcNode*,MvQOgcNode **);
    //bool findByValue(QString,MvQOgcNode **);
    //bool findByDisplayValue(QString,MvQOgcNode **);

    MvQPlaceMarkNode* parent() { return parent_; }

protected:
    void setParent(MvQPlaceMarkNode* parent) { parent_ = parent; }

    QString name_;
    QPointF coordinates_;
    QString description_;
    QPixmap pix_;
    QList<QStringList> layerData_;
    Type type_;
    bool visible_;
    bool outOfPlot_;

    MvQPlaceMarkNode* parent_;
    QList<MvQPlaceMarkNode*> children_;
};

class MvQPlaceMarkTree
{
public:
    MvQPlaceMarkTree() { root_ = new MvQPlaceMarkNode(MvQPlaceMarkNode::FolderType); }
    ~MvQPlaceMarkTree() { clear(); }

    /*MvQOgcNode* currentNode() {return currentNode_;}
	void setCurrentNode(MvQOgcNode*);
	QString currentValue() {return (currentNode_)?currentNode_->value():QString();}
	QString currentDisplayValue() {return (currentNode_)?currentNode_->displayValue():QString();}
	QString currentDescription() {return (currentNode_)?currentNode_->description():QString();}

	void setCurrentValue(QString);
	void setCurrentDisplayValue(QString);*/

    MvQPlaceMarkNode* root() { return root_; }
    void clear() { root_->clear(); }
    void moveNode(MvQPlaceMarkNode*, MvQPlaceMarkNode*);

protected:
    MvQPlaceMarkNode* root_;
};


class MvQPlaceMarkItem : public MvQPlotItem
{
    Q_OBJECT

public:
    enum CurrentAction
    {
        NoAction,
        MoveAction
    };
    enum PixmapAnchor
    {
        CentreAnchor,
        BottomCentreAnchor
    };


    MvQPlaceMarkItem(MvQPlaceMarkNode*, MgQPlotScene*, MvQPlotView*, QGraphicsItem* parent = 0);
    ~MvQPlaceMarkItem();

    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
    QRectF boundingRect() const;

    void mousePressEventFromView(QMouseEvent*);
    void mouseMoveEventFromView(QMouseEvent*);
    void mouseReleaseEventFromView(QMouseEvent*);

    CurrentAction currentAction() { return currentAction_; }

    bool highlighted() { return highlighted_; };

    void setPixmapColour(QColor);
    void setScenePosition(QPointF&);
    void setHighlighted(bool);

    void updateVisibility();
    void reset();

    MvQPlaceMarkNode* placeMark() { return pm_; }

signals:
    void itemUpdated();

protected:
    void updateLayerData();

    CurrentAction currentAction_;
    QString name_;
    MgQLayoutItem* dataLayout_;
    QRectF boundingRect_;
    QPointF dragPos_;
    bool outOfPlot_;
    bool highlighted_;
    QPixmap pix_;
    PixmapAnchor anchor_;

    MvQPlaceMarkNode* pm_;
};


class MvQPlaceMark : public MvQPlotItem
{
    Q_OBJECT

public:
    enum CurrentAction
    {
        NoAction,
        MoveAction
    };
    enum PixmapAnchor
    {
        CentreAnchor,
        BottomCentreAnchor
    };

    MvQPlaceMark(MgQPlotScene*, MvQPlotView*, QGraphicsItem* parent = 0);
    ~MvQPlaceMark();

    void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
    QRectF boundingRect() const;

    void setActivated(bool);

    void mousePressEventFromView(QMouseEvent*);
    void mouseMoveEventFromView(QMouseEvent*);
    void mouseReleaseEventFromView(QMouseEvent*);

    CurrentAction currentAction() { return currentAction_; }

    bool highlighted() { return highlighted_; };
    bool isOutOfPlot() { return outOfPlot_; }

    void setPixmapColour(QColor);
    void setScenePosition(QPointF);
    void setCoordinates(QPointF);
    QPointF coordinates() const { return coordinates_; }
    void setHighlighted(bool);
    void updateScenePosition();

    void updateVisibility();
    void reset(MgQLayoutItem*);
    void reset(){};
    void setMagnifier(MvQMagnifier*);

signals:
    void pointSelected(QPointF);
    void beingMoved(QPointF);

protected:
    QPointF checkScenePosInMagnifier(const QPointF&);
    QPointF checkMagnifiedPosInMagnifier(const QPointF&);

    CurrentAction currentAction_;
    QString name_;
    MgQLayoutItem* dataLayout_;
    QRectF boundingRect_;
    QPointF dragPos_;
    bool outOfPlot_;
    bool highlighted_;
    QPixmap pix_;
    PixmapAnchor anchor_;
    QPointF coordinates_;
    MvQMagnifier* magnifier_;
};

#endif
