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

#pragma once

#include "MvQRequestPanelLine.h"
#include "MvIconParameter.h"

#include <QPen>
#include <QRect>
#include <QString>
#include <QVector>
#include <QWidget>

class QColor;
class QLabel;

class RequestPanel;

struct ColorCell
{
    ColorCell() = default;
    ColorCell(QColor c) :
        col(c) {}
    QColor col;
    int xp;
    int yp;
    int w;
    int h;
    void render(QPainter* painter);
    void renderSelection(QPainter* painter);
};

class MvQColourGradWidget : public QWidget
{
    Q_OBJECT

public:
    MvQColourGradWidget(QWidget* parent = nullptr);
    void reset(QList<QColor>, const std::string&, const std::vector<std::string>&, const std::string&, const std::vector<std::string>&);
    QColor currentColour() const;
    void setCurrentColour(QColor);
    QList<QColor> colours() const;
    void setEdited(bool);
    bool setTechs(const std::vector<std::string>& vals, bool redraw);
    bool setSteps(const std::vector<std::string>& vals, bool redraw);
    bool setWayMethod(const std::string& val, bool redraw);
    bool setDirection(const std::string& val, bool redraw);

public slots:
    void slotInsertBeforeCell();
    void slotInsertAfterCell();
    void slotDeleteCell();
    void slotReverseLeft();
    void slotReverseRight();
    void slotReverseAll();
    void slotShowInfo();

protected slots:
    void slotCopyColour();
    void slotPasteColour();

signals:
    void changed();
    void currentChanged(QColor);
    void singleCellClicked();

protected:
    void resizeEvent(QResizeEvent*) override;
    void changeEvent(QEvent* event) override;
    void paintEvent(QPaintEvent*) override;
    void mousePressEvent(QMouseEvent*) override;
    void createPixmap();
    void renderBlock(QPainter*, QColor c1, QColor c2, QString tech, int num, QRect r, int, int);
    void renderCurrentCell(QPainter*);
    void paintCell(QPainter* painter, QRectF cr, QColor c1, QColor c2, float pos, QString tech);
    void setCurrentCell(QPoint);
    void setCurrentCell(int);
    void deleteCell(int);
    void insertBeforeCell(int);
    void insertAfterCell(int);
    void checkActionState();
    bool isTechValid(QString v);
    void reverseLeft(int);
    void reverseRight(int);

    QColor interpolateLinear(QColor c1, QColor c2, float p);
    QColor interpolateHslClockwise(QColor c1, QColor c2, float p);
    QColor interpolateHslAntiClockwise(QColor c1, QColor c2, float p);
    QColor interpolateHslShort(QColor c1, QColor c2, float p);
    QColor interpolateHslLong(QColor c1, QColor c2, float p);
    QColor interpolateHclClockwise(QColor c1, QColor c2, float p);
    QColor interpolateHclAntiClockwise(QColor c1, QColor c2, float p);
    QColor interpolateHclShort(QColor c1, QColor c2, float p);
    QColor interpolateHclLong(QColor c1, QColor c2, float p);

    bool edited_;
    QPixmap pix_;
    QVector<ColorCell> cells_;
    QVector<QColor> allColours_;
    int cellHeight_;
    int currentCell_;
    QPen blackPen_;
    QPen whitePen_;
    QAction* insertBeforeAc_;
    QAction* insertAfterAc_;
    QAction* deleteCellAc_;
    QAction* reverseLeftAc_;
    QAction* reverseRightAc_;
    QAction* reverseAllAc_;
    QAction* copyColAc_;
    QAction* pasteColAc_;
    QAction* infoAc_;
    int editorGapX_;
    int editorGapY_;
    int gradHeight_;
    QVector<int> steps_;
    QStringList techs_;
    QStringList validTechs_;
    QString wayMethod_;
    QStringList validWayMethods_;
    QString direction_;
    QStringList validDirections_;
};

class MvQColourGradLine : public MvQRequestPanelLine
{
    Q_OBJECT

public:
    MvQColourGradLine(RequestPanel& owner, const MvIconParameter& param);
    ~MvQColourGradLine() override = default;

    QString currentValue() { return {}; }
    void refresh(const std::vector<std::string>&) override;
    void changed(const char* param, const std::vector<std::string>&) override;
    void changed(const char* param, const std::string&) override;
    bool isDependent() const override { return true; }

public slots:
    void slotListChanged();
    void slotCurrentChanged(QColor);
    void slotHelperEdited(const std::vector<std::string>&) override;
    void slotSingleCellClicked();
    void slotHelperOpened(bool) override;

protected:
    void buildHelper() override;
    void updateHelper();

    MvQColourGradWidget* widget_;
    std::string waypointParam_;
    std::string techParam_;
    std::string directionParam_;
    std::string stepParam_;
};
