#include "EditColumnTableModel.h"
#include "catalog/PgDatabaseCatalog.h"
#include "catalog/PgTypeContainer.h"
#include "catalog/PgCollationContainer.h"

EditColumnTableModel::EditColumnTableModel(std::shared_ptr<PgDatabaseCatalog> catalog, QObject *parent)
	: QAbstractTableModel(parent)
	, m_catalog(catalog)
{
	m_data.push_back({});
}

QVariant EditColumnTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
	if (role == Qt::DisplayRole) {
		if (orientation == Qt::Horizontal) {
			switch(section) {
			case NameCol: return tr("Column name");
			case TypeCol: return tr("Type");
			case LengthCol: return tr("Length");
			case ScaleCol: return tr("Scale");
			case CollateCol: return tr("Collate");
			case NotNullCol: return tr("NN");
			case DefaultCol: return tr("Default");
			case PrimaryKeyCol: return tr("P");
			case UniqueCol: return tr("U");
			case CommentCol: return tr("Comment");
			}
		}
	}
	return {};
}

int EditColumnTableModel::rowCount(const QModelIndex &) const
{
	return static_cast<int>(m_data.size());
}

int EditColumnTableModel::columnCount(const QModelIndex &) const
{
	return colCount;
}

QVariant EditColumnTableModel::data(const QModelIndex &index, int role) const
{
	auto rij = static_cast<size_t>(index.row());
	auto && d = m_data.at(rij);
	if (role == Qt::EditRole || role == Qt::DisplayRole) {
		switch (index.column()) {
		case NameCol:       return d.name;
		case TypeCol:
			if (role == Qt::DisplayRole) {
				if (d.type != InvalidOid) {
					auto&& t = m_catalog->types()->getByKey(d.type);
					return t ? t->objectName() : QString();
				}
				return QString();
			}
			else
				return d.type;
		case LengthCol:     return d.length;
		case ScaleCol:      return d.scale;
		case CollateCol:
			if (role == Qt::DisplayRole) {
				if (d.collate != InvalidOid) {
					auto&& c = m_catalog->collations()->getByKey(d.collate);
					return c ? c->objectName() : QString();
				}
				return QString();
			}
			else
				return d.collate;
		case NotNullCol:    return d.notNull;
		case DefaultCol:	return d.def;
		case PrimaryKeyCol: return d.primaryKey;
		case UniqueCol:     return d.unique;
		case CommentCol:    return d.comment;
		}
	}
	return {};
}

Qt::ItemFlags EditColumnTableModel::flags(const QModelIndex &) const
{
	Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
	flags |= Qt::ItemIsEditable;
	return flags;

}

bool EditColumnTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
	auto rij = static_cast<size_t>(index.row());
	auto && d = m_data.at(rij);
	if (role == Qt::EditRole) {
		const int col = index.column();
		if (col == NameCol) {
			d.name = value.toString();
			return true;
		}
		if (col == TypeCol) {
			d.type = value.toUInt();
			return true;
		}
		if (col == LengthCol) {
			d.length = value.toInt();
			return true;
		}
		if (col == ScaleCol) {
			d.scale = value.toInt();
			return true;
		}
		if (col == CollateCol) {
			d.collate = value.toUInt();
			return true;
		}
		if (col == NotNullCol) {
			d.notNull = value.toBool();
			return true;
		}
		if (col == DefaultCol) {
			d.def = value.toString();
			return true;
		}
		if (col == PrimaryKeyCol) {
			d.primaryKey = value.toInt();
			return true;
		}
		if (col == UniqueCol) {
			d.notNull = value.toBool();
			return true;
		}
		if (col == CommentCol) {
			d.comment = value.toString();
			return true;
		}
	}
	return false;
}

bool EditColumnTableModel::removeRows(int , int , const QModelIndex &)
{
	return false;
}

//bool EditColumnTableModel::submit()
//{

//}

//void EditColumnTableModel::revert()
//{

//}
