#include "CurrentDagDock.hpp"
#include "ui_CurrentDagDock.h"
#include "MainWindow.hpp"

//==============================================================================
/**
 * Constructor
 */
CurrentDagDock::CurrentDagDock(MainWindow *parent) :
    QDockWidget(parent),
    _ui(new Ui::CurrentDagDock),
    _digDagData(0),
    currentPatternIndex(0),
    _patternModel(0),
    _tidListModel(0),
    _tidListSelectionModel(0),
    _tidListModelIsComplete(true)
{
  _ui->setupUi(this);

  updateTidListStatusLabel(false);

  setupModelsAndViews();

  connectSlots();


}


/**
 * Destructor
 */
CurrentDagDock::~CurrentDagDock() {
  delete _patternModel;
  delete _tidListModel;
  delete _ui;
}


//==============================================================================
// Getters & setters

void CurrentDagDock::setDigDagData(DigDagData *digDagData) {
  _digDagData = digDagData;
}


//==============================================================================
// Methods

/**
 *
 */
void CurrentDagDock::connectSlots() {

  // Load button slot
  QObject::connect(_ui->showTidListButton, SIGNAL(clicked()), this, SLOT(showTidList()));

}


/**
 *
 */
void CurrentDagDock::setupModelsAndViews() {

  //----------------------------------------------------------------------------
  // DAG pattern properties model/view
  _patternModel = new QStandardItemModel(0, 2);

  // Set headers
  _patternModel->setHeaderData(0, Qt::Horizontal, tr("Property"));
  _patternModel->setHeaderData(1, Qt::Horizontal, tr("Value"));

  // Insert rows : properties names
  _patternModel->insertRow(0);
  _patternModel->setData(_patternModel->index(0, 0), tr("Index"));
  _patternModel->insertRow(1);
  _patternModel->setData(_patternModel->index(1, 0), tr("Support"));
  _patternModel->insertRow(2);
  _patternModel->setData(_patternModel->index(2, 0), tr("Nodes"));
  _patternModel->insertRow(3);
  _patternModel->setData(_patternModel->index(3, 0), tr("Edges"));
  _patternModel->insertRow(4);
  _patternModel->setData(_patternModel->index(4, 0), tr("Length"));

  // Link model to the view
  _ui->patternPropertiesTreeView->setModel(_patternModel);


  //----------------------------------------------------------------------------
  // TID list model/view
  _tidListModel = new QStandardItemModel(0, 1);

  // Set headers
  _tidListModel->setHeaderData(0, Qt::Horizontal, tr("Input DAG index"));

  // Link model to the view
  _ui->tidListTreeView->setModel(_tidListModel);

  // Create selection model
  _tidListSelectionModel = new QItemSelectionModel(_tidListModel);

  // Link selection model to the view
  _ui->tidListTreeView->setSelectionModel(_tidListSelectionModel);


  //----------------------------------------------------------------------------
  // TODO Input DAG properties model/view


  //----------------------------------------------------------------------------
  // TODO Input DAG supported patterns model/view


}


/**
 *
 */
void CurrentDagDock::showDagPattern(int index) {

  currentPatternIndex = index;

  // Switch stacked widget
  _ui->stackedWidget->setCurrentIndex(0);

  // Update DAG properties contents
  updateDagPatternProperties();

  // Update DAG's TID list content
  clearTidList();

  // Enable show button
  _tidListModelIsComplete = true;
  _ui->showTidListButton->setEnabled(_tidListModelIsComplete);

  // Reset status label
  _ui->tidListStatusLabel->setText("");
  _ui->tidListStatusLabel->setVisible(false);

}


/**
 * Updates the Pattern Model contents to display the current DAG pattern properties.
 */
void CurrentDagDock::updateDagPatternProperties() {
  DagPattern *dagPattern = _digDagData->getPatternsList()->at(currentPatternIndex);
  _patternModel->setData(_patternModel->index(0, 1), currentPatternIndex); // TODO getIndex()
  _patternModel->setData(_patternModel->index(1, 1), dagPattern->getSupport());
  _patternModel->setData(_patternModel->index(2, 1), dagPattern->getStructure()->getNumberOfNodes());
  _patternModel->setData(_patternModel->index(3, 1), dagPattern->getStructure()->getNumberOfEdges());
  _patternModel->setData(_patternModel->index(4, 1), dagPattern->getStructure()->getLength());
}


/**
 * Removes all items in the TID list model.
 */
void CurrentDagDock::clearTidList() {
  if (_tidListModel->rowCount() > 0) {
    _tidListModel->removeRows(0, _tidListModel->rowCount());
  }
}


/**
 * Updates the TID list status label. If show is false, the message is useless
 * since label is not visible.
 *
 * @param show The new visibility value of the label
 * @param message The new message displayed by the label
 */
void CurrentDagDock::updateTidListStatusLabel(bool show, QString message)  {
  _ui->tidListStatusLabel->setVisible(show);
  _ui->tidListStatusLabel->setText(message);
}


//==============================================================================
// Slots

/**
 * Loads and displays the TID list of the current DAG pattern. As TID list can
 * be very long, a progress dialog is displayed during the loading process. If
 * the process is canceled by the user the TID list shown is incomplete and the
 * status label warns the user about this. The user can reload the TID list by pressing
 * again the button. If loading is completed, button is disabled and the status label
 * set invisible.
 */
void CurrentDagDock::showTidList() {

  clearTidList();

  // Get pattern's TID list
  QList<int>* tidList = _digDagData->getPatternsList()->at(currentPatternIndex)->getTidList();

  // Progress dialog
  int updateStepSize = tidList->size() / 5;
  bool progressCanceled = false;
  QProgressDialog progressDialog(tr("Loading TID list..."),
                                 tr("Cancel"),
                                 0,
                                 tidList->size(),
                                 this->parentWidget());

  progressDialog.setWindowModality(Qt::WindowModal);
  progressDialog.show();

  // Set tid list model content
  for (int i = 0; i < tidList->size(); i++) {
    if (i % updateStepSize == 0)
      progressDialog.setValue(i);

    _tidListModel->insertRow(i);
    _tidListModel->setData(_tidListModel->index(i, 0), tidList->at(i));

    if (progressDialog.wasCanceled()) {
      progressCanceled = true;
      break;
    }
  }
  progressDialog.setValue(tidList->size());

  if (progressCanceled) {
    updateTidListStatusLabel(true, tr("Warning: TID list was not completely loaded"));
  }
  else {
    updateTidListStatusLabel(false);

    // Disable show button if TID list was completely loaded
    _tidListModelIsComplete = true;
    _ui->showTidListButton->setEnabled(!_tidListModelIsComplete);
  }

}


