/*****************************************************************************
 *
 * Testmanager - Graphical Automation and Visualisation Tool
 *
 * Copyright (C) 2018 - 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 "SvgPluginDialog.h"

#include <QAbstractTableModel>
#include <QDebug>
#include <QLineEdit>
#include <QCompleter>


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

class SvgPluginDialog::Model:
    public QAbstractTableModel
{
    public:
        Model(Pd::Svg &svg, QList<SvgPlugin::Row> &attributes):
            svg(svg),
            rows(attributes)
        {
        }

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

        int rowCount(const QModelIndex &index) const
        {
            if (index.isValid()) {
                return 0;
            }
            else {
                return rows.size();
            }
        }

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

        int columnCount(const QModelIndex &) const
        {
            return 1;
        }

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

        QVariant data(const QModelIndex &index, int role) const
        {
            if (!index.isValid() || index.row() < 0 || index.row() >= rows.size())
                return QVariant();

            switch (role) {
                case Qt::DisplayRole:
                case Qt::EditRole:
                    return rows[index.row()].id;

                case Qt::ForegroundRole:
                    if (!rows[index.row()].available) {
                        return QColor(Qt::red);
                    }
                    return QVariant();

                default:
                    return QVariant();
            }
        }

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

        /** Appends new data line in dialog table.
         */
        bool setData(const QModelIndex &index, const QVariant &value, int role)
        {
            if (role != Qt::EditRole || !index.isValid()
                    || index.row() < 0 || index.row() >= rows.size()
                    || index.column() != 0)
            {
                return false;
            }

            switch (index.column()) {
                case 0: // id
                    rows[index.row()].id = value.toString();
                    rows[index.row()].available = svg.existId(rows[index.row()].id);
                    return true;
            }

            return false;
        }

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

        QVariant headerData(int section, Qt::Orientation o, int role) const {
            Q_UNUSED(section);

            if (role == Qt::DisplayRole && o == Qt::Horizontal) {
                return SvgPluginDialog::tr("Attribute ID");
            }
            else {
                return QVariant();
            }
        }

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

        Qt::ItemFlags flags(const QModelIndex &index) const {
            if (!index.isValid()) {
                return Qt::NoItemFlags;
            }

            return Qt::ItemIsEnabled | Qt::ItemIsEditable |
                Qt::ItemIsSelectable;
        }

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

        void addRow() {
            beginInsertRows(QModelIndex(), rows.size(), rows.size());
            SvgPlugin::Row row;
            rows.append(row);
            endInsertRows();
        }

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

        void remove(const QModelIndexList &indexes) {
            QList<QPersistentModelIndex> persistentIndexes;

            foreach (QModelIndex index, indexes) {
                persistentIndexes << index;
            }

            foreach (const QPersistentModelIndex &index, persistentIndexes) {
                if (index.isValid()) {
                    beginRemoveRows(QModelIndex(), index.row(), index.row());
                    rows.removeAt(index.row());
                    endRemoveRows();
                }
            }
        }

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


    private:
        Pd::Svg &svg;
        QList<SvgPlugin::Row> &rows;
};

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

SvgPluginDialog::SvgPluginDialog(
        Pd::Svg &svg,
        QList<SvgPlugin::Row> &rows,
        QWidget *parent
        ):
    QDialog(parent),
    svgAttributes(rows),
    model(new Model(svg, rows))
{
    setupUi(this);

    tableView->setModel(model);

    connect(tableView->selectionModel(),
            SIGNAL(selectionChanged(const QItemSelection &,
                    const QItemSelection &)),
            this, SLOT(selectionChanged(const QItemSelection &,
                    const QItemSelection &)));

    if (!svg.getSvgPath().isEmpty()) {
        labelSvgPath->setText(svg.getSvgPath());
    }
    else {
        labelSvgPath->setText("No file loaded.");
        labelSvgPath->setStyleSheet("color:red");
    }

    /** Implement autocomplete for the table. */
    QStringList idList = svg.getIdList();
    tableView->setEditTriggers(QAbstractItemView::AllEditTriggers);
    tableView->setItemDelegate(new SvgPluginDelegate(tableView, idList));
}

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

SvgPluginDialog::~SvgPluginDialog()
{
    tableView->setModel(nullptr);
    delete model;
}

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

void SvgPluginDialog::on_buttonBox_accepted()
{
    accept();
}

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

void SvgPluginDialog::on_toolButtonAdd_clicked()
{
    model->addRow();
}

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

void SvgPluginDialog::on_toolButtonRemove_clicked()
{
    model->remove(tableView->selectionModel()->selectedIndexes());
}

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

void SvgPluginDialog::selectionChanged(const QItemSelection &,
        const QItemSelection &)
{
    toolButtonRemove->setEnabled(tableView->selectionModel()->hasSelection());
}

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

/** Delegate class for autocomplete function in dialog.
*/
SvgPluginDelegate::SvgPluginDelegate(
        QObject *parent,
        QStringList list
        ):
    QItemDelegate(parent),
    stringList(list)
{
}

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

QWidget* SvgPluginDelegate::createEditor(
        QWidget* parent,
        const QStyleOptionViewItem& option,
        const QModelIndex& index
        ) const
{
    QWidget* editor = QItemDelegate::createEditor(parent, option, index);
    QLineEdit* lineEdit = dynamic_cast<QLineEdit*>(editor);

    if (lineEdit) {
        QCompleter* completer = new QCompleter(stringList, lineEdit);
        lineEdit->setCompleter(completer);
    }
    
    return editor;
}

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