/* -*- 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.h"

#include <QtGui>

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

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());

  ndn::Name::const_iterator it  = prefixName.begin();
  ndn::Name::const_iterator end = prefixName.end();
  size_t offset = 0;

  for(; it != end; it++, offset++)
    {
      if(it->toEscapedString() == "%F0.")
        {
          encaped = true;
          break;
        }
    }

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

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