/* -*- 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 "invitelistdialog.h"
#include "ui_invitelistdialog.h"

using namespace std;

InviteListDialog::InviteListDialog(ndn::Ptr<ContactManager> contactManager,
				   QWidget *parent) 
  :QDialog(parent)
  , ui(new Ui::InviteListDialog)
  , m_contactManager(contactManager)
  , m_contactListModel(new QStringListModel)
{
  ui->setupUi(this);

  refreshContactList();

  ui->contactListView->setModel(m_contactListModel);

  connect(ui->inviteButton, SIGNAL(clicked()),
	  this, SLOT(inviteWrapper()));
  connect(ui->cancelButton, SIGNAL(clicked()),
	  this, SLOT(onCancelClicked()));
}

InviteListDialog::~InviteListDialog()
{
  delete ui;
  delete m_contactListModel;
}

void
InviteListDialog::setInviteLabel(string label)
{ 
  string msg("invite to chatroom:\n");
  msg += label;
  ui->inviteLabel->setText(QString::fromUtf8(msg.c_str())); 
  refreshContactList();
}

void
InviteListDialog::refreshContactList()
{
  m_contactList = m_contactManager->getContactItemList();
  QStringList contactNameList;
  for(int i = 0; i < m_contactList.size(); i++)
    {
      contactNameList << QString::fromUtf8(m_contactList[i]->getAlias().c_str());
    }

  m_contactListModel->setStringList(contactNameList);
}

void
InviteListDialog::inviteWrapper()
{
  QModelIndexList selected = ui->contactListView->selectionModel()->selectedIndexes();
  QString text = m_contactListModel->data(selected.first(), Qt::DisplayRole).toString();
  string alias = text.toUtf8().constData();

  int i = 0;
  for(; i < m_contactList.size(); i++)
    {
      if(alias == m_contactList[i]->getAlias())
        break;
    }

  QString invitedContactNamespace = QString::fromUtf8(m_contactList[i]->getNameSpace().toUri().c_str());

  bool isIntroducer = true;

  emit invitionDetermined(invitedContactNamespace, isIntroducer);

  this->close();
}

void
InviteListDialog::onCancelClicked()
{ this->close(); }

#if WAF
#include "invitelistdialog.moc"
#include "invitelistdialog.cpp.moc"
#endif
