#include "TriggerTableModel.h"
#include "catalog/PgDatabaseCatalog.h"
#include "catalog/PgTriggerContainer.h"
#include "CustomDataRole.h"
#include "ScopeGuard.h"

TriggerTableModel::TriggerTableModel(QObject *parent)
	: QAbstractTableModel(parent)
{
}

QVariant TriggerTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
	if (orientation == Qt::Horizontal) {
		if (role == Qt::DisplayRole) {
			switch (section) {
				case NameCol: return tr("Name");
				case EventsCol: return tr("Events");
				case WhenCol: return tr("When");
				case DeferrableCol: return tr("Df");
				case InitiallyCol: return tr("ID");
				case ForCol: return tr("For");
				case CondCol: return tr("Cond.");
//				case ReferencingCol: return tr("Referencing");
				case ProcedureCol: return tr("Function");
			}
		}
	}
	return QVariant();
}

void TriggerTableModel::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
{
	if (cat != m_catalog) {
		m_catalog = cat;
		refreshConnection = connect(m_catalog.get(), &PgDatabaseCatalog::refreshed, this,
									&TriggerTableModel::refresh);
	}
	refresh();
}

int TriggerTableModel::rowCount(const QModelIndex &) const
{
	return m_triggers ? static_cast<int>(m_triggers->count()) : 0;
}


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


QVariant TriggerTableModel::data(const QModelIndex &index, int role) const
{
	if (role == Qt::DisplayRole)
		return getData(index);
	else if (role == CustomDataTypeRole)
		return getType(index.column());
	else if (role == FirstHiddenValue) {
		auto&& t = m_triggers->getByIdx(index.row());
		return t.relid; //
	}
	return QVariant();
}


PgTrigger TriggerTableModel::trigger(int row) const
{
	return m_triggers->getByIdx(row);
}


Oid TriggerTableModel::getType(int column) const
{
	switch (column) {
		case DeferrableCol:
		case InitiallyCol:
			return Pgsql::bool_oid;
	}
	return Pgsql::varchar_oid;
}


QVariant TriggerTableModel::getData(const QModelIndex &index) const
{
	auto&& t = m_triggers->getByIdx(index.row());
	switch (index.column()) {
	case NameCol: return t.objectName();
	case EventsCol: return t.eventAbbr();
	case WhenCol: return t.typeFireWhen();
	case DeferrableCol: return t.deferrable;
	case InitiallyCol: return t.initdeferred;
	case ForCol: return t.forEach();
	case CondCol: return t.whenclause;
//	case ReferencingCol: return tr("Referencing");
	case ProcedureCol: return t.procedure();

	}
	return QVariant();
}

void TriggerTableModel::refresh()
{
	beginResetModel();
	SCOPE_EXIT { endResetModel(); };

	m_triggers = m_catalog->triggers();
}
