/* -*- 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 <QApplication>
#include <QMessageBox>
#include <QDir>
#include <QTimer>
#include "controller.hpp"

#ifndef Q_MOC_RUN
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <ndn-cxx/util/random.hpp>
#include "cryptopp.hpp"
#include "config.pb.h"
#include "endorse-info.pb.h"
#include "logging.h"
#endif

INIT_LOGGER("chronochat.Controller");

Q_DECLARE_METATYPE(ndn::Name)
Q_DECLARE_METATYPE(ndn::IdentityCertificate)
Q_DECLARE_METATYPE(chronochat::EndorseInfo)
Q_DECLARE_METATYPE(ndn::Interest)
Q_DECLARE_METATYPE(size_t)
Q_DECLARE_METATYPE(chronochat::ChatroomInfo)
Q_DECLARE_METATYPE(chronochat::Invitation)
Q_DECLARE_METATYPE(std::string)
Q_DECLARE_METATYPE(ndn::Name::Component)

namespace chronochat {

using std::string;

// constructor & destructor
Controller::Controller(QWidget* parent)
  : QDialog(parent)
  , m_localPrefixDetected(false)
  , m_settingDialog(new SettingDialog(this))
  , m_startChatDialog(new StartChatDialog(this))
  , m_profileEditor(new ProfileEditor(this))
  , m_invitationDialog(new InvitationDialog(this))
  , m_invitationRequestDialog(new InvitationRequestDialog(this))
  , m_contactPanel(new ContactPanel(this))
  , m_browseContactDialog(new BrowseContactDialog(this))
  , m_addContactPanel(new AddContactPanel(this))
  , m_discoveryPanel(new DiscoveryPanel(this))
{
  qRegisterMetaType<ndn::Name>("ndn.Name");
  qRegisterMetaType<ndn::IdentityCertificate>("ndn.IdentityCertificate");
  qRegisterMetaType<chronochat::EndorseInfo>("chronochat.EndorseInfo");
  qRegisterMetaType<ndn::Interest>("ndn.Interest");
  qRegisterMetaType<size_t>("size_t");
  qRegisterMetaType<chronochat::ChatroomInfo>("chronochat.Chatroom");
  qRegisterMetaType<chronochat::Invitation>("chronochat.Invitation");
  qRegisterMetaType<std::string>("std.string");
  qRegisterMetaType<ndn::Name::Component>("ndn.Component");


  // Connection to ContactManager
  connect(m_backend.getContactManager(), SIGNAL(warning(const QString&)),
          this, SLOT(onWarning(const QString&)));
  connect(this, SIGNAL(refreshBrowseContact()),
          m_backend.getContactManager(), SLOT(onRefreshBrowseContact()));
  connect(m_backend.getContactManager(), SIGNAL(contactInfoFetchFailed(const QString&)),
          this, SLOT(onWarning(const QString&)));

  // Connection to SettingDialog
  connect(this, SIGNAL(identityUpdated(const QString&)),
          m_settingDialog, SLOT(onIdentityUpdated(const QString&)));
  connect(m_settingDialog, SIGNAL(identityUpdated(const QString&)),
          this, SLOT(onIdentityUpdated(const QString&)));
  connect(m_settingDialog, SIGNAL(nickUpdated(const QString&)),
          this, SLOT(onNickUpdated(const QString&)));
  connect(m_settingDialog, SIGNAL(prefixUpdated(const QString&)),
          this, SLOT(onLocalPrefixConfigured(const QString&)));

  // Connection to ProfileEditor
  connect(this, SIGNAL(closeDBModule()),
          m_profileEditor, SLOT(onCloseDBModule()));
  connect(this, SIGNAL(identityUpdated(const QString&)),
          m_profileEditor, SLOT(onIdentityUpdated(const QString&)));
  connect(m_profileEditor, SIGNAL(updateProfile()),
          m_backend.getContactManager(), SLOT(onUpdateProfile()));

  // Connection to StartChatDialog
  connect(m_startChatDialog, SIGNAL(startChatroom(const QString&, bool)),
          this, SLOT(onStartChatroom(const QString&, bool)));

  // Connection to InvitationDialog
  connect(m_invitationDialog, SIGNAL(invitationResponded(const ndn::Name&, bool)),
          &m_backend, SLOT(onInvitationResponded(const ndn::Name&, bool)));

  // Connection to InvitationRequestDialog
  connect(m_invitationRequestDialog, SIGNAL(invitationRequestResponded(const ndn::Name&, bool)),
          &m_backend, SLOT(onInvitationRequestResponded(const ndn::Name&, bool)));

  // Connection to AddContactPanel
  connect(m_addContactPanel, SIGNAL(fetchInfo(const QString&)),
          m_backend.getContactManager(), SLOT(onFetchContactInfo(const QString&)));
  connect(m_addContactPanel, SIGNAL(addContact(const QString&)),
          m_backend.getContactManager(), SLOT(onAddFetchedContact(const QString&)));
  connect(m_backend.getContactManager(),
          SIGNAL(contactEndorseInfoReady(const chronochat::EndorseInfo&)),
          m_addContactPanel,
          SLOT(onContactEndorseInfoReady(const chronochat::EndorseInfo&)));

  // Connection to BrowseContactDialog
  connect(m_browseContactDialog, SIGNAL(directAddClicked()),
          this, SLOT(onDirectAdd()));
  connect(m_browseContactDialog, SIGNAL(fetchIdCert(const QString&)),
          m_backend.getContactManager(), SLOT(onFetchIdCert(const QString&)));
  connect(m_browseContactDialog, SIGNAL(addContact(const QString&)),
          m_backend.getContactManager(), SLOT(onAddFetchedContactIdCert(const QString&)));
  connect(m_backend.getContactManager(), SIGNAL(idCertNameListReady(const QStringList&)),
          m_browseContactDialog, SLOT(onIdCertNameListReady(const QStringList&)));
  connect(m_backend.getContactManager(), SIGNAL(nameListReady(const QStringList&)),
          m_browseContactDialog, SLOT(onNameListReady(const QStringList&)));
  connect(m_backend.getContactManager(), SIGNAL(idCertReady(const ndn::IdentityCertificate&)),
          m_browseContactDialog, SLOT(onIdCertReady(const ndn::IdentityCertificate&)));

  // Connection to ContactPanel
  connect(m_contactPanel, SIGNAL(waitForContactList()),
          m_backend.getContactManager(), SLOT(onWaitForContactList()));
  connect(m_contactPanel, SIGNAL(waitForContactInfo(const QString&)),
          m_backend.getContactManager(), SLOT(onWaitForContactInfo(const QString&)));
  connect(m_contactPanel, SIGNAL(removeContact(const QString&)),
          m_backend.getContactManager(), SLOT(onRemoveContact(const QString&)));
  connect(m_contactPanel, SIGNAL(updateAlias(const QString&, const QString&)),
          m_backend.getContactManager(), SLOT(onUpdateAlias(const QString&, const QString&)));
  connect(m_contactPanel, SIGNAL(updateIsIntroducer(const QString&, bool)),
          m_backend.getContactManager(), SLOT(onUpdateIsIntroducer(const QString&, bool)));
  connect(m_contactPanel, SIGNAL(updateEndorseCertificate(const QString&)),
          m_backend.getContactManager(), SLOT(onUpdateEndorseCertificate(const QString&)));
  connect(m_contactPanel, SIGNAL(warning(const QString&)),
          this, SLOT(onWarning(const QString&)));
  connect(this, SIGNAL(closeDBModule()),
          m_contactPanel, SLOT(onCloseDBModule()));
  connect(this, SIGNAL(identityUpdated(const QString&)),
          m_contactPanel, SLOT(onIdentityUpdated(const QString&)));
  connect(m_backend.getContactManager(), SIGNAL(contactAliasListReady(const QStringList&)),
          m_contactPanel, SLOT(onContactAliasListReady(const QStringList&)));
  connect(m_backend.getContactManager(), SIGNAL(contactIdListReady(const QStringList&)),
          m_contactPanel, SLOT(onContactIdListReady(const QStringList&)));
  connect(m_backend.getContactManager(), SIGNAL(contactInfoReady(const QString&, const QString&,
                                                                 const QString&, bool)),
          m_contactPanel, SLOT(onContactInfoReady(const QString&, const QString&,
                                                  const QString&, bool)));

  // Connection to backend thread
  connect(this, SIGNAL(shutdownBackend()),
          &m_backend, SLOT(shutdown()));
  connect(this, SIGNAL(updateLocalPrefix()),
          &m_backend, SLOT(onUpdateLocalPrefixAction()));
  connect(this, SIGNAL(identityUpdated(const QString&)),
          &m_backend, SLOT(onIdentityChanged(const QString&)));
  connect(this, SIGNAL(addChatroom(QString)),
          &m_backend, SLOT(addChatroom(QString)));
  connect(this, SIGNAL(removeChatroom(QString)),
          &m_backend, SLOT(removeChatroom(QString)));

  // Thread notifications:
  // on local prefix udpated:
  connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)),
          this, SLOT(onLocalPrefixUpdated(const QString&)));
  connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)),
          m_settingDialog, SLOT(onLocalPrefixUpdated(const QString&)));

  // on invitation validated:
  connect(&m_backend, SIGNAL(invitationValidated(QString, QString, ndn::Name)),
          m_invitationDialog, SLOT(onInvitationReceived(QString, QString, ndn::Name)));
  connect(&m_backend, SIGNAL(startChatroom(const QString&, bool)),
          this, SLOT(onStartChatroom(const QString&, bool)));

  // on invitation request received
  connect(&m_backend, SIGNAL(invitationRequestReceived(QString, QString, ndn::Name)),
          m_invitationRequestDialog, SLOT(onInvitationRequestReceived(QString, QString,
                                                                      ndn::Name)));

  // on invitation accepted:
  connect(&m_backend, SIGNAL(startChatroomOnInvitation(chronochat::Invitation, bool)),
          this, SLOT(onStartChatroom2(chronochat::Invitation, bool)));

  m_backend.start();

  initialize();

  m_chatroomDiscoveryBackend
    = new ChatroomDiscoveryBackend(m_localPrefix,
                                   m_identity,
                                   this);

  // connect to chatroom discovery back end
  connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)),
          m_chatroomDiscoveryBackend, SLOT(updateRoutingPrefix(const QString&)));
  connect(this, SIGNAL(localPrefixConfigured(const QString&)),
          m_chatroomDiscoveryBackend, SLOT(updateRoutingPrefix(const QString&)));
  connect(this, SIGNAL(newChatroomForDiscovery(Name::Component)),
          m_chatroomDiscoveryBackend, SLOT(onNewChatroomForDiscovery(Name::Component)));
  connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomInfoRequest(std::string, bool)),
          this, SLOT(onChatroomInfoRequest(std::string, bool)));
  connect(this, SIGNAL(respondChatroomInfoRequest(ChatroomInfo, bool)),
          m_chatroomDiscoveryBackend, SLOT(onRespondChatroomInfoRequest(ChatroomInfo, bool)));
  connect(this, SIGNAL(shutdownDiscoveryBackend()),
          m_chatroomDiscoveryBackend, SLOT(shutdown()));
  connect(this, SIGNAL(identityUpdated(const QString&)),
          m_chatroomDiscoveryBackend, SLOT(onIdentityUpdated(const QString&)));

  // connect chatroom discovery back end with front end
  connect(m_discoveryPanel, SIGNAL(waitForChatroomInfo(const QString&)),
          m_chatroomDiscoveryBackend, SLOT(onWaitForChatroomInfo(const QString&)));
  connect(m_discoveryPanel, SIGNAL(warning(const QString&)),
          this, SLOT(onWarning(const QString&)));
  connect(this, SIGNAL(identityUpdated(const QString&)),
          m_discoveryPanel, SLOT(onIdentityUpdated(const QString&)));
  connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomListReady(const QStringList&)),
          m_discoveryPanel, SLOT(onChatroomListReady(const QStringList&)));
  connect(m_chatroomDiscoveryBackend, SIGNAL(chatroomInfoReady(const ChatroomInfo&, bool)),
          m_discoveryPanel, SLOT(onChatroomInfoReady(const ChatroomInfo&, bool)));
  connect(m_discoveryPanel, SIGNAL(startChatroom(const QString&, bool)),
          this, SLOT(onStartChatroom(const QString&, bool)));
  connect(m_discoveryPanel, SIGNAL(sendInvitationRequest(const QString&, const QString&)),
          &m_backend, SLOT(onSendInvitationRequest(const QString&, const QString&)));
  connect(&m_backend, SIGNAL(invitationRequestResult(const std::string&)),
          m_discoveryPanel, SLOT(onInvitationRequestResult(const std::string&)));

  m_chatroomDiscoveryBackend->start();

  createTrayIcon();

  emit updateLocalPrefix();
}

Controller::~Controller()
{
  saveConf();
}

// public methods


// private methods
string
Controller::getDBName()
{
  string dbName("chronos-");

  std::stringstream ss;
  {
    using namespace CryptoPP;

    SHA256 hash;
    StringSource(m_identity.wireEncode().wire(), m_identity.wireEncode().size(), true,
                 new HashFilter(hash, new HexEncoder(new FileSink(ss), false)));
  }
  dbName.append(ss.str()).append(".db");

  return dbName;
}

void
Controller::openDB()
{
  m_db = QSqlDatabase::addDatabase("QSQLITE");
  QString path = (QDir::home().path());
  path.append(QDir::separator())
    .append(".chronos")
    .append(QDir::separator())
    .append(getDBName().c_str());
  m_db.setDatabaseName(path);

  m_db.open();

  // bool ok = m_db.open();
  // _LOG_DEBUG("DB opened: " << std::boolalpha << ok );
}

void
Controller::initialize()
{
  loadConf();

  openDB();

  emit identityUpdated(QString(m_identity.toUri().c_str()));
}

void
Controller::loadConf()
{
  namespace fs = boost::filesystem;

  fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
  fs::create_directories (chronosDir);

  std::ifstream is((chronosDir / "config").c_str ());
  ChronoChat::Conf conf;
  if (conf.ParseFromIstream(&is)) {
    m_identity.clear();
    m_identity.append(conf.identity());
    if (conf.has_nick())
      m_nick = conf.nick();
    else
      m_nick = m_identity.get(-1).toUri();
  }
  else {
    m_identity.clear();
    // TODO: change below to system default;
    m_identity.append("chronochat-tmp-identity")
      .append(getRandomString());

    m_nick = m_identity.get(-1).toUri();
  }
}

void
Controller::saveConf()
{
  namespace fs = boost::filesystem;

  fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
  fs::create_directories (chronosDir);

  std::ofstream os((chronosDir / "config").c_str ());
  ChronoChat::Conf conf;
  conf.set_identity(m_identity.toUri());
  if (!m_nick.empty())
    conf.set_nick(m_nick);
  conf.SerializeToOstream(&os);

  os.close();
}

void
Controller::createActions()
{
  m_startChatroom = new QAction(tr("Start new chat"), this);
  connect(m_startChatroom, SIGNAL(triggered()), this, SLOT(onStartChatAction()));

  m_settingsAction = new QAction(tr("Settings"), this);
  connect(m_settingsAction, SIGNAL(triggered()), this, SLOT(onSettingsAction()));

  m_editProfileAction = new QAction(tr("Edit profile"), this);
  connect(m_editProfileAction, SIGNAL(triggered()), this, SLOT(onProfileEditorAction()));

  m_contactListAction = new QAction(tr("Contact List"), this);
  connect(m_contactListAction, SIGNAL(triggered()), this, SLOT(onContactListAction()));

  m_addContactAction = new QAction(tr("Add contact"), this);
  connect(m_addContactAction, SIGNAL(triggered()), this, SLOT(onAddContactAction()));

  m_chatroomDiscoveryAction = new QAction(tr("Chatroom Discovery"), this);
  connect(m_chatroomDiscoveryAction, SIGNAL(triggered()), this, SLOT(onChatroomDiscoveryAction()));

  m_updateLocalPrefixAction = new QAction(tr("Update local prefix"), this);
  connect(m_updateLocalPrefixAction, SIGNAL(triggered()),
          &m_backend, SLOT(onUpdateLocalPrefixAction()));

  m_minimizeAction = new QAction(tr("Mi&nimize"), this);
  connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(onMinimizeAction()));

  m_quitAction = new QAction(tr("Quit"), this);
  connect(m_quitAction, SIGNAL(triggered()), this, SLOT(onQuitAction()));

}

void
Controller::createTrayIcon()
{
  createActions();

  m_trayIconMenu = new QMenu(this);
  m_trayIconMenu->addAction(m_startChatroom);
  m_trayIconMenu->addAction(m_chatroomDiscoveryAction);

  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_settingsAction);
  m_trayIconMenu->addAction(m_editProfileAction);
  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_contactListAction);
  m_trayIconMenu->addAction(m_addContactAction);
  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_updateLocalPrefixAction);
  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_minimizeAction);
  m_closeMenu = m_trayIconMenu->addMenu("Close chatroom");
  m_closeMenu->setEnabled(false);
  m_trayIconMenu->addSeparator();
  m_trayIconMenu->addAction(m_quitAction);

  m_trayIcon = new QSystemTrayIcon(this);
  m_trayIcon->setContextMenu(m_trayIconMenu);

  m_trayIcon->setIcon(QIcon(":/images/icon_small.png"));
  m_trayIcon->setToolTip("ChronoChat System Tray Icon");
  m_trayIcon->setVisible(true);
}

void
Controller::updateMenu()
{
  QMenu* menu = new QMenu(this);
  QMenu* closeMenu = 0;

  menu->addAction(m_startChatroom);
  menu->addAction(m_chatroomDiscoveryAction);

  menu->addSeparator();
  menu->addAction(m_settingsAction);
  menu->addAction(m_editProfileAction);
  menu->addSeparator();
  menu->addAction(m_contactListAction);
  menu->addAction(m_addContactAction);
  menu->addSeparator();
  {
    ChatActionList::const_iterator it = m_chatActionList.begin();
    ChatActionList::const_iterator end = m_chatActionList.end();
    if (it != end) {
      for (; it != end; it++)
        menu->addAction(it->second);
      menu->addSeparator();
    }
  }
  menu->addAction(m_updateLocalPrefixAction);
  menu->addSeparator();
  menu->addAction(m_minimizeAction);
  closeMenu = menu->addMenu("Close chatroom");
  {
    ChatActionList::const_iterator it = m_closeActionList.begin();
    ChatActionList::const_iterator end = m_closeActionList.end();
    if (it == end)
      closeMenu->setEnabled(false);
    else
      for (; it != end; it++)
        closeMenu->addAction(it->second);
  }
  menu->addSeparator();
  menu->addAction(m_quitAction);

  m_trayIcon->setContextMenu(menu);
  delete m_trayIconMenu;
  m_trayIconMenu = menu;
  m_closeMenu = closeMenu;
}

string
Controller::getRandomString()
{
  uint32_t r = ndn::random::generateWord32();
  std::stringstream ss;
  {
    using namespace CryptoPP;
    StringSource(reinterpret_cast<uint8_t*>(&r), 4, true,
                 new HexEncoder(new FileSink(ss), false));

  }
  // for (int i = 0; i < 8; i++)
  //   {
  //     uint32_t t = r & mask;
  //     if (t < 10)
  //       ss << static_cast<char>(t + 0x30);
  //     else
  //       ss << static_cast<char>(t + 0x57);
  //     r = r >> 4;
  //   }

  return ss.str();
}

void
Controller::addChatDialog(const QString& chatroomName, ChatDialog* chatDialog)
{
  m_chatDialogList[chatroomName.toStdString()] = chatDialog;
  connect(chatDialog, SIGNAL(closeChatDialog(const QString&)),
          this, SLOT(onRemoveChatDialog(const QString&)));
  connect(chatDialog, SIGNAL(showChatMessage(const QString&, const QString&, const QString&)),
          this, SLOT(onShowChatMessage(const QString&, const QString&, const QString&)));
  connect(chatDialog, SIGNAL(resetIcon()),
          this, SLOT(onResetIcon()));
  connect(&m_backend, SIGNAL(localPrefixUpdated(const QString&)),
          chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));
  connect(this, SIGNAL(localPrefixConfigured(const QString&)),
          chatDialog->getBackend(), SLOT(updateRoutingPrefix(const QString&)));

  // connect chat dialog with discovery backend
  connect(chatDialog->getBackend(), SIGNAL(addInRoster(ndn::Name, ndn::Name::Component)),
          m_chatroomDiscoveryBackend, SLOT(onAddInRoster(ndn::Name, ndn::Name::Component)));
  connect(chatDialog->getBackend(), SIGNAL(eraseInRoster(ndn::Name, ndn::Name::Component)),
          m_chatroomDiscoveryBackend, SLOT(onEraseInRoster(ndn::Name, ndn::Name::Component)));


  QAction* chatAction = new QAction(chatroomName, this);
  m_chatActionList[chatroomName.toStdString()] = chatAction;
  connect(chatAction, SIGNAL(triggered()),
          chatDialog, SLOT(onShow()));

  QAction* closeAction = new QAction(chatroomName, this);
  m_closeActionList[chatroomName.toStdString()] = closeAction;
  connect(closeAction, SIGNAL(triggered()),
          chatDialog, SLOT(shutdown()));

  updateMenu();
  emit newChatroomForDiscovery(Name::Component(chatroomName.toStdString()));
}

void
Controller::updateDiscoveryList(const ChatroomInfo& info, bool isAdd)
{
  emit discoverChatroomChanged(info, isAdd);
}

void
Controller::onIdentityUpdated(const QString& identity)
{
  while (!m_chatDialogList.empty()) {
    ChatDialogList::const_iterator it = m_chatDialogList.begin();
    it->second->shutdown();
  }

  emit closeDBModule();

  Name identityName(identity.toStdString());
  m_identity = identityName;

  QTimer::singleShot(500, this, SLOT(onIdentityUpdatedContinued()));
}

void
Controller::onIdentityUpdatedContinued()
{
  QString connection = m_db.connectionName();
  // _LOG_DEBUG("connection name: " << connection.toStdString());
  QSqlDatabase::removeDatabase(connection);
  m_db.close();

  openDB();

  emit identityUpdated(QString(m_identity.toUri().c_str()));
}

void
Controller::onNickUpdated(const QString& nick)
{
  m_nick = nick.toStdString();
}

void
Controller::onLocalPrefixUpdated(const QString& localPrefix)
{
  QString privateLocalPrefix("/private/local");

  if (privateLocalPrefix != localPrefix)
    m_localPrefixDetected = true;
  else
    m_localPrefixDetected = false;

  m_localPrefix = Name(localPrefix.toStdString());
}

void
Controller::onLocalPrefixConfigured(const QString& prefix)
{
  if (!m_localPrefixDetected) {
    m_localPrefix = Name(prefix.toStdString());
    emit localPrefixConfigured(prefix);
  }
}

void
Controller::onStartChatAction()
{
  string chatroom = "chatroom-" + getRandomString();

  m_startChatDialog->setChatroom(chatroom);
  m_startChatDialog->show();
  m_startChatDialog->raise();
}

void
Controller::onSettingsAction()
{
  m_settingDialog->setNick(QString(m_nick.c_str()));
  m_settingDialog->show();
  m_settingDialog->raise();
}

void
Controller::onProfileEditorAction()
{
  m_profileEditor->show();
  m_profileEditor->raise();
}

void
Controller::onAddContactAction()
{
  emit refreshBrowseContact();
  m_browseContactDialog->show();
  m_browseContactDialog->raise();
}

void
Controller::onContactListAction()
{
  m_contactPanel->show();
  m_contactPanel->raise();
}

void
Controller::onChatroomDiscoveryAction()
{
  m_discoveryPanel->show();
  m_discoveryPanel->raise();
}

void
Controller::onDirectAdd()
{
  m_addContactPanel->show();
  m_addContactPanel->raise();
}

void
Controller::onMinimizeAction()
{
  m_settingDialog->hide();
  m_startChatDialog->hide();
  m_profileEditor->hide();
  m_invitationDialog->hide();
  m_addContactPanel->hide();
  m_discoveryPanel->hide();

  ChatDialogList::iterator it = m_chatDialogList.begin();
  ChatDialogList::iterator end = m_chatDialogList.end();
  for (; it != end; it++)
    it->second->hide();
}

void
Controller::onQuitAction()
{
  while (!m_chatDialogList.empty()) {
    ChatDialogList::const_iterator it = m_chatDialogList.begin();
    it->second->shutdown();
  }

  delete m_settingDialog;
  delete m_startChatDialog;
  delete m_profileEditor;
  delete m_invitationDialog;
  delete m_browseContactDialog;
  delete m_addContactPanel;
  delete m_discoveryPanel;
  if (m_chatroomDiscoveryBackend->isRunning()) {
    emit shutdownDiscoveryBackend();
    m_chatroomDiscoveryBackend->wait();
  }
  delete m_chatroomDiscoveryBackend;

  if (m_backend.isRunning()) {
    emit shutdownBackend();
    m_backend.wait();
  }

  QApplication::quit();
}

void
Controller::onStartChatroom(const QString& chatroomName, bool secured)
{
  Name chatroomPrefix;
  chatroomPrefix.append("ndn")
    .append("broadcast")
    .append("ChronoChat")
    .append("Chatroom")
    .append(chatroomName.toStdString());

  // check if the chatroom exists
  if (m_chatDialogList.find(chatroomName.toStdString()) != m_chatDialogList.end()) {
    QMessageBox::information(this, tr("ChronoChat"),
                             tr("You are creating an existing chatroom."
                                "You can check it in the context memu."));
    return;
  }

  // TODO: We should create a chatroom specific key/cert
  //(which should be created in the first half of this method
  //, but let's use the default one for now.
  Name chatPrefix;
  chatPrefix.append(m_identity).append("CHRONOCHAT-CHATDATA").append(chatroomName.toStdString());

  ChatDialog* chatDialog
    = new ChatDialog(chatroomPrefix,
                     chatPrefix,
                     m_localPrefix,
                     chatroomName.toStdString(),
                     m_nick,
                     true,
                     m_identity,
                     this);

  addChatDialog(chatroomName, chatDialog);
  chatDialog->show();

  emit addChatroom(chatroomName);
}

void
Controller::onStartChatroom2(chronochat::Invitation invitation, bool secured)
{
  QString chatroomName = QString::fromStdString(invitation.getChatroom());
  onStartChatroom(chatroomName, secured);

  ChatDialogList::iterator it = m_chatDialogList.find(chatroomName.toStdString());

  BOOST_ASSERT(it != m_chatDialogList.end());
  it->second->addSyncAnchor(invitation);
}


void
Controller::onShowChatMessage(const QString& chatroomName, const QString& from, const QString& data)
{
  m_trayIcon->showMessage(QString("Chatroom %1 has a new message").arg(chatroomName),
                          QString("<%1>: %2").arg(from).arg(data),
                          QSystemTrayIcon::Information, 20000);
  m_trayIcon->setIcon(QIcon(":/images/note.png"));
}

void
Controller::onResetIcon()
{
  m_trayIcon->setIcon(QIcon(":/images/icon_small.png"));
}

void
Controller::onRemoveChatDialog(const QString& chatroomName)
{
  ChatDialogList::iterator it = m_chatDialogList.find(chatroomName.toStdString());
  if (it != m_chatDialogList.end()) {
    ChatDialog* deletedChat = it->second;
    if (deletedChat)
      delete deletedChat;

    m_chatDialogList.erase(it);

    QAction* chatAction = m_chatActionList[chatroomName.toStdString()];
    QAction* closeAction = m_closeActionList[chatroomName.toStdString()];
    if (chatAction)
      delete chatAction;
    if (closeAction)
      delete closeAction;

    m_chatActionList.erase(chatroomName.toStdString());
    m_closeActionList.erase(chatroomName.toStdString());

    updateMenu();
  }
}

void
Controller::onWarning(const QString& msg)
{
  QMessageBox::information(this, tr("ChronoChat"), msg);
}

void
Controller::onError(const QString& msg)
{
  QMessageBox::critical(this, tr("ChronoChat"), msg, QMessageBox::Ok);
  exit(1);
}

void
Controller::onChatroomInfoRequest(std::string chatroomName, bool isManager)
{
  auto it = m_chatDialogList.find(chatroomName);
  if (it != m_chatDialogList.end())
    emit respondChatroomInfoRequest(it->second->getChatroomInfo(), isManager);
}

} // namespace chronochat

#if WAF
#include "controller.moc"
// #include "controller.cpp.moc"
#endif
