#include <QApplication>

#include "melview.h"

class ClassComboBox: public QComboBox
{
public:
  ClassComboBox(QWidget *parent = 0)
    : QComboBox(parent)
  {
    addItem("Signal");
    addItem("Unknown");
    addItem("Unclassified Noise");
    addItem("Movement");
    addItem("Cardiac");
    addItem("White Matter");
    addItem("Non-brain");
    addItem("MRI");
    addItem("Susceptability-motion");
    setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
  }
};

QWidget *ICDelegate::createEditor(QWidget *parent,
				  const QStyleOptionViewItem &option,
				  const QModelIndex &index) const
{
  if(index.column() == 0) {
    QCheckBox *editor = new QCheckBox(parent);
    return editor;
  } else if(index.column() == 1) {
    ClassComboBox *editor = new ClassComboBox(parent);
    return editor;
  } else
    return QStyledItemDelegate::createEditor(parent, option, index);
}

void ICDelegate::setEditorData(QWidget *editor,
			       const QModelIndex &index) const
{
  if(QComboBox *cb = qobject_cast<QComboBox *>(editor)) {
    // Do the combo box thingy here
    int i = cb->findText(index.data(Qt::EditRole).toString());
    if(i >= 0)
      cb->setCurrentIndex(i);
  } else
    QStyledItemDelegate::setEditorData(editor, index);
}

void ICDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
				    const QModelIndex &index) const
{
  if(QComboBox *cb = qobject_cast<QComboBox *>(editor)) {
    // Do the combo box thingy here
    model->setData(index, cb->currentText(), Qt::EditRole);
  } else
    QStyledItemDelegate::setModelData(editor, model, index);
}

void ICDelegate::updateEditorGeometry(QWidget *editor, 
				      const QStyleOptionViewItem &option,
				      const QModelIndex &index) const
{
  editor->setGeometry(option.rect);
}

void ICDelegate::paint(QPainter *painter, 
		       const QStyleOptionViewItem &option,
		       const QModelIndex &index) const
{
  if (index.column() == 0) {
    bool data = index.model()->data(index, Qt::DisplayRole).toBool();
    QStyleOptionButton cbstyle;
    cbstyle.rect = option.rect;
    if(data)
      cbstyle.state = QStyle::State_On|QStyle::State_Enabled;
    else
      cbstyle.state = QStyle::State_Off|QStyle::State_Enabled;

    QApplication::style()->drawControl(QStyle::CE_CheckBox, &cbstyle, painter);
  } else
    QStyledItemDelegate::paint(painter, option, index);
}

class ICModel : public QAbstractTableModel
{
public:
  ICModel(QObject *parent = 0);

  void setICData(const QList< QPair<QString, bool> > &data);

  int rowCount(const QModelIndex &parent = QModelIndex()) const;
  int columnCount(const QModelIndex &parent = QModelIndex()) const;

  Qt::ItemFlags flags(const QModelIndex &index) const
  {
    return QAbstractTableModel::flags(index) |
      Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
  }

  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
  bool  setData(const QModelIndex &index, const QVariant &value,
		int role);

  QVariant headerData(int section, Qt::Orientation orientation, 
		      int role = Qt::DisplayRole) const;
  
private:
  QList< QPair<QString, bool> > icData;
  QStringList headers;
};

ICModel::ICModel(QObject *parent)
  : QAbstractTableModel(parent)
{
  headers << "Filter"
	  << "Classification";
}

void ICModel::setICData(const QList< QPair<QString, bool> > &data)
{
  icData = data;
  reset();
}
			
int ICModel::rowCount(const QModelIndex & /* parent */) const
{
  return 50;
}

int ICModel::columnCount(const QModelIndex & /* parent */) const
{
  return 2;
}

bool ICModel::setData(const QModelIndex &index, const QVariant &value,
		   int role)
{
  if (index.isValid() && role == Qt::EditRole) {
    int row(index.row());
    
    QPair<QString, bool> p = icData.value(row);

    if (index.column() == 0)
      p.second = value.toBool();
    else if (index.column() == 1)
      p.first = value.toString();
    else
      return false;

    icData.replace(row, p);
    emit(dataChanged(index, index));

    return true;
  }
  return false;
}

QVariant ICModel::data(const QModelIndex &index, int role) const
{
  if (!index.isValid())
    return QVariant();

  if ((role == Qt::CheckStateRole) && (index.column() == 0))
    return true;

  if (role == Qt::DisplayRole) {
    QPair<QString, bool> d = icData.at(index.row());
    if(index.column() == 0)
      return d.second;
    else if(index.column() == 1)
      return d.first;
  }
  
  return QVariant();
}

QVariant ICModel::headerData(int section,
			     Qt::Orientation orientation,
			     int role) const
{
  if ((role == Qt::DisplayRole) && (orientation == Qt::Vertical))
    return QString::number(section + 1);
  if ((role == Qt::DisplayRole) && (orientation == Qt::Horizontal) && 
      (section < headers.length()))
    return headers.at(section);
    
  return QVariant();
}


MelodicView::MelodicView(QWidget *parent)
  : QMainWindow(parent)
{
  setupUi(this);

  ICModel *model =  new ICModel(this);
  icTable->setModel(model);

  QList< QPair<QString, bool> > ics;

  icTable->setItemDelegate(new ICDelegate(icTable));
  icTable->setEditTriggers(QAbstractItemView::DoubleClicked);
  for (int r = 0; r < 50; ++r) {
    if( r % 2) 
      ics.append( QPair<QString, bool>("Unknown", false) );
    else
      ics.append( QPair<QString, bool>("MRI", true) );
  }
  QStringList headers;
  headers << "Filter" << "Classification";
  // icTable->setHorizontalHeaderLabels(headers);
  
  model->setICData(ics);
  icTable->horizontalHeader()->setMinimumSectionSize(10);
  icTable->verticalHeader()->setMinimumSectionSize(10);

  icTable->resizeColumnsToContents();
  icTable->resizeRowsToContents();

  icTable->show();

  statusbar->showMessage(QString("ready"), 3000);
}

// void MelodicView::on_icTable_cellActivated(int r, int c)
// {
//   statusbar->showMessage(QString("cellActivated(%1, %2)").arg(r).arg(c), 3000);
// }

int main(int argc, char *argv[])
{
  //  Q_INIT_RESOURCE(application);

  QApplication app(argc, argv);
  
  app.setOrganizationName("FMRIB");
  app.setApplicationName("Melodic Viewer");

  MelodicView  mv;
  mv.show();

  return app.exec();
}
