#ifndef VISUALIZATIONCHART_H
#define VISUALIZATIONCHART_H

#include <iostream>
#include <QObject>
#include <QList>
#include <QMap>
#include <QQueue>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QLineSeries>
#include <QtCharts/QSplineSeries>

#include <QtCharts/QLegend>
#include <QtCharts/QBarCategoryAxis>
#include <QtCharts/QValueAxis>
#include <QDebug>
#include <QLineF>
#include <QGraphicsSceneMouseEvent>

QT_CHARTS_USE_NAMESPACE
using namespace std;

class CircularQueue
{
public:
    CircularQueue() = default;
    CircularQueue(int offset, int step)
        : mOffset(offset), mStep(step)
    {}

    void setSize(int size)
    {
        mSize=size;
    }

    void add(int v)
    {
        if(mQue.size() == mSize ) {

            mQue.pop_front();
            mQue.push_back(v);
        }
        else {
            mQue.push_back(v);
        }

        auto mm = std::minmax_element(mQue.begin(), mQue.end());
        mMin = *mm.first;
        mMax = *mm.second;
    }

    int min()
    {
        return mMin;
    }
    int max()
    {
        return mMax;
    }
    int offset()
    {
        return mOffset;
    }
    void addOffset()
    {
        mOffset = mOffset + mStep;
    }

    QList<int>& container() { return mQue; }
private:
    QList<int> mQue;
    int mSize=1;

    int mMin=0;
    int mMax=0;

    int mOffset = 10;
    int mStep = 1;
};

class VisualizationChart : public QChart
{
    Q_OBJECT

public:
    VisualizationChart();
    VisualizationChart(int w, int h, bool keepXGrowToTheRight = false, bool keepYFullRange = false);
    VisualizationChart(int w, int h, int minY, int maxY, bool keepXGrowToTheRight = false, bool keepYFullRange = false);

    void addSeriesWithNumber(int number, QString name, QColor color);
    void getSeriesWithNumberNameAndColor(int number, QString &name, QColor &color);

    void hideSeriesWithNumber(int number);
    void showSeriesWithNumber(int number);

    QSplineSeries &  getSeries();
    QSplineSeries &getSplineSeries();

    void appendPointToSeries(int serNum, const QPointF point);
    void appendNextX();
    void appendYToSeries(int serNum, const qreal y);
    void refreshSeries(int serNum);

    void append(const QPointF point);
    void append(const qreal x, const qreal y);
    void append(const qreal y);

    VisualizationChart &operator+=(const QPointF point);
    VisualizationChart &operator+=(const qreal y);
    VisualizationChart &operator<<(const QPointF point);
    VisualizationChart &operator<<(const qreal y);

    void setTitleForX(QString s);
    void setTitleForY(QString s);

signals:
    void sendSecs(int secs);

protected:
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void hoverMoveEvent(QGraphicsSceneHoverEvent *event);

    void show15MinutesXIntervalNearCursor(QGraphicsSceneHoverEvent *event);
    void showCoordinatesNearCursor(QGraphicsSceneHoverEvent *event);
    void showUpdatedCoordinatesNearCursor(QGraphicsSceneHoverEvent *event);

private:
    int mW = 0;
    int mH = 0;

    int       xi = 0;
    const int xeps = 0;
    // const int yeps = 10;
    const int yeps = 500;
    int mMaxY = 60;
    int mMinY = -60;
    int mRangeY = mMaxY - mMinY;
    int mMinYExtraPixelsUnderMinimumY = 1;
    int mMaxYExtraPixelsOverMaximumY = 1;

    int xlimit = (60 * 3) + 2; //10 + 2;
    //int xlimit = (60 * 3) + 2; //10 + 2;
    //int xlimit = 150;

    int xmin, xmax;
    int ymin, ymax;

    //
    bool mMakeXaxisLengtGrowToTheRightAccordingIncommingXdata = false;
    bool mMakeYaxisLengtAutoResizeAccordingIncommingYdata = true;


    CircularQueue mQue;

    QValueAxis *axisX;
    QValueAxis *axisY;

    QMap<int , QSplineSeries *> mSeriesMap;


    //QSplineSeries* getSplineSeries(int num);
    QSplineSeries* getSplineSeries(int num);
    QColor getSplineSeriesColor(int num);

    //QSplineSeries *ssMax;
    //QSplineSeries *ssMid;
    //QSplineSeries *ssMin;

    QColor getFirstSeriesColor();
    QColor getSecondSeriesColor();
    QColor getThirdSeriesColor();

    QGraphicsTextItem *mChartYTitle;
    QGraphicsTextItem *mChartXTitle;

    QVector<QGraphicsLineItem *> mlinesHoriz;
    QGraphicsLineItem *m_lineHoriz1;
    QGraphicsLineItem *m_lineHoriz2;
    QGraphicsLineItem *m_lineHoriz3;
    QGraphicsLineItem *m_lineHoriz4;
    QGraphicsLineItem *m_lineHoriz5;
    QGraphicsLineItem *m_lineHorizX;

    QVector<QGraphicsTextItem *> mTextsHoriz;
    QGraphicsTextItem *mTextHoriz1;
    QGraphicsTextItem *mTextHoriz2;
    QGraphicsTextItem *mTextHoriz3;
    QGraphicsTextItem *mTextHoriz4;
    QGraphicsTextItem *mTextHoriz5;

    QGraphicsLineItem *m_lineVert1;
    QGraphicsLineItem *m_lineVert2;
    QGraphicsLineItem *m_lineVert3;
    QGraphicsLineItem *m_lineVert4;
    QGraphicsLineItem *m_lineVert5;
    QGraphicsLineItem *m_lineVert6;

    QGraphicsTextItem *mTextVert1;
    QGraphicsTextItem *mTextVert2;
    QGraphicsTextItem *mTextVert3;
    QGraphicsTextItem *mTextVert4;
    QGraphicsTextItem *mTextVert5;
    QGraphicsTextItem *mTextVert6;

    QGraphicsLineItem *mLineLegendWhiteBackground;

    QGraphicsLineItem *m_lineVert;
    QGraphicsTextItem *m_lineVertText;

    QGraphicsSimpleTextItem *m_coordX;
    QGraphicsSimpleTextItem *m_coordY;

    void initChart();
    void initChartOld();
};

#endif // VISUALIZATIONCHART_H
