/* -*- 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 "digesttreescene.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(ndn::shared_ptr<boost::asio::io_service> ioService,
                                 QWidget *parent)
  : QGraphicsScene(parent)
  , m_scheduler(*ioService)
{
  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++) 
  {
    Roster_iterator it = m_roster.find(v[i].prefix.c_str());
    if (it == m_roster.end()) 
    {
      rePlot = true; 
      DisplayUserPtr p(new DisplayUser());
      time_t tempTime = time(NULL) - FRESHNESS + 1;
      p->setReceived(tempTime);
      p->setPrefix(v[i].prefix.c_str());
      p->setSeq(v[i].high);
      m_roster.insert(p->getPrefix(), p);
    }
    else 
    {
      it.value()->setSeq(v[i].high);
    }
  }

  if (rePlot) 
  {
    plot(digest);
    m_scheduler.scheduleEvent(ndn::time::milliseconds(600), ndn::bind(&DigestTreeScene::emitReplot, this));
  }
  else 
  {
    for (int i = 0; i < n; i++) 
    {
      Roster_iterator it = m_roster.find(v[i].prefix.c_str());
      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 prefix, QString nick)
{
  Roster_iterator it = m_roster.find(prefix);
  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);
}

#if WAF
#include "digesttreescene.moc"
#include "digesttreescene.cpp.moc"
#endif
