#include "status_dialog.hh"
#include "ui_status_dialog.h"
#include "../../TradeCore/chart_candle.hh"
#include "../../3rdParty/qwt/qwt_date.h"
#include <QVector>

namespace {

template <typename Type>
void pushValue(Type value, QVector<Type>& vector)
{
    if (vector.size() < sampleCount) {
        vector.push_back(value);
        return;
    }

    for (int i = 1; i < vector.size(); i++)
        vector[i-1] = vector[i];

    vector[vector.size()-1] = value;
}

QwtOHLCSample toOHLCSample(const ChartCandle& candle)
{
    QwtOHLCSample sample;
    sample.time = QwtDate::toDouble(candle.dateTime());
    sample.open = candle.open();
    sample.high = candle.high();
    sample.low = candle.low();
    sample.close = candle.close();
    return sample;
}

} //namespace

StatusDialog::StatusDialog(QWidget* parent) :
    QDialog(parent),
    ui_(new Ui::StatusDialog),
    sma12_(12)
{
    ui_->setupUi(this);
}

StatusDialog::~StatusDialog()
{
    delete ui_;
}

void StatusDialog::updateInputPlot(const std::vector<double>& data)
{
    auto qData = QVector<double>::fromStdVector(data);
    ui_->inputPlot->setPlotData(qData);

    if (isVisible())
        ui_->inputPlot->replot();
}

void StatusDialog::updateOutputPlot(const ChartCandle& candle, double output)
{
    sma12_(candle.close());

    pushValue(QwtDate::toDouble(candle.dateTime()), timeValues_);
    pushValue(output, networkOutputs_);
    pushValue(toOHLCSample(candle), priceSamples_);

    if (sma12Values_.empty()) {
        for (int i = 0; i < 11; i++)
            sma12_(candle.close());
    }

    pushValue(sma12_(), sma12Values_);

    ui_->outputPlot->plotData(
        timeValues_, networkOutputs_, sma12Values_, priceSamples_);

    double from = QwtDate::toDouble(candle.dateTime().addSecs(-4 * 60 * 60));
    double to = QwtDate::toDouble(candle.dateTime());

    ui_->outputPlot->setAxisScale(QwtPlot::xBottom, from, to);

    if (isVisible()) {
        ui_->outputPlot->replot();

        if (!networkInfo_.file.isEmpty()) {
            ui_->outputPlot->threshold(networkInfo_.threshold);
            ui_->outputPlot->thresholdVisible(true);
        } else {
            ui_->outputPlot->thresholdVisible(false);
        }
    }
}

void StatusDialog::networkOutput(double output, bool isTradingTime)
{
    networkOutput_ = output;
    tradingTime_ = isTradingTime;

    if (isVisible()) {
        ui_->infoWidget->networkOutput(networkOutput_);
        ui_->infoWidget->tradingTime(tradingTime_);
    }
}

void StatusDialog::networkInfo(const NetworkInfo& networkInfo)
{
    networkInfo_ = networkInfo;

    if (isVisible())
        ui_->infoWidget->networkInfo(networkInfo_);
}

void StatusDialog::orders(const std::vector<Order>& orders)
{
    orders_ = orders;

    if (isVisible())
        ui_->infoWidget->orders(orders_);
}

void StatusDialog::updateInfoWidget()
{
    ui_->infoWidget->networkOutput(networkOutput_);
    ui_->infoWidget->tradingTime(tradingTime_);
    ui_->infoWidget->networkInfo(networkInfo_);
    ui_->infoWidget->orders(orders_);
}

void StatusDialog::replot()
{
    ui_->outputPlot->replot();
    ui_->inputPlot->replot();
}
