#include <QtWidgets>
#include "tablemodel.h"

//
// Public Functions
//
/**
 * Empty constructor. Pass parent parameter
 * to parent constructor.
 */
TableModel::TableModel(QObject *parent)
    : QAbstractTableModel(parent)
{
    columnTitles = QStringList();
    rowTitles = QStringList();
    contents = QList<QList<double> >();
}

/**
 * Changes the table values in the model.
 * @param {QList<QList<double> >} c - a 2D list of all
 *     values in the table
 */
void TableModel::setContents(const QList<QList<double> > c)
{
    beginResetModel();
    contents = c;
    endResetModel();
}

/**
 * Sets the titles of the table's rows.
 * @param {QStringList} rt - a list of row titles
 */
void TableModel::setRowTitles(QStringList rt)
{
    beginResetModel();
    rowTitles = rt;
    endResetModel();
}

/**
 * Sets the titles of the table's columns.
 * @param {QStringList} ct - a list of column titles
 */
void TableModel::setColumnTitles(QStringList ct)
{
    beginResetModel();
    columnTitles = ct;
    endResetModel();
}

/**
 * Returns the number of rows in the table.
 * @return {int} the number of rows
 */
int TableModel::rowCount(const QModelIndex & /* parent */) const
{
    return contents.length();
}

/**
 * Returns the number of columns in the table.
 * @return {int} the number of columns
 */
int TableModel::columnCount(const QModelIndex & /* parent */) const
{
    if (contents.length() <= 0)
        return 0;
    return contents.at(0).length();
}

/**
 * Returns data from the table, taking a position and a role
 * for the data.
 * @param {&QModelIndex} index - indicates where in the table
 *     the information should be taken from.
 * @param {int} role - indicates what the data being requested
 *     will be used for
 * @return {QVariant} the data requested, either a value from
 *     the table or an alignment
 */
QVariant TableModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (role == Qt::TextAlignmentRole) {
        return int(Qt::AlignRight | Qt::AlignVCenter);
    } else if (role == Qt::DisplayRole) {
        // If the data will be used for display, return the
        // value from the table at the given index.
        return contents.at(index.row()).at(index.column());
    }
    return QVariant();
}

/**
 * Returns text to be displayed in the header.
 * @param {int} section - index of header content
 * @param {Qt::Orientation} orientation - indicates if
 *     the header is for rows or columsn
 * @param {int} role - indicates what the data will be
 *     used for
 * @return {QVariant} the text to display in the header
 */
QVariant TableModel::headerData(int section,
                                Qt::Orientation orientation,
                                int role) const
{
    if (role != Qt::DisplayRole)
        return QVariant();
    // Check to make sure that the index requested
    // is present in the list of titles the model has.
    if (orientation == Qt::Horizontal)
        if (section < columnTitles.length())
            return columnTitles.at(section);
    if (orientation == Qt::Vertical)
        if (section < rowTitles.length())
            return rowTitles.at(section);
    return QVariant();
}

/**
 * Returns the table's values as a 2D list.
 * @return {QList<QList<double> >} the table's contents as
 *     a 2D list
 */
QList<QList<double> > TableModel::getContents() const
{
    return contents;
}

/**
 * Returns the list of row titles.
 * @return {QStringList} the list of row titles
 */
QStringList TableModel::getRowTitles() const
{
    return rowTitles;
}

/**
 * Returns the list of column titles.
 * @return {QStringList} the list of column titles
 */
QStringList TableModel::getColumnTitles() const
{
    return columnTitles;
}

/**
 * Returns the list of column titles without duplicates.
 * @return {QStringList} the list of column titles
 */
QStringList TableModel::getUniqueColumnTitles() const
{
    QStringList cols = columnTitles;
    cols.removeDuplicates();
    return cols;
}

void TableModel::showColumn(int col)
{

}

void TableModel::hideColumn(int col)
{

}
