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

 Copyright 2017 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 *************************************/

#pragma once

#include <QGraphicsItem>
#include <QGraphicsPixmapItem>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsSvgItem>

class QGraphicsSvgItem;
class QSvgRenderer;
class LocationView;

class MapLayerItem : public QGraphicsItem
{
public:
    enum
    {
        Type = UserType + 1
    };
    MapLayerItem();
    QRectF boundingRect() const override;
    void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) override;
    int type() const override { return Type; }

protected:
    QPixmap pix_;
    QRectF bRect_;
    QRectF srcRect_;
    QSvgRenderer* svg_;
};

class MapMarkerItem : public QGraphicsItem
{
public:
    enum
    {
        Type = UserType + 2
    };
    enum Symbol
    {
        CircleSymbol,
        CrossSymbol
    };

    MapMarkerItem(int id);

    QRectF boundingRect() const override;
    void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) override;
    void setCurrent(bool);
    int type() const override { return Type; }
    int id() const { return id_; }
    static void setSymbol(Symbol sym, float size);

protected:
    int id_;
    bool current_;
    static Symbol symbol_;
    static float symbolSize_;
    static QRectF bRect_;
    static QBrush brush_;
    static QBrush selectBrush_;
    static QPen pen_;
    static QPen crossPen_;
    static QPen selectPen_;
    static QPen crossSelectPen_;
};

class LocationView : public QGraphicsView
{
    Q_OBJECT

public:
    LocationView(QWidget* parent = nullptr);
    void addPoints(const std::vector<double>& lat,
                   const std::vector<double>& lon);
    void setCurrentPoint(int);
    void clearPoints();
    int minZoomLevel() const { return minZoomLevel_; }
    int maxZoomLevel() const { return maxZoomLevel_; }
    int zoomLevel() const { return zoomLevel_; }
    void setZoomLevel(int);
    float currentScale() const;

public Q_SLOTS:
    void showFullMap();
    void zoomToData();
    void zoomIn();
    void zoomOut();

Q_SIGNALS:
    void currentChanged(int);
    void zoomLevelChanged(int);

protected:
    void keyPressEvent(QKeyEvent* event) override;
    void wheelEvent(QWheelEvent* e) override;
    void mousePressEvent(QMouseEvent* event) override;
    void mouseMoveEvent(QMouseEvent* event) override;
    void mouseReleaseEvent(QMouseEvent* event) override;
    void zoom(int level);
    void pan(QPointF delta);
    float scaleFromLevel(int level) const;
    int zoomLevelFromScale(float) const;
    void adjustMarkers(int);

    QGraphicsScene* scene_{nullptr};
    MapLayerItem* layer_{nullptr};
    MapLayerItem* svg_{nullptr};

    std::vector<MapMarkerItem*> markers_;
    int minZoomLevel_{0};
    int maxZoomLevel_{28};
    int zoomLevel_{0};
    float zoomDelta_{0.18};
    QRectF dataRect_;
    MapMarkerItem* selectedItem_{nullptr};
    QPoint dragPos_;
    bool inDrag_{false};
};
