/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2013, Regents of the University of California
 *                     Yingdi Yu
 *
 * BSD license, See the LICENSE file for more information
 *
 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
 */


#include "browse-contact-dialog.h"
#include "ui_browse-contact-dialog.h"

#ifndef Q_MOC_RUN
#include "profile.h"
#endif

using namespace ndn;
using namespace chronos;

BrowseContactDialog::BrowseContactDialog(QWidget *parent) 
  : QDialog(parent)
  , ui(new Ui::BrowseContactDialog)
  , m_contactListModel(new QStringListModel)
{
  ui->setupUi(this);

  m_typeHeader = new QTableWidgetItem(QString("Type"));
  m_valueHeader = new QTableWidgetItem(QString("Value"));
  ui->InfoTable->setHorizontalHeaderItem(0, m_typeHeader);
  ui->InfoTable->setHorizontalHeaderItem(1, m_valueHeader);

  ui->ContactList->setModel(m_contactListModel);

  connect(ui->ContactList->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
          this, SLOT(onSelectionChanged(const QItemSelection &, const QItemSelection &)));
  connect(ui->AddButton, SIGNAL(clicked()),
	  this, SLOT(onAddClicked()));
  connect(ui->DirectAddButton, SIGNAL(clicked()),
	  this, SLOT(onDirectAddClicked()));
}

BrowseContactDialog::~BrowseContactDialog()
{
  delete m_typeHeader;
  delete m_valueHeader;
  delete ui;
}

void
BrowseContactDialog::onSelectionChanged(const QItemSelection& selected,
                                        const QItemSelection& deselected)
{
  QModelIndexList items = selected.indexes();
  QString certName = m_contactCertNameList[items.first().row()];
  emit fetchIdCert(certName);
}

void
BrowseContactDialog::onAddClicked()
{
  QItemSelectionModel* selectionModel = ui->ContactList->selectionModel();
  QModelIndexList selectedList = selectionModel->selectedIndexes();
  QModelIndexList::iterator it = selectedList.begin();
  for(; it != selectedList.end(); it++)
    emit addContact(m_contactNameList[it->row()]);

  this->close();
}

void
BrowseContactDialog::onDirectAddClicked()
{
  emit directAddClicked();
  this->close();
}

void
BrowseContactDialog::closeEvent(QCloseEvent *e)
{
  ui->InfoTable->clear();
  for(int i = ui->InfoTable->rowCount() - 1; i >= 0 ; i--)
      ui->InfoTable->removeRow(i);
  ui->InfoTable->horizontalHeader()->hide();

  hide();
  e->ignore();
}

void
BrowseContactDialog::onIdCertNameListReady(const QStringList& qCertNameList)
{
  m_contactCertNameList = qCertNameList;
}

void
BrowseContactDialog::onNameListReady(const QStringList& qNameList)
{
  m_contactNameList = qNameList;
  m_contactListModel->setStringList(m_contactNameList);
}

void
BrowseContactDialog::onIdCertReady(const IdentityCertificate& idCert)
{
  Profile profile(idCert);

  ui->InfoTable->clear();

  for(int i = ui->InfoTable->rowCount() - 1; i >= 0 ; i--)
    ui->InfoTable->removeRow(i);

  ui->InfoTable->horizontalHeader()->show();
  ui->InfoTable->setColumnCount(2);
  
  Profile::const_iterator proIt = profile.begin();
  Profile::const_iterator proEnd = profile.end();
  int rowCount = 0;

  for(; proIt != proEnd; proIt++, rowCount++)
    {
      ui->InfoTable->insertRow(rowCount);  
      QTableWidgetItem* type = new QTableWidgetItem(QString::fromStdString(proIt->first));
      ui->InfoTable->setItem(rowCount, 0, type);
      
      QTableWidgetItem* value = new QTableWidgetItem(QString::fromStdString(proIt->second));
      ui->InfoTable->setItem(rowCount, 1, value);	  
    }
}

#if WAF
#include "browse-contact-dialog.moc"
#include "browse-contact-dialog.cpp.moc"
#endif
