/* -*- 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(0) + 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(0) + 1);
    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
