/* -*- 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>
 */

#include "digest-tree-scene.hpp"

#include <QtGui>

#ifndef Q_MOC_RUN
#include <vector>
#include <iostream>
#include <assert.h>
#include <boost/lexical_cast.hpp>
#include <memory>
#endif

namespace chronos {

static const double Pi = 3.14159265358979323846264338327950288419717;

//DisplayUserPtr DisplayUserNullPtr;

DigestTreeScene::DigestTreeScene(QWidget *parent)
  : QGraphicsScene(parent)
{
  previouslyUpdatedUser = DisplayUserNullPtr;
}

void
DigestTreeScene::processUpdate(const std::vector<Sync::MissingDataInfo> &v, QString digest)
{
  int n = v.size();
  bool rePlot = false;
  for (int i = 0; i < n; i++) {
    QString routablePrefix(v[i].prefix.c_str());
    QString prefix = trimRoutablePrefix(routablePrefix);

    Roster_iterator it = m_roster.find(prefix);
    if (it == m_roster.end()) {
      // std::cout << "processUpdate v[" << i << "]: " << prefix.toStdString() << std::endl;
      rePlot = true;
      DisplayUserPtr p(new DisplayUser());
      time_t tempTime = ::time(NULL) - FRESHNESS + 1;
      p->setReceived(tempTime);
      p->setPrefix(prefix);
      p->setSeq(v[i].high);
      m_roster.insert(p->getPrefix(), p);
    }
    else {
      it.value()->setSeq(v[i].high);
    }
  }

  if (rePlot) {
    plot(digest);
    QTimer::singleShot(2100, this, SLOT(emitReplot()));
  }
  else {
    for (int i = 0; i < n; i++) {
      QString routablePrefix(v[i].prefix.c_str());
      QString prefix = trimRoutablePrefix(routablePrefix);

      Roster_iterator it = m_roster.find(prefix);
      if (it != m_roster.end()) {
        DisplayUserPtr p = it.value();
        QGraphicsTextItem *item = p->getSeqTextItem();
        QGraphicsRectItem *rectItem = p->getInnerRectItem();
        std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
        item->setPlainText(s.c_str());
        QRectF textBR = item->boundingRect();
        QRectF rectBR = rectItem->boundingRect();
        item->setPos(rectBR.x() + (rectBR.width() - textBR.width())/2,
                     rectBR.y() + (rectBR.height() - textBR.height())/2);
      }
    }
    m_rootDigest->setPlainText(digest);
  }
}

void
DigestTreeScene::emitReplot()
{
  emit replot();
}

QStringList
DigestTreeScene::getRosterList()
{
  QStringList rosterList;
  RosterIterator it(m_roster);
  while (it.hasNext()) {
    it.next();
    DisplayUserPtr p = it.value();
    if (p != DisplayUserNullPtr) {
      rosterList << "- " + p->getNick();
    }
  }
  return rosterList;
}

void
DigestTreeScene::msgReceived(QString routablePrefix, QString nick)
{
  QString prefix = trimRoutablePrefix(routablePrefix);
  Roster_iterator it = m_roster.find(prefix);
  // std::cout << "msgReceived prefix: " << prefix.toStdString() << std::endl;
  if (it != m_roster.end()) {
    // std::cout << "Updating for prefix = " << prefix.toStdString() <<
    // " nick = " << nick.toStdString() << std::endl;
    DisplayUserPtr p = it.value();
    p->setReceived(::time(NULL));
    if (nick != p->getNick()) {
      // std::cout << "old nick = " << p->getNick().toStdString() << std::endl;
      p->setNick(nick);
      QGraphicsTextItem *nickItem = p->getNickTextItem();
      QGraphicsRectItem *nickRectItem = p->getNickRectItem();
      nickItem->setPlainText(p->getNick());
      QRectF rectBR = nickRectItem->boundingRect();
      QRectF nickBR = nickItem->boundingRect();
      nickItem->setPos(rectBR.x() + (rectBR.width() - nickBR.width())/2, rectBR.y() + 5);
      emit rosterChanged(QStringList());
    }

    reDrawNode(p, Qt::red);

    if (previouslyUpdatedUser != DisplayUserNullPtr && previouslyUpdatedUser != p) {
      reDrawNode(previouslyUpdatedUser, Qt::darkBlue);
    }

    previouslyUpdatedUser = p;
  }
}

void
DigestTreeScene::clearAll()
{
  clear();
  m_roster.clear();
}

bool
DigestTreeScene::removeNode(const QString prefix)
{
  int removedCount = m_roster.remove(prefix);
  return (removedCount > 0);
}

void
DigestTreeScene::plot(QString digest)
{
#ifdef _DEBUG
  std::cout << "Plotting at time: " << ::time(NULL) << std::endl;
#endif
  clear();

  int nodeSize = 40;

  int siblingDistance = 100, levelDistance = 100;
  std::auto_ptr<TreeLayout> layout(new OneLevelTreeLayout());
  layout->setSiblingDistance(siblingDistance);
  layout->setLevelDistance(levelDistance);

  // do some cleaning, get rid of stale member info
  Roster_iterator it = m_roster.begin();
  QStringList staleUserList;
  while (it != m_roster.end()) {
    DisplayUserPtr p = it.value();
    if (p != DisplayUserNullPtr) {
      time_t now = ::time(NULL);
      if (now - p->getReceived() >= FRESHNESS) {
#ifdef _DEBUG
        std::cout << "Removing user: " << p->getNick().toStdString() << std::endl;
        std::cout << "now - last = " << now - p->getReceived() << std::endl;
#endif
        staleUserList << p->getNick();
        p = DisplayUserNullPtr;
        it = m_roster.erase(it);
      }
      else {
        if (!m_currentPrefix.startsWith("/private/local") &&
            p->getPrefix().startsWith("/private/local")) {
#ifdef _DEBUG
          std::cout << "erasing: " << p->getPrefix().toStdString() << std::endl;
#endif
          staleUserList << p->getNick();
          p = DisplayUserNullPtr;
          it = m_roster.erase(it);
          continue;
        }
        ++it;
      }
    }
    else {
      it = m_roster.erase(it);
    }
  }

  // for simpicity here, whenever we replot, we also redo the roster list
  emit rosterChanged(staleUserList);

  int n = m_roster.size();

  std::vector<TreeLayout::Coordinate> childNodesCo(n);

  layout->setOneLevelLayout(childNodesCo);

  plotEdge(childNodesCo, nodeSize);
  plotNode(childNodesCo, digest, nodeSize);

  previouslyUpdatedUser = DisplayUserNullPtr;

}

void
DigestTreeScene::plotEdge(const std::vector<TreeLayout::Coordinate> &childNodesCo, int nodeSize)
{
  int n = childNodesCo.size();
  for (int i = 0; i < n; i++) {
    double x1 = 0.0, y1 = 0.0;
    double x2 = childNodesCo[i].x, y2 = childNodesCo[i].y;
    QPointF src(x1 + nodeSize/2, y1 + nodeSize/2);
    QPointF dest(x2 + nodeSize/2, y2 + nodeSize/2);
    QLineF line(src, dest);
    double angle = ::acos(line.dx() / line.length());

    double arrowSize = 10;
    QPointF sourceArrowP0 = src + QPointF((nodeSize/2 + 10) * line.dx() / line.length(),
                                          (nodeSize/2 +10) * line.dy() / line.length());
    QPointF sourceArrowP1 = sourceArrowP0 + QPointF(cos(angle + Pi / 3 - Pi/2) * arrowSize,
                                                    sin(angle + Pi / 3 - Pi/2) * arrowSize);
    QPointF sourceArrowP2 = sourceArrowP0 + QPointF(cos(angle + Pi - Pi / 3 - Pi/2) * arrowSize,
                                                    sin(angle + Pi - Pi / 3 - Pi/2) * arrowSize);

    addLine(QLineF(sourceArrowP0, dest), QPen(Qt::black));
    addPolygon(QPolygonF() << sourceArrowP0<< sourceArrowP1 <<
               sourceArrowP2, QPen(Qt::black), QBrush(Qt::black));
  }
}

void
DigestTreeScene::plotNode(const std::vector<TreeLayout::Coordinate>& childNodesCo,
                          QString digest, int nodeSize)
{
  RosterIterator it(m_roster);
  int n = childNodesCo.size();
  int rim = 3;

  // plot root node
  QRectF rootBoundingRect(0, 0, nodeSize, nodeSize);
  QRectF rootInnerBoundingRect(rim, rim, nodeSize - rim * 2, nodeSize - rim * 2);
  addRect(rootBoundingRect, QPen(Qt::black), QBrush(Qt::darkRed));
  addRect(rootInnerBoundingRect, QPen(Qt::black), QBrush(Qt::lightGray));
  QRectF digestRect(- 5.5 * nodeSize , - nodeSize, 12 * nodeSize, 30);
  addRect(digestRect, QPen(Qt::darkCyan), QBrush(Qt::darkCyan));

  QGraphicsTextItem *digestItem = addText(digest);
  QRectF digestBoundingRect = digestItem->boundingRect();
  digestItem->setDefaultTextColor(Qt::black);
  digestItem->setFont(QFont("Cursive", 12, QFont::Bold));
  digestItem->setPos(- 4.5 * nodeSize + (12 * nodeSize - digestBoundingRect.width()) / 2,
                     - nodeSize + 5);
  m_rootDigest = digestItem;

  // plot child nodes
  for (int i = 0; i < n; i++) {
    if (it.hasNext())
      it.next();
    else
      abort();

    double x = childNodesCo[i].x;
    double y = childNodesCo[i].y;
    QRectF boundingRect(x, y, nodeSize, nodeSize);
    QRectF innerBoundingRect(x + rim, y + rim, nodeSize - rim * 2, nodeSize - rim * 2);
    DisplayUserPtr p = it.value();
    QGraphicsRectItem *rectItem = addRect(boundingRect, QPen(Qt::black), QBrush(Qt::darkBlue));
    p->setRimRectItem(rectItem);

    QGraphicsRectItem *innerRectItem = addRect(innerBoundingRect,
                                               QPen(Qt::black),
                                               QBrush(Qt::lightGray));
    p->setInnerRectItem(innerRectItem);

    std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
    QGraphicsTextItem *seqItem = addText(s.c_str());
    seqItem->setFont(QFont("Cursive", 12, QFont::Bold));
    QRectF seqBoundingRect = seqItem->boundingRect();
    seqItem->setPos(x + nodeSize / 2 - seqBoundingRect.width() / 2,
                    y + nodeSize / 2 - seqBoundingRect.height() / 2);
    p->setSeqTextItem(seqItem);

    QRectF textRect(x - nodeSize / 2, y + nodeSize, 2 * nodeSize, 30);
    QGraphicsRectItem *nickRectItem = addRect(textRect, QPen(Qt::darkCyan), QBrush(Qt::darkCyan));
    p->setNickRectItem(nickRectItem);
    QGraphicsTextItem *nickItem = addText(p->getNick());
    QRectF textBoundingRect = nickItem->boundingRect();
    nickItem->setDefaultTextColor(Qt::white);
    nickItem->setFont(QFont("Cursive", 12, QFont::Bold));
    nickItem->setPos(x + nodeSize / 2 - textBoundingRect.width() / 2, y + nodeSize + 5);
    p->setNickTextItem(nickItem);
  }

}

void
DigestTreeScene::reDrawNode(DisplayUserPtr p, QColor rimColor)
{
    QGraphicsRectItem *rimItem = p->getRimRectItem();
    rimItem->setBrush(QBrush(rimColor));
    QGraphicsRectItem *innerItem = p->getInnerRectItem();
    innerItem->setBrush(QBrush(Qt::lightGray));
    QGraphicsTextItem *seqTextItem = p->getSeqTextItem();
    std::string s = boost::lexical_cast<std::string>(p->getSeqNo().getSeq());
    seqTextItem->setPlainText(s.c_str());
    QRectF textBR = seqTextItem->boundingRect();
    QRectF innerBR = innerItem->boundingRect();
    seqTextItem->setPos(innerBR.x() + (innerBR.width() - textBR.width())/2,
                        innerBR.y() + (innerBR.height() - textBR.height())/2);
}

QString
DigestTreeScene::trimRoutablePrefix(QString prefix)
{
  bool encaped = false;
  ndn::Name prefixName(prefix.toStdString());

  size_t offset = 0;
  for (ndn::Name::const_iterator it  = prefixName.begin(); it != prefixName.end(); it++, offset++) {
    if (it->toUri() == "%F0.") {
      encaped = true;
      break;
    }
  }

  if (!encaped)
    return prefix;
  else
    return QString(prefixName.getSubName(offset+1).toUri().c_str());
}

} // namespace chronos

#if WAF
#include "digest-tree-scene.moc"
// #include "digest-tree-scene.cpp.moc"
#endif
