#include "cellsmonitorpage.h"
#include "ui_cellsmonitorpage.h"
#include <math.h>

#include <QStandardItemModel>

#include "cellsmonitorcheckboxdelegate.h"
#include "cellsmonitorlabelvoltagedelegate.h"

CellsMonitorPage::CellsMonitorPage(QWidget *parent) :
    QFrame(parent),
    ui(new Ui::CellsMonitorPage)
{
    ui->setupUi(this);
    hideTestUi();

    m_tablesNumber = 3;
    //m_cellsNumber  = 26;
    m_cellsNumber  = mCellVoltageArray.size();

    initTableHeader();
}

CellsMonitorPage::~CellsMonitorPage()
{
    delete ui;
}

void CellsMonitorPage::hideTestUi()
{
    ui->lbCols->hide();
    ui->lbCells->hide();
    ui->editCols->hide();
    ui->editCells->hide();
    ui->pbTestOne->hide();
    ui->pbTestTwo->hide();
}

BMSInterface *CellsMonitorPage::bms() const
{
    return mDieBieMS;
}

void CellsMonitorPage::setDieBieMS(BMSInterface *dieBieMS)
{
    mDieBieMS = dieBieMS;

    if (mDieBieMS) {
        //connect(mDieBieMS->commands(), &Commands::valuesReceived,this, &CellsMonitorPage::valuesReceived);
        connect(mDieBieMS->commands(), &Commands::cellsReceived,this, &CellsMonitorPage::cellsReceived);
    }
}



void CellsMonitorPage::clearTables()
{
    ui->tableViewLeft->reset();
    ui->tableViewMiddle->reset();
    ui->tableViewRight->reset();
}


void CellsMonitorPage::initTableHeader()
{
    initTableView(m_tablesNumber, true);
}


void CellsMonitorPage::initTableView(QTableView* tableView, bool doInitForCellVoltagArray)
{
    //Создаем модель и представление
    QStandardItemModel *model = new QStandardItemModel(MODEL_ROWS_IN_ONE_TABLE, MODEL_COLUMN_IN_ONE_TABLE);

    int rowWeight = 40;
    //Заолняем Заголовок
    QStringList hedarenamesNumVolBalancing =  QStringList()
            << tr("№")
            << tr("      Напряжение      ")
            << tr("      Балансировка");

    model->setHeaderData(ColNumber, Qt::Horizontal, QObject::tr(hedarenamesNumVolBalancing[ColNumber].toUtf8()));
    model->setHeaderData(ColVoltage, Qt::Horizontal, QObject::tr(hedarenamesNumVolBalancing[ColVoltage].toUtf8()));
    model->setHeaderData(ColBalancing, Qt::Horizontal, QObject::tr(hedarenamesNumVolBalancing[ColBalancing].toUtf8()));

    tableView->verticalHeader()->setDefaultSectionSize(rowWeight);

    int tableViewIndexStart = 0;
    int tableviewIndexEnd = 0;
    int left = 0;
    int right = 0;
    int index = 0;

    if(m_tablesNumber == TwoTables)
    {
        if(ui->tableViewLeft == tableView)
            index = FirstSubTable;
        if(ui->tableViewRight == tableView)
            index = SecondSubTable;
        left =  (index+0) * MODEL_ROWS_IN_ONE_TABLE;
        right = (index+1) * MODEL_ROWS_IN_ONE_TABLE;
        //left = left - ((index+0) * MODEL_ROWS_IN_ONE_TABLE);
        //right = right - ((index+0) * MODEL_ROWS_IN_ONE_TABLE);

        tableViewIndexStart = (0 * MODEL_ROWS_IN_ONE_TABLE);
        switch (index)
        {
            case (FirstSubTable):
            {
                tableviewIndexEnd
                = (m_cellsNumber < MODEL_ROWS_IN_ONE_TABLE)
                ? m_cellsNumber
                : MODEL_ROWS_IN_ONE_TABLE
                ;
            }
            break;
            case(SecondSubTable):
            {
                tableviewIndexEnd
                = (m_cellsNumber < MODEL_ROWS_IN_ONE_TABLE)
                ? 0
                : m_cellsNumber - MODEL_ROWS_IN_ONE_TABLE
                ;
            }
            break;
        }

    }
    else if(m_tablesNumber == ThreeTables)
    {
        int index = 0;
        if(ui->tableViewLeft == tableView)
            index = FirstSubTable;
        if(ui->tableViewMiddle == tableView)
            index = SecondSubTable;
        if(ui->tableViewRight == tableView)
            index = ThirdSubTable;
        left =  (index+0) * MODEL_ROWS_IN_ONE_TABLE;
        right = (index+1) * MODEL_ROWS_IN_ONE_TABLE;

        tableViewIndexStart = (0 * MODEL_ROWS_IN_ONE_TABLE);

        switch (index)
        {
            case (FirstSubTable):
            {
                tableviewIndexEnd
                = (m_cellsNumber < MODEL_ROWS_IN_ONE_TABLE*1)
                ? m_cellsNumber
                : MODEL_ROWS_IN_ONE_TABLE
                ;
            }
            break;
            case (SecondSubTable):
            {
                bool isInSecond = (m_cellsNumber>MODEL_ROWS_IN_ONE_TABLE*1) && (m_cellsNumber <= MODEL_ROWS_IN_ONE_TABLE*2);
                bool isInThird = (m_cellsNumber>MODEL_ROWS_IN_ONE_TABLE*2) && (m_cellsNumber <= MODEL_ROWS_IN_ONE_TABLE*3);

                if(isInSecond)
                {
                    tableviewIndexEnd = m_cellsNumber - MODEL_ROWS_IN_ONE_TABLE;
                }
                if(isInThird)
                {
                    tableviewIndexEnd = MODEL_ROWS_IN_ONE_TABLE;
                }
            }
            break;
            case (ThirdSubTable):
            {
                bool isInThird = (m_cellsNumber>MODEL_ROWS_IN_ONE_TABLE*2) && (m_cellsNumber <= MODEL_ROWS_IN_ONE_TABLE*3);

                if(isInThird)
                {
                    tableviewIndexEnd = m_cellsNumber - MODEL_ROWS_IN_ONE_TABLE*2;
                }
            }
            break;
        }

    }

    //Заолняем модель данными
    int cellNumber = 0;
    for (int row = tableViewIndexStart; row < tableviewIndexEnd; ++row)
    {
        cellNumber++;
        for (int column = 0; column < MODEL_COLUMN_IN_ONE_TABLE; ++column)
        {
            //cellNumber++;

            if( cellNumber > m_cellsNumber)
                continue;

            QModelIndex index = model->index(row, column, QModelIndex());
            switch(column)
            {
                case ColNumber:
                {
                    model->setData(index, QVariant(left + row + 1));
                    model->setData(index, Qt::AlignCenter, Qt::TextAlignmentRole);
                }
                break;
                case ColVoltage:
                {
                    if(doInitForCellVoltagArray)
                        model->setData(index, mCellVoltageArray[left + row].voltage);
                    else // just test data
                        model->setData(index, QVariant( (left + row + 1) ));
                }
                break;
                case ColBalancing:
                {
                    if(doInitForCellVoltagArray)
                        model->setData(index, mCellVoltageArray[left + row].balancing);
                    else
                        model->setData(index, QVariant(row%2));
                }
                break;
            }
        }
    }


    //Устанавливаем модель в представление
    tableView->setModel(model);

    //Устанавливаем делегат в столбец
    CheckBoxDelegate *delegateCbox = new CheckBoxDelegate();
    LabelVoltageDelegate *delegateLab = new LabelVoltageDelegate();

    tableView->setItemDelegateForColumn(ColVoltage, delegateLab);
    tableView->setItemDelegateForColumn(ColBalancing, delegateCbox);
    //Внешний вид предтавления
    tableView->verticalHeader()->hide();
    tableView->horizontalHeader()->setStretchLastSection(false);
    tableView->setSelectionMode(QAbstractItemView::NoSelection);
    tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    tableView->setShowGrid(false);

    // has to be last
    tableView->setColumnWidth(ColNumber, 50);
    tableView->setColumnWidth(ColVoltage, 100);
    tableView->setColumnWidth(ColBalancing, 150);
}


