/*****************************************************************************
 *
 * Testmanager - Graphical Automation and Visualisation Tool
 *
 * Copyright (C) 2019  Florian Pose <fp@igh.de>
 *
 * This file is part of Testmanager.
 *
 * Testmanager is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option)
 * any later version.
 *
 * Testmanager is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with Testmanager. If not, see <http://www.gnu.org/licenses/>.
 *
 ****************************************************************************/

#include "TooltipMatrix.h"

#include <pdcom/Variable.h>

#include <QPainter>
#include <QResizeEvent>
#include <QDebug>

/****************************************************************************/

TooltipMatrix::TooltipMatrix(
        QWidget *parent
        ):
    QFrame(parent),
    variable(nullptr),
    dataPresent(false),
    rowCount(0),
    columnCount(0),
    fieldSize(20, 20)
{
}

/****************************************************************************/

TooltipMatrix::~TooltipMatrix()
{
    clearVariable();
}

/****************************************************************************/

void TooltipMatrix::setVariable(PdCom::Variable *var, double period)
{
    clearVariable();

    if (not var) {
        return;
    }

    if (var->dimension.size() < 1 or var->dimension.size() > 2) {
        qWarning() << "invalid dimension size " << var->dimension.size();
        return;
    }

    if (var->dimension.size() == 1) {
        rowCount = 1;
        columnCount = var->dimension[0];
    }
    else { // 2
        rowCount = var->dimension[0];
        columnCount = var->dimension[1];
    }

    try {
        var->subscribe(this, period);
    }
    catch (PdCom::VariableException &e) {
        QString msg(
                tr("Variable subscription"
                    " failed: %1").arg(e.what()));
        qWarning() << msg;
        rowCount = 0;
        columnCount = 0;
        return;
    }

    if (period == 0.0) {
        try {
            var->poll(this);
        }
        catch (PdCom::VariableException &e) {
            QString msg(
                    tr("Variable polling"
                        " failed: %1").arg(e.what()));
            qWarning() << msg;
            rowCount = 0;
            columnCount = 0;
            return;
        }
    }

    variable = var;
    setMinimumSize(columnCount * fieldSize.width(),
            rowCount * fieldSize.height());
}

/****************************************************************************/

void TooltipMatrix::clearVariable()
{
    if (variable) {
        variable->unsubscribe(this);
        variable = nullptr;
        dataPresent = false;
        rowCount = 0;
        columnCount = 0;
        fieldSize = QSize(20, 20);
        setMinimumSize(0, 0);
        update();
    }
}

/****************************************************************************/

void TooltipMatrix::resizeEvent(QResizeEvent *)
{
}

/****************************************************************************/

void TooltipMatrix::paintEvent(QPaintEvent *event)
{
    QFrame::paintEvent(event);

    if (rowCount <= 0 or columnCount <= 0) {
        return;
    }

    QPainter painter(this);

    int rowHeight = contentsRect().height() / rowCount;
    int colWidth = contentsRect().width() / columnCount;

    double value[variable->dimension.getElementCount()];
    variable->getValue(value, variable->dimension.getElementCount());

    QLocale loc;
    QRect bound;
    int maxWidth = 0;
    int maxHeight = 0;

    for (int row = 0; row < rowCount; row++) {
        for (int col = 0; col < columnCount; col++) {
            QRect rect(contentsRect().left() + colWidth * col,
                    contentsRect().top() + rowHeight * row,
                    colWidth, rowHeight);
            rect.adjust(1, 1, -1, -1);
            painter.fillRect(rect, QPalette().base());

            if (dataPresent) {
                rect.adjust(1, 1, -1, -1);
                QString text(
                        loc.toString(value[row * columnCount + col], 'g', 3));
                painter.drawText(rect, Qt::AlignRight | Qt::AlignVCenter,
                        text, &bound);
                if (bound.width() > maxWidth) {
                    maxWidth = bound.width();
                }
                if (bound.height() > maxHeight) {
                    maxHeight = bound.height();
                }
            }
        }
    }

    maxWidth += 4;
    maxHeight += 4;
    if (maxWidth > fieldSize.width()) {
        fieldSize.setWidth(maxWidth);
        setMinimumSize(columnCount * fieldSize.width(),
                rowCount * fieldSize.height());
    }
    if (maxHeight > fieldSize.height()) {
        fieldSize.setHeight(maxHeight);
        setMinimumSize(columnCount * fieldSize.width(),
                rowCount * fieldSize.height());
    }
}

/****************************************************************************/

void TooltipMatrix::notify(PdCom::Variable *)
{
    dataPresent = true;
    update();
}

/****************************************************************************/

void TooltipMatrix::notifyDelete(PdCom::Variable *)
{
    variable = nullptr;
    dataPresent = false;
    update();
}

/****************************************************************************/
