/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK 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 Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/

#include "Tabular.h"

#include "MMLMonitorDisplayFactory.h"
#include "MMLDisplay.h"
#include "MMLComponent.h"

#include <monitoringgui/MonitoringGuiManager.h>
#include <monitoringgui/MonitoringDialog.h>

#include <QHeaderView>
#include <QApplication>

bool tabularRegistered = MMLMonitorDisplayFactory::getInstance()->registerClass<Tabular>("Tabular");

Tabular::Tabular(Monitor* monitor, MMLComponent* manager): MMLMonitorDisplay(monitor, manager) {
    QTableWidget* t = manager->getMonitoringGuiManager()->getDialog()->getMonitorsTableWidget();
    line = manager->getDisplay()->getDisplayedMonitorLine();
    int j = t->columnCount();
    oldRowSize = t->rowHeight(line);
    t->setColumnCount(j + 1);
    auto* item = new QTableWidgetItem();
    item->setText(("Tabular"));
    t->setHorizontalHeaderItem(j, item);
    table = new QTableWidget;
    table->setEditTriggers(QAbstractItemView::NoEditTriggers);
    t->setCellWidget(line, j, table);
    table->installEventFilter(this);
}

Tabular::~Tabular() {
    if (table) {
        delete table;
        table = nullptr;
    }
}

// ---------------------- update ----------------------------
void Tabular::update() {
    table->clear();
    QTableWidget* t = manager->getMonitoringGuiManager()->getDialog()->getMonitorsTableWidget();
    QString s;
    QStringList labels;
    switch (monitor->getValueType()) {

        case Monitor::SCALAR:
            table->setColumnCount(1);
            table->setRowCount(1);
            table->setItem(0, 0, new QTableWidgetItem(s.setNum(monitor->getValue(0))));
            table->verticalHeader()->hide();
            table->horizontalHeader()->hide();
            break;

        case Monitor::SCALARSET:
            table->setColumnCount(monitor->getNumberOfIndex());
            table->setRowCount(1);
            for (unsigned int j = 0; j < monitor->getNumberOfIndex(); j++) {
                QTableWidgetItem* item1 = new QTableWidgetItem();
                item1->setText(s.setNum(monitor->getIndexOfValues(j)));
                table->setHorizontalHeaderItem(j, item1);
                table->setItem(0, j, new QTableWidgetItem(s.setNum(monitor->getValue(j))));
            }
            table->verticalHeader()->hide();
            t->setRowHeight(line, 3 * table->rowHeight(0));
            break;

        case Monitor::VECTORSET:
            table->setColumnCount(monitor->getNumberOfIndex());
            table->setRowCount(3);
            for (unsigned int j = 0; j < monitor->getNumberOfIndex(); j++) {
                QTableWidgetItem* item2 = new QTableWidgetItem();
                item2->setText(s.setNum(monitor->getIndexOfValues(j)));
                table->setHorizontalHeaderItem(j, item2);
                for (unsigned int i = 0; i < 3; i++) {
                    table->setItem(i, j, new QTableWidgetItem(s.setNum(monitor->getValue(3 * j + i))));
                }
            }
            labels << "x" << "y" << "z";
            table->setVerticalHeaderLabels(labels);
            t->setRowHeight(line, 5 * table->rowHeight(0));
            break;

        case Monitor::MATRIX_33SET:
            table->setColumnCount(monitor->getNumberOfIndex());
            table->setRowCount(6);
            for (unsigned int j = 0; j < monitor->getNumberOfIndex(); j++) {
                QTableWidgetItem* item3 = new QTableWidgetItem();
                item3->setText(s.setNum(monitor->getIndexOfValues(j)));
                table->setHorizontalHeaderItem(j, item3);
                for (unsigned int i = 0; i < 6; i++) {
                    table->setItem(i, j, new QTableWidgetItem(s.setNum(monitor->getValue(6 * j + i))));
                }
            }
            labels << "1,1" << "1,2" << "1,3"  << "2,1" << "2,2" << "2,3"  << "3,1" << "3,2" << "3,3";
            table->setVerticalHeaderLabels(labels);
            t->setRowHeight(line, 9 * table->rowHeight(0));
            break;
    }
}

// ---------------------- hide ----------------------------
void Tabular::hide() {
    table->clear();
    QTableWidget* t = manager->getMonitoringGuiManager()->getDialog()->getMonitorsTableWidget();
    int i = t->columnCount();
    t->removeColumn(i - 1);
    t->setColumnCount(i - 1);
    t->setRowHeight(line, oldRowSize);
}

// ---------------------- copy ----------------------------
void Tabular::copy() {
    QList<QTableWidgetSelectionRange> list = table->selectedRanges();
    if (list.size() > 0) {
        QTableWidgetSelectionRange range = list[0];
        QString str;
        for (int i = 0; i < range.rowCount(); ++i) {
            if (i > 0) {
                str += "\n";
            }
            for (int j = 0; j < range.columnCount(); ++j) {
                if (j > 0) {
                    str += " ";
                }
                str += table->item(range.topRow() + i, range.leftColumn() + j)->text();
            }
        }
        QApplication::clipboard()->setText(str);
    }
}

// ---------------------- eventFilter ----------------------------
bool Tabular::eventFilter(QObject* obj, QEvent* event) {
    if (event->type() == QEvent::ContextMenu) {
        auto* mEvent = static_cast<QMouseEvent*>(event);
        QMenu menu(table);
        menu.addAction("special copy for spreadsheet", this, SLOT(copy()));
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
        menu.exec(mEvent->globalPos());
#else
        menu.exec(mEvent->globalPosition().toPoint());
#endif
        return true;
    }
    else {
        // standard event processing
        return QObject::eventFilter(obj, event);
    }
}


