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

#ifndef DIGEST_TREE_SCENE_H
#define DIGEST_TREE_SCENE_H

#include <QtGui/QGraphicsScene>
#include <QColor>
#include <QMap>

#ifndef Q_MOC_RUN
#include "tree-layout.h"
#include <sync-seq-no.h>
#include <sync-logic.h>
#include <ctime>
#include <vector>
#include <boost/shared_ptr.hpp>
#endif

const int FRESHNESS = 60;

class QGraphicsTextItem;

class User;
class DisplayUser;
typedef boost::shared_ptr<DisplayUser> DisplayUserPtr;
static DisplayUserPtr DisplayUserNullPtr;

class DigestTreeScene : public QGraphicsScene
{
  Q_OBJECT

typedef QMap<QString, DisplayUserPtr> Roster;
typedef QMap<QString, DisplayUserPtr>::iterator Roster_iterator;
typedef QMapIterator<QString, DisplayUserPtr> RosterIterator;

public:
  DigestTreeScene(QWidget *parent = 0);
  void processUpdate(const std::vector<Sync::MissingDataInfo> &v, QString digest);
  void msgReceived(QString prefix, QString nick);
  void clearAll();
  bool removeNode(const QString prefix);
  void plot(QString digest);
  QStringList getRosterList();
  void setCurrentPrefix(QString prefix) {m_currentPrefix = prefix;}
  QMap<QString, DisplayUserPtr> getRosterFull() { return m_roster;}

signals:
  void replot();
  void rosterChanged(QStringList);

private slots:
  void emitReplot();

private:
  void plotEdge(const std::vector<TreeLayout::Coordinate> &v, int nodeSize);
  void plotNode(const std::vector<TreeLayout::Coordinate> &v, QString digest, int nodeSize);
  void reDrawNode(DisplayUserPtr p, QColor rimColor);

  QString trimRoutablePrefix(QString prefix);

private:
  Roster m_roster;
  QGraphicsTextItem *m_rootDigest;
  DisplayUserPtr previouslyUpdatedUser;
  QString m_currentPrefix;
};

class User
{
public:
  User():m_received(time(NULL)) {}
  User(QString n, QString p, QString c): m_nick(n), m_prefix(p), m_chatroom(c), m_received(time(NULL)) {}
  void setNick(QString nick) {m_nick = nick;}
  void setPrefix(QString prefix) {m_prefix = prefix;}
  void setChatroom(QString chatroom) {m_chatroom = chatroom;}
  void setSeq(Sync::SeqNo seq) {m_seq = seq;}
  void setReceived(time_t t) {m_received = t;}
  void setOriginPrefix(QString originPrefix) { m_originPrefix = originPrefix;}
  QString getNick() { return m_nick;}
  QString getPrefix() { return m_prefix;}
  QString getChatroom() { return m_chatroom;}
  QString getOriginPrefix() { return m_originPrefix;}
  Sync::SeqNo getSeqNo() { return m_seq;}
  time_t getReceived() { return m_received;}
private:
  QString m_nick;
  QString m_prefix;
  QString m_chatroom;
  QString m_originPrefix;
  Sync::SeqNo m_seq;
  time_t m_received;
};

class DisplayUser : public User
{
public:
  DisplayUser():m_seqTextItem(NULL), m_nickTextItem(NULL), m_rimRectItem(NULL) {}
  DisplayUser(QString n, QString p , QString c): User(n, p, c), m_seqTextItem(NULL), m_nickTextItem(NULL), m_rimRectItem(NULL) {}
  QGraphicsTextItem *getSeqTextItem() {return m_seqTextItem;}
  QGraphicsTextItem *getNickTextItem() {return m_nickTextItem;}
  QGraphicsRectItem *getRimRectItem() {return m_rimRectItem;}
  QGraphicsRectItem *getInnerRectItem() {return m_innerRectItem;}
  QGraphicsRectItem *getNickRectItem() {return m_nickRectItem;}
  void setSeqTextItem(QGraphicsTextItem *item) { m_seqTextItem = item;}
  void setNickTextItem(QGraphicsTextItem *item) { m_nickTextItem = item;}
  void setRimRectItem(QGraphicsRectItem *item) {m_rimRectItem = item;}
  void setInnerRectItem(QGraphicsRectItem *item) {m_innerRectItem = item;}
  void setNickRectItem(QGraphicsRectItem *item) {m_nickRectItem = item;}
private:
  QGraphicsTextItem *m_seqTextItem;
  QGraphicsTextItem *m_nickTextItem;
  QGraphicsRectItem *m_rimRectItem;
  QGraphicsRectItem *m_innerRectItem;
  QGraphicsRectItem *m_nickRectItem;
};

#endif // DIGEST_TREE_SCENE_H