void CellsMonitorPage::initTableView(int tablesNum, bool doInitForCellVoltagArray)
{
    m_tablesNumber = tablesNum;
    //m_cellsNumber = cellsNum;
    m_cellsNumber = mCellVoltageArray.size();

    if(m_cellsNumber > MAX_ROWS_ALL_TABLES)
        m_cellsNumber = MAX_ROWS_ALL_TABLES;
    clearTables();
    auto gBackGr = ui->lbCellsMonitorTableBorderBackground->geometry();
    auto gL = ui->tableViewLeft->geometry();
    auto gR = ui->tableViewRight->geometry();


    if(tablesNum == TwoTables) { // 13
        MODEL_ROWS_IN_ONE_TABLE = 13;
        auto one_half = (double)gBackGr.width()/2.0;

        initTableView(ui->tableViewLeft, doInitForCellVoltagArray); // w=501 // x=340
        ui->tableViewLeft->setGeometry(gL.x(),
                                       gL.y(),
                                       one_half + 20,
                                       gL.height()
                                       );
        ui->tableViewMiddle->hide();
        ui->tableViewRight->setGeometry(gL.x() + gBackGr.width()/2,
                                        gL.y(),
                                        one_half - 3,
                                        gL.height()
                                        );

        initTableView(ui->tableViewRight, doInitForCellVoltagArray); // w=491 // x=830
    }
    else if(tablesNum == ThreeTables) { // 11
        //340
        //650
        //980

        //331
        //341
        //341

        MODEL_ROWS_IN_ONE_TABLE = 11;
        auto one_third = (double)gBackGr.width()/3.0;

        ui->tableViewLeft->setGeometry(gL.x(),
                                       gL.y(),
                                       (one_third * 1) + 10,
                                       gL.height()
                                       );

        ui->tableViewMiddle->setGeometry(gL.x() + (one_third * 1), //( (2.0 * (double)gBackGr.width()) / 3.0),
                                  gL.y(),
                                  (one_third * 1) + 10,
                                  gL.height()
                                  );
        ui->tableViewMiddle->show();

        ui->tableViewRight->setGeometry(gL.x() + (one_third * 2),
                                        gL.y(),
                                        (one_third * 1) - 3,
                                        gL.height()
                                        );

        initTableView(ui->tableViewLeft, doInitForCellVoltagArray);
        initTableView(ui->tableViewMiddle, doInitForCellVoltagArray);
        initTableView(ui->tableViewRight, doInitForCellVoltagArray);
    }
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////
///
///////////////////////////////////////////////////////////////////////////////////////////////////////////



void CellsMonitorPage::cellsReceived(int cellCount, QVector<double> cellVoltageArray)
{
    mCellVoltageArray.clear();
    mCellVoltageArray.resize(cellCount);

    QVector<double> dataxNew;
    dataxNew.clear();
    QVector<double> datayNormal;
    datayNormal.clear();
    QVector<double> datayBalance;
    datayBalance.clear();
    QVector<QString> labels;
    int indexPointer = 0;

    double cellHardUnder = mDieBieMS->bmsConfig()->getParamDouble("cellHardUnderVoltage");
    double cellHardOver  = mDieBieMS->bmsConfig()->getParamDouble("cellHardOverVoltage");

    for(indexPointer = 0; indexPointer < cellCount; indexPointer++)
    {
        mCellVoltageArray[indexPointer].voltage = cellVoltageArray[indexPointer];

        dataxNew.append(indexPointer + 1);

        if(cellVoltageArray[indexPointer] < 0.0){
            datayNormal.append(0.0);
            datayBalance.append(fabs(cellVoltageArray[indexPointer]));
        }else{
            datayNormal.append(fabs(cellVoltageArray[indexPointer]));
            datayBalance.append(0.0);
        }

        QString voltageString = QStringLiteral("%1V (C").arg(fabs(cellVoltageArray[indexPointer]), 0, 'f', 2);
        labels.append(voltageString + QString::number(indexPointer) + ")");

        bool BALANCE_ON_IS_SAME_AS_EQUAL_ZERO = (datayBalance.last() == 0.0);
        BALANCE_ON_IS_SAME_AS_EQUAL_ZERO = !BALANCE_ON_IS_SAME_AS_EQUAL_ZERO;
        mCellVoltageArray[indexPointer].balancing = BALANCE_ON_IS_SAME_AS_EQUAL_ZERO;
    }


    initTableView(m_tablesNumber, true);


    //QSharedPointer<QCPAxisTickerText> textTicker(new QCPAxisTickerText);
    //textTicker->addTicks(dataxNew, labels);

    //ui->cellBarGraph->xAxis->setTicker(textTicker);
    //ui->cellBarGraph->xAxis->setRange(0.5, indexPointer + 0.5);
    //ui->cellBarGraph->yAxis->setRange(cellHardUnder, cellHardOver);
    //barsNormal->setData(dataxNew, datayNormal);
    //barsBalance->setData(dataxNew, datayBalance);
}

void CellsMonitorPage::appendDoubleAndTrunc(QVector<double> *vec, double num, int maxSize)
{
    vec->append(num);

    if(vec->size() > maxSize) {
        vec->remove(0, vec->size() - maxSize);
    }
}






void CellsMonitorPage::on_editCols_textChanged(const QString &arg1)
{
    m_tablesNumber = (arg1).toInt();
    int cells = (ui->editCells->text()).toInt();

    mCellVoltageArray.clear();

    for(int i = 0, ilen = cells; i<ilen ;++i)
    {
        CellInfo c;
        c.voltage = (double)(i*3);
        c.balancing = (bool)(i%3);

        mCellVoltageArray.push_back(c);
    }

    initTableView(m_tablesNumber, false);
}

void CellsMonitorPage::on_editCells_textChanged(const QString &arg1)
{
    m_tablesNumber = (ui->editCols->text()).toInt();
    int cells = (arg1).toInt();

    mCellVoltageArray.clear();

    for(int i = 0, ilen = cells; i<ilen ;++i)
    {
        CellInfo c;
        c.voltage = (double)(i*3);
        c.balancing = (bool)(i%3);

        mCellVoltageArray.push_back(c);
    }

    initTableView(m_tablesNumber, false);
}

void CellsMonitorPage::on_pbTestOne_clicked()
{
    mCellVoltageArray.clear();
    for(int i = 0, ilen = 21; i<ilen ;++i)
    {
        CellInfo c;
        c.voltage = (double)(i*3);
        c.balancing = (bool)(i%3);

        mCellVoltageArray.push_back(c);
    }

    initTableView(m_tablesNumber, true);
}

void CellsMonitorPage::on_pbTestTwo_clicked()
{
    mCellVoltageArray.clear();
    for(int i = 0, ilen = 21; i<ilen ;++i)
    {
        CellInfo c;
        c.voltage = (double)(i*4);
        c.balancing = (bool)(i%4);

        mCellVoltageArray.push_back(c);
    }

    initTableView(m_tablesNumber, true);
}
