#include "TypeSelectionItemModel.h"
//#include "CustomDataRole.h"
#include "catalog/PgTypeContainer.h"
#include <algorithm>

TypeSelectionItemModel::TypeSelectionItemModel(QObject *parent)
	: QAbstractListModel(parent)
{
}

int TypeSelectionItemModel::rowCount(const QModelIndex &/*parent*/) const
{
	int result = static_cast<int>(m_types.size());
//	if (!parent.isValid()) {

//	}
	return result;
}

int TypeSelectionItemModel::columnCount(const QModelIndex &/*parent*/) const
{
	int result = 2;
//	if (parent.isValid())
//		result = 1;


	return result;
}

QVariant TypeSelectionItemModel::data(const QModelIndex &index, int role) const
{
	QVariant result;
	if (index.isValid()) {
		int row = index.row();
		int column = index.column();
		if (role == Qt::DisplayRole) {
			//const PgType &tp = m_types->getByIdx(row);
			if (column == 0) {
				result = m_types[static_cast<size_t>(row)]; //tp.typname;

			}
		}
	}
	return result;
}

void TypeSelectionItemModel::setTypeList(std::shared_ptr<const PgTypeContainer> types)
{
	beginResetModel();
	m_types.clear();
	if (types) {
		for (const auto &e : *types) {
			if (e.category != TypCategory::Array && e.type != "c") {
				m_types.push_back(e.objectName());
			}
		}
		std::sort(m_types.begin(), m_types.end());
	}
	//emit dataChanged(this->createIndex(0, 0), this->createIndex(types->count(), 0), QVector<int>() << Qt::DisplayRole);
    endResetModel();
}

// ----------------


TypeModel::TypeModel(QObject *parent)
	: QAbstractListModel(parent)
{
}

int TypeModel::rowCount(const QModelIndex &/*parent*/) const
{
	if (m_types)
		return static_cast<int>(m_types->count());

	return 0;
}

int TypeModel::columnCount(const QModelIndex &/*parent*/) const
{
	return colCount;
}

QVariant TypeModel::data(const QModelIndex &index, int role) const
{
//    if (role == CustomDataTypeRole)
//            return getType(index.column());

	if (index.isValid()) {
		int row = index.row();
		int column = index.column();
		if (role == Qt::DisplayRole) {
			//const PgType &tp = m_types->getByIdx(row);
			auto elem = m_types->getByIdx(row);
			switch (column) {
			case OidCol: return elem.oid();
			case NameCol: return elem.objectName();
            case NamespaceCol: return elem.nsName();
            case OwnerCol: return elem.ownerName();
            case CategoryCol: return TypCategoryString(elem.category);
			}
		}
	}
    return QVariant();
}

QString TypeModel::TypCategoryString(TypCategory tc)
{
    switch (tc) {
    case TypCategory::Array:
        return tr("array");
    case TypCategory::Boolean:
        return tr("boolean");
    case TypCategory::Composite:
        return tr("composite");
    case TypCategory::DateTime:
        return tr("datetime");
    case TypCategory::Enum:
        return tr("enum");
    case TypCategory::Geometric:
        return tr("geometric");
    case TypCategory::NetworkAddress:
        return tr("networkaddress");
    case TypCategory::Numeric:
        return tr("numeric");
    case TypCategory::Pseudo:
        return tr("pseude");
    case TypCategory::Range:
        return tr("range");
    case TypCategory::String:
        return tr("string");
    case TypCategory::Timespan:
        return tr("timespan");
    case TypCategory::UserDefined:
        return tr("user");
    case TypCategory::BitString:
        return tr("bitstring");
    case TypCategory::Unknown:
        return tr("unknown");
    }
    return "?";
}

Oid TypeModel::getType(int column) const
{
    switch (column) {
    case OidCol:
        return Pgsql::oid_oid;
    case NameCol:
    case NamespaceCol:
    case OwnerCol:
    case CategoryCol:
        return Pgsql::varchar_oid;
    }
    return InvalidOid;
}

void TypeModel::setTypeList(std::shared_ptr<const PgTypeContainer> types)
{
	beginResetModel();
	m_types = types;
    endResetModel();
}

PgType TypeModel::typ(int row) const
{
    return m_types->getByIdx(row);
}

QVariant TypeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Horizontal) {
        if (role == Qt::DisplayRole) {
            switch (section) {
            case OidCol: return tr("Oid");
            case NameCol: return tr("Name");
            case NamespaceCol: return tr("Schema");
            case OwnerCol: return tr("Owner");
            case CategoryCol: return tr("Category");
            }
        }
    }
    return {};
}
