#include "HaskellModel.h"

#include <sstream>

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

HaskellModel::~HaskellModel() {
}

int HaskellModel::rowCount(const QModelIndex & parent) const {
    if (parent.isValid()) {
        return 0;
    } else if (delegates[delegateHandle].callbacks && delegates[delegateHandle].callbacks->rowCountCb) {
        return delegates[delegateHandle].callbacks->rowCountCb();
    } else {
        return 0;
    }
} 

int HaskellModel::columnCount(const QModelIndex & parent) const {
  if (delegates[delegateHandle].callbacks && delegates[delegateHandle].callbacks->columnCountCb) {
    return delegates[delegateHandle].callbacks->columnCountCb();
  } else {
    return 0;
  }
}

QVariant HaskellModel::data(const QModelIndex & parent, int role) const {
    QVariant* ptr;
    if ((Qt::UserRole <= role) && parent.isValid() && delegates[delegateHandle].callbacks && delegates[delegateHandle].callbacks->dataCb) {
     ptr = reinterpret_cast<QVariant*>(delegates[delegateHandle].callbacks->dataCb(parent.row(), role - Qt::UserRole));
     QVariant value = *ptr;
     delete ptr;
     return value;
   } else {
     return QVariant();
   }
} 

QVariant HaskellModel::headerData(int column, Qt::Orientation, int role) {
  if((Qt::DisplayRole == role) && delegates[delegateHandle].callbacks && delegates[delegateHandle].callbacks->headerDataCb) {
    return delegates[delegateHandle].callbacks->headerDataCb(column);
  } else {
    return QVariant();
  }
}

int HaskellModel::delegate() const {
    return delegateHandle;
}

void HaskellModel::setDelegate(int handle) {
    delegateHandle = handle;
}

QHash<int,QByteArray> HaskellModel::roleNames() const {
  return delegates[delegateHandle].roles;
}

/* static */ HaskellModelDelegateHandle HaskellModel::registerDelegate() {
  HaskellModelDelegate dlg;
  dlg.callbacks = NULL;
  dlg.roles = QHash<int,QByteArray>();
  delegates.push_back(dlg);
  return delegates.size() - 1;
}

/* static */ void HaskellModel::unregisterDelegate(HaskellModelDelegateHandle hndl) {
  delegates[hndl].callbacks = NULL;
}

/* static */ void HaskellModel::setCallbacks
    ( HaskellModelDelegateHandle hndl
    , HaskellModelCallbacks* cbs
    ) {
  delegates[hndl].callbacks = cbs;
}

/* static */ void HaskellModel::addRole
    ( HaskellModelDelegateHandle hndl
    , int key
    , char* value
    ) {
  delegates[hndl].roles[Qt::UserRole + key] = value;
}

/* static */ std::vector<HaskellModelDelegate> HaskellModel::delegates
  = std::vector<HaskellModelDelegate>();


