#include "multichartview.h"
#include "ui_multichartview.h"
#include "converttoseries.h"

using namespace QtCharts;

MultiChartView::MultiChartView(DataQueue *queue, QWidget *parent) :
    QWidget(parent), dataQueue(queue),
    ui(new Ui::MultiChartView)
{
    ui->setupUi(this);
    xRangeMax = 0.0;
    xRangeMin = 0.0;
    connect(dataQueue, SIGNAL(resultReady(QString)), this, SLOT(dataReady(QString)));
    //connect(&dataQueue, SIGNAL(finished()), &dataQueue, SLOT(deleteLater()));
    labelFont = QFont("Sans", 10);
    tickLabelFont = QFont("Sans", 7);
    setContentsMargins(QMargins(0,0,0,0));
}

MultiChartView::~MultiChartView()
{
    std::map<std::string, Chart*>::iterator cit;
    for (cit = chartMap.begin(); cit != chartMap.end(); cit++) {
        delete cit->second;
    }
    std::map<std::string, ChartView*>::iterator vit;
    for (vit = viewMap.begin(); vit != viewMap.end(); vit++) {
        delete vit->second;
    }
    delete ui;
}


void MultiChartView::addArray(const nix::DataArray &array) {
    while (dataQueue->isRunning()){
        // uncool!!!
    }
    this->arrayMap.insert(std::pair<std::string, nix::DataArray>(array.id(), array));
    ArrayInfo ai(array);
    this->infoMap.insert(std::pair<std::string, ArrayInfo*>(ai.arrayid, &ai));
    Chart* chart = createChart(ai);
    ChartView *view = createChartView(chart, ai);

    double absMin = 0.0, absMax = 0.0;
    std::map<std::string, ArrayInfo*>::iterator it;
    for (it = infoMap.begin(); it != infoMap.end(); it++) {
        if (it->second->xoffset < absMin)
            absMin = it->second->xoffset;
        if (it->second->xmax > absMax)
            absMax = it->second->xmax;
    }

    ui->scrollBar->setMinimum(0);
    ui->scrollBar->setMaximum(100000);
    ui->scrollBar->setPageStep(100);
    ui->vBox->addWidget(view);
    loadData(ai);
}

Chart* MultiChartView::createChart(const ArrayInfo &info) {
    Chart *chart = new Chart();
    //chart->setTitle(QString::fromStdString(info.name));
    chart->setToolTip(QString::fromStdString(info.name));
    chart->legend()->hide();
    chart->createDefaultAxes();

    QValueAxis *axisY = new QValueAxis;
    axisY->setTickCount(10);
    axisY->applyNiceNumbers();
    axisY->setTitleText(QString::fromStdString(info.ylabel));
    axisY->setTitleFont(labelFont);
    axisY->setLabelsFont(tickLabelFont);
    chart->setAxisY(axisY);

    QValueAxis *axisX = new QValueAxis;
    axisX->setRange(info.xoffset, info.xmax);
    axisX->setTickCount(10);
    axisX->setLabelFormat("%.4f");
    axisX->setTitleFont(labelFont);
    axisX->setTitleText(QString::fromStdString(info.xlabel));
    axisX->setLabelsFont(tickLabelFont);
    axisX->applyNiceNumbers();
    chart->setAxisX(axisX);
    connect(axisX, SIGNAL(rangeChanged(qreal,qreal)), chart, SLOT(XRangeChanged(qreal,qreal)));

    this->chartMap.insert(std::pair<std::string, Chart*>(info.arrayid, chart));
    return chart;
}

ChartView* MultiChartView::createChartView(Chart *chart, const ArrayInfo &info) {
    ChartView *view = new ChartView(chart);
    view->setLineWidth(1);
    view->setRenderHint(QPainter::Antialiasing);

    /*
    QMargins margins = voltageChart->margins();
    int marg1 = margins.left();
    margins.setLeft(marg1 * 4);
    eodChart->setMargins(margins);
    */

    this->viewMap.insert(std::pair<std::string, ChartView*>(info.arrayid, view));
    return view;
}

void MultiChartView::loadData(const ArrayInfo &info) {
    if (arrayMap.at(info.arrayid)) {
        nix::NDSize count(1, 100000);
        nix::NDSize start(1, 0);
        std::string vId, eodId;
        dataQueue->requestData(arrayMap.at(info.arrayid), count, start, vId);
    }
}

void MultiChartView::dataReady(QString requestId){
    DataResult1D data = dataQueue->getData(requestId);
    if (data.id.empty()) {
        return;
    }
    ConvertToSeries *task = new ConvertToSeries();
    QLineSeries *series = new QLineSeries();
    task->setData(series, data);
    connect(task, SIGNAL(dataConverted(QLineSeries*,QString, double, double)), this, SLOT(dataConverted(QLineSeries*,QString, double, double)));
    QThreadPool::globalInstance()->start(task);
}

void MultiChartView::dataConverted(QLineSeries *series, QString entityId, double ymin, double ymax) {
    Chart *chart = chartMap[entityId.toStdString()];
    series->setUseOpenGL(true);
    chart->addSeries(series);

    if (chart->axisX()->type() == QAbstractAxis::AxisTypeValue) {
        QValueAxis *axisX = static_cast<QValueAxis*>(chart->axisX());
        axisX->setRange(series->at(0).x(), series->at(series->count()-1).x());
    }
    if (chart->axisY()->type() == QAbstractAxis::AxisTypeValue) {
        QValueAxis *axisY = static_cast<QValueAxis*>(chart->axisY());
        double range = ymax - ymin;
        axisY->setRange(ymin - 0.2 * range, ymax + 0.2 * range);
    }

    QPen pen = series->pen();
    pen.setWidth(1);
    series->setPen(pen);
}