/* -*- 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: Zhenkai Zhu <zhenkai@cs.ucla.edu>
 *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 *         Yingdi Yu <yingdi@cs.ucla.edu>
 */

#include "chat-dialog.hpp"
#include "ui_chat-dialog.h"

#include <QScrollBar>
#include <QMessageBox>
#include <QCloseEvent>

Q_DECLARE_METATYPE(ndn::Name)
Q_DECLARE_METATYPE(time_t)
Q_DECLARE_METATYPE(std::vector<chronochat::NodeInfo>)

namespace chronochat {

static const Name PRIVATE_PREFIX("/private/local");
static const uint8_t ROUTING_HINT_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.

ChatDialog::ChatDialog(const Name& chatroomPrefix,
                       const Name& userChatPrefix,
                       const Name& routingPrefix,
                       const std::string& chatroomName,
                       const std::string& nick,
                       bool isSecured,
                       const Name& signingId,
                       QWidget* parent)
  : QDialog(parent)
  , ui(new Ui::ChatDialog)
  , m_backend(chatroomPrefix, userChatPrefix, routingPrefix, chatroomName, nick, signingId)
  , m_chatroomName(chatroomName)
  , m_nick(nick.c_str())
  , m_isSecured(isSecured)
{
  qRegisterMetaType<ndn::Name>("ndn::Name");
  qRegisterMetaType<time_t>("time_t");
  qRegisterMetaType<std::vector<chronochat::NodeInfo> >("std::vector<chronochat::NodeInfo>");

  m_scene = new DigestTreeScene(this);
  m_trustScene = new TrustTreeScene(this);
  m_rosterModel = new QStringListModel(this);

  ui->setupUi(this);

  ui->syncTreeViewer->setScene(m_scene);
  m_scene->setSceneRect(m_scene->itemsBoundingRect());
  ui->syncTreeViewer->hide();

  ui->trustTreeViewer->setScene(m_trustScene);
  m_trustScene->setSceneRect(m_trustScene->itemsBoundingRect());
  ui->trustTreeViewer->hide();

  ui->listView->setModel(m_rosterModel);

  Name routablePrefix;

  if (routingPrefix.isPrefixOf(userChatPrefix))
    routablePrefix = userChatPrefix;
  else
    routablePrefix.append(routingPrefix)
      .append(ROUTING_HINT_SEPARATOR, 2)
      .append(userChatPrefix);

  updateLabels(routablePrefix);

  QStringList roster;
  roster << "- " + m_nick;
  m_rosterModel->setStringList(roster);

  // When backend receives a sync update, notify frontend to update sync tree
  connect(&m_backend, SIGNAL(syncTreeUpdated(std::vector<chronochat::NodeInfo>, QString)),
          this,       SLOT(updateSyncTree(std::vector<chronochat::NodeInfo>, QString)));

  // When backend receives a new chat message, notify frontent to print it out.
  connect(&m_backend, SIGNAL(chatMessageReceived(QString, QString, time_t)),
          this,       SLOT(receiveChatMessage(QString, QString, time_t)));

  // When backend detects a new session, notify frontend to print the message.
  connect(&m_backend, SIGNAL(sessionAdded(QString, QString, time_t)),
          this,       SLOT(addSession(QString, QString, time_t)));

  // When backend detects a deleted session, notify frontend to print the message.
  connect(&m_backend, SIGNAL(sessionRemoved(QString, QString, time_t)),
          this,       SLOT(removeSession(QString, QString, time_t)));

  // When backend detects nick changed, notify frontend to print the new nick
  connect(&m_backend, SIGNAL(nickUpdated(QString, QString)),
          this,       SLOT(updateNick(QString, QString)));

  // When backend receives a new message, notify frontend to print notification
  connect(&m_backend, SIGNAL(messageReceived(QString)),
          this,       SLOT(receiveMessage(QString)));

  // When backend updates prefix, notify frontend to update labels.
  connect(&m_backend, SIGNAL(chatPrefixChanged(ndn::Name)),
          this,       SLOT(updateLabels(ndn::Name)));

  // When frontend gets a message to send, notify backend.
  connect(this,       SIGNAL(msgToSent(QString, time_t)),
          &m_backend, SLOT(sendChatMessage(QString, time_t)));

  // When frontend gets a shutdown command, notify backend.
  connect(this,       SIGNAL(shutdownBackend()),
          &m_backend, SLOT(shutdown()));

  m_scene->plot("Empty");

  connect(ui->lineEdit, SIGNAL(returnPressed()),
          this, SLOT(onReturnPressed()));
  connect(ui->syncTreeButton, SIGNAL(pressed()),
          this, SLOT(onSyncTreeButtonPressed()));
  connect(ui->trustTreeButton, SIGNAL(pressed()),
          this, SLOT(onTrustTreeButtonPressed()));

  disableSyncTreeDisplay();
  QTimer::singleShot(2200, this, SLOT(enableSyncTreeDisplay()));

  m_backend.start();
}


ChatDialog::~ChatDialog()
{
}

void
ChatDialog::closeEvent(QCloseEvent *e)
{
  // When close button is clicked, do not close the dialog immediately.

  QMessageBox::information(this, tr("ChronoChat"),
                           tr("The chatroom will keep running in the "
                              "system tray. To close the chatroom, "
                              "choose <b>Close chatroom</b> in the "
                              "context memu of the system tray entry."));
  hide();
  e->ignore();
}

void
ChatDialog::changeEvent(QEvent *e)
{
  switch(e->type()) {
  case QEvent::ActivationChange:
    if (isActiveWindow()) {
      emit resetIcon();
    }
    break;
  default:
    break;
  }
}

void
ChatDialog::resizeEvent(QResizeEvent *e)
{
  fitView();
}

void
ChatDialog::showEvent(QShowEvent *e)
{
  fitView();
}

shared_ptr<ChatroomInfo>
ChatDialog::getChatroomInfo()
{
  shared_ptr<ChatroomInfo> chatroomInfo = make_shared<ChatroomInfo>();

  chatroomInfo->setName(Name::Component(m_chatroomName));

  QStringList prefixList = m_scene->getRosterPrefixList();
  for(QStringList::iterator it = prefixList.begin();
      it != prefixList.end(); ++it ) {
    Name participant = Name(it->toStdString()).getPrefix(-3);
    chatroomInfo->addParticipant(participant);
  }

  if (m_isSecured)
    chatroomInfo->setTrustModel(ChatroomInfo::TRUST_MODEL_HIERARCHICAL);
  else
    chatroomInfo->setTrustModel(ChatroomInfo::TRUST_MODEL_NONE);
  return chatroomInfo;
}

// private methods:
void ChatDialog::disableSyncTreeDisplay()
{
  ui->syncTreeButton->setEnabled(false);
  ui->syncTreeViewer->hide();
  fitView();
}

void
ChatDialog::appendChatMessage(const QString& nick, const QString& text, time_t timestamp)
{
  QTextCharFormat nickFormat;
  nickFormat.setForeground(Qt::darkGreen);
  nickFormat.setFontWeight(QFont::Bold);
  nickFormat.setFontUnderline(true);
  nickFormat.setUnderlineColor(Qt::gray);

  // Print who & when
  QTextCursor cursor(ui->textEdit->textCursor());
  cursor.movePosition(QTextCursor::End);
  QTextTableFormat tableFormat;
  tableFormat.setBorder(0);
  QTextTable *table = cursor.insertTable(1, 2, tableFormat);
  QString from = QString("%1 ").arg(nick);
  QTextTableCell fromCell = table->cellAt(0, 0);
  fromCell.setFormat(nickFormat);
  fromCell.firstCursorPosition().insertText(from);
  printTimeInCell(table, timestamp);

  // Print what
  QTextCursor nextCursor(ui->textEdit->textCursor());
  nextCursor.movePosition(QTextCursor::End);
  table = nextCursor.insertTable(1, 1, tableFormat);
  table->cellAt(0, 0).firstCursorPosition().insertText(text);

  // Popup notification
  showMessage(from, text);

  QScrollBar *bar = ui->textEdit->verticalScrollBar();
  bar->setValue(bar->maximum());
}

void
ChatDialog::appendControlMessage(const QString& nick,
                                 const QString& action,
                                 time_t timestamp)
{
  QTextCharFormat nickFormat;
  nickFormat.setForeground(Qt::gray);
  nickFormat.setFontWeight(QFont::Bold);
  nickFormat.setFontUnderline(true);
  nickFormat.setUnderlineColor(Qt::gray);

  QTextCursor cursor(ui->textEdit->textCursor());
  cursor.movePosition(QTextCursor::End);
  QTextTableFormat tableFormat;
  tableFormat.setBorder(0);
  QTextTable *table = cursor.insertTable(1, 2, tableFormat);

  QString controlMsg = QString("%1 %2  ").arg(nick).arg(action);
  QTextTableCell fromCell = table->cellAt(0, 0);
  fromCell.setFormat(nickFormat);
  fromCell.firstCursorPosition().insertText(controlMsg);
  printTimeInCell(table, timestamp);
}

QString
ChatDialog::formatTime(time_t timestamp)
{
  struct tm *tm_time = localtime(&timestamp);
  int hour = tm_time->tm_hour;
  QString amOrPM;
  if (hour > 12) {
    hour -= 12;
    amOrPM = "PM";
  }
  else {
    amOrPM = "AM";
    if (hour == 0) {
      hour = 12;
    }
  }

  char textTime[12];
  sprintf(textTime, "%d:%02d:%02d %s",
          hour, tm_time->tm_min, tm_time->tm_sec, amOrPM.toStdString().c_str());
  return QString(textTime);
}

void
ChatDialog::printTimeInCell(QTextTable *table, time_t timestamp)
{
  QTextCharFormat timeFormat;
  timeFormat.setForeground(Qt::gray);
  timeFormat.setFontUnderline(true);
  timeFormat.setUnderlineColor(Qt::gray);
  QTextTableCell timeCell = table->cellAt(0, 1);
  timeCell.setFormat(timeFormat);
  timeCell.firstCursorPosition().insertText(formatTime(timestamp));
}

void
ChatDialog::showMessage(const QString& from, const QString& data)
{
  if (!isActiveWindow())
    emit showChatMessage(QString::fromStdString(m_chatroomName),
                         from, data);
}

void
ChatDialog::fitView()
{
  QRectF rect = m_scene->itemsBoundingRect();
  m_scene->setSceneRect(rect);
  ui->syncTreeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);

  QRectF trustRect = m_trustScene->itemsBoundingRect();
  m_trustScene->setSceneRect(trustRect);
  ui->trustTreeViewer->fitInView(m_trustScene->itemsBoundingRect(), Qt::KeepAspectRatio);
}

// public slots:
void
ChatDialog::onShow()
{
  this->show();
  this->raise();
  this->activateWindow();
}

void
ChatDialog::shutdown()
{
  if (m_backend.isRunning()) {
    emit shutdownBackend();
    m_backend.wait();
  }
  hide();
  emit closeChatDialog(QString::fromStdString(m_chatroomName));
}

// private slots:
void
ChatDialog::updateSyncTree(std::vector<chronochat::NodeInfo> updates, QString rootDigest)
{
  m_scene->processSyncUpdate(updates, rootDigest);
}

void
ChatDialog::receiveChatMessage(QString nick, QString text, time_t timestamp)
{
  appendChatMessage(nick, text, timestamp);
}

void
ChatDialog::addSession(QString sessionPrefix, QString nick, time_t timestamp)
{
  appendControlMessage(nick, "enters room", timestamp);
  m_scene->updateNick(sessionPrefix, nick);
  m_rosterModel->setStringList(m_scene->getRosterList());
}

void
ChatDialog::removeSession(QString sessionPrefix, QString nick, time_t timestamp)
{
  appendControlMessage(nick, "leaves room", timestamp);
  m_scene->removeNode(sessionPrefix);
  m_rosterModel->setStringList(m_scene->getRosterList());
}

void
ChatDialog::updateNick(QString sessionPrefix, QString nick)
{
  m_scene->updateNick(sessionPrefix, nick);
  m_rosterModel->setStringList(m_scene->getRosterList());
}

void
ChatDialog::receiveMessage(QString sessionPrefix)
{
  m_scene->messageReceived(sessionPrefix);
}

void
ChatDialog::updateLabels(Name newChatPrefix)
{
  // Reset DigestTree
  m_scene->clearAll();
  m_scene->plot("Empty");

  // Display chatroom name
  QString chatroomName = QString("Chatroom: %1").arg(QString::fromStdString(m_chatroomName));
  ui->infoLabel->setStyleSheet("QLabel {color: #630; font-size: 16px; font: bold \"Verdana\";}");
  ui->infoLabel->setText(chatroomName);

  // Display chat message prefix
  QString chatPrefix;
  if (PRIVATE_PREFIX.isPrefixOf(newChatPrefix)) {
    chatPrefix =
      QString("<Warning: no connection to hub or hub does not support prefix autoconfig.>\n"
              "<Prefix = %1>")
      .arg(QString::fromStdString(newChatPrefix.toUri()));
    ui->prefixLabel->setStyleSheet(
      "QLabel {color: red; font-size: 12px; font: bold \"Verdana\";}");
  }
  else {
    chatPrefix = QString("<Prefix = %1>")
      .arg(QString::fromStdString(newChatPrefix.toUri()));
    ui->prefixLabel->setStyleSheet(
      "QLabel {color: Green; font-size: 12px; font: bold \"Verdana\";}");
  }
  ui->prefixLabel->setText(chatPrefix);
}

void
ChatDialog::onReturnPressed()
{
  QString text = ui->lineEdit->text();

  if (text.isEmpty())
    return;

  ui->lineEdit->clear();

  time_t timestamp =
    static_cast<time_t>(time::toUnixTimestamp(time::system_clock::now()).count() / 1000);
  // appendChatMessage(m_nick, text, timestamp);

  emit msgToSent(text, timestamp);

  fitView();
}

void
ChatDialog::onSyncTreeButtonPressed()
{
  if (ui->syncTreeViewer->isVisible()) {
    ui->syncTreeViewer->hide();
    ui->syncTreeButton->setText("Show ChronoSync Tree");
  }
  else {
    ui->syncTreeViewer->show();
    ui->syncTreeButton->setText("Hide ChronoSync Tree");
  }

  fitView();
}

void
ChatDialog::onTrustTreeButtonPressed()
{
  if (ui->trustTreeViewer->isVisible()) {
    ui->trustTreeViewer->hide();
    ui->trustTreeButton->setText("Show Trust Tree");
  }
  else {
    ui->trustTreeViewer->show();
    ui->trustTreeButton->setText("Hide Trust Tree");
  }

  fitView();
}

void ChatDialog::enableSyncTreeDisplay()
{
  ui->syncTreeButton->setEnabled(true);
  ui->syncTreeViewer->show();
  fitView();
}

} // namespace chronochat


#if WAF
#include "chat-dialog.moc"
// #include "chat-dialog.cpp.moc"
#endif
