/*
    Copyright (C) 2012 Bartosz Broda, Jacek Bochenek, Łukasz Biłeńkij, 
    Damian Jaworski, Wojciech Mazur, Dominik Piasecki, Maciej Piasecki, 
    Radosław Ramocki
    
    This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.

    This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. 

    See the LICENSE and COPYING files for more details.
*/

#ifndef CLUTOTREESCENE_H
#define CLUTOTREESCENE_H

#include <QGraphicsScene>
#include "ui_mainwindow.h"
#include "node.h"
#include "bubblerect.h"
#include "qgraphicsclusteritem.h"
#include <stack>

/**
  Class representing graphics scene used to draw cluto tree
  */
class ClutoTreeScene : public QGraphicsScene
{
    Q_OBJECT

public:
    ClutoTreeScene(Ui::MainWindow *ui, QObject *parent = 0);

    /**
      Draw tree with node on the top of the stack as a root.
      Use recursive function DrawCluster
      */
    void DrawTree();

    /**
      Push new root onto the stack
      */
    void PushRoot(Node * root, bool clearStack);

    /**
      Remove current root from the stack
      */
    void PopRoot();
    void SetMaxLevel(size_t maxlevel);
    void SetLabels(std::vector<std::string> * labels);

    /**
      Highlight node under mouse pointer
      */
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);

    /**
      Traverse subtree and read labels from all leaves (left button)
      Pop the root and display tree - go level up (right button)
      */
    void mousePressEvent(QGraphicsSceneMouseEvent *event);

    /**
      Go to subtree with double-clicked node as a root
      */
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);

    /**
      Remove highlight from currently highlighted node
      */
    void Unhighlight();

    void SetSims(double min, double max);

signals:
    void RedrawingNeeded();
    void CenteringNeeded(int x, int y);
    void ShowLabels(Node * node);
    void UpdateSimNeeded(Node * node);

private:

    /**
      Recursive function, draws nodes of the tree
      */
    void DrawCluster(size_t yposition, size_t vlength, Node* node);

    /**
      Pointer to labels vector
      */
    std::vector<std::string> * labels;

    /**
      Pointer to main UI
      */
    Ui::MainWindow *ui;

    /**
      Stack of roots, node currenly displayed as a root is on the top
      */
    std::stack<Node *> roots;

    /**
      Max level (depth) in displayed tree
      */
    size_t maxlevel;

    /**
      Bubble rectangle showing on mouse move
      */
    BubbleRect * bubble;

    /**
      Currently highlighted item
      */
    QGraphicsClusterItem * highlighted;

    /**
      Number of levels skipped by displaying. Actually - the level of current root
      */
    size_t skippedLevels;

    /**
      Position to restore view, when popping the root from the stack.
      */
    QPointF restorePos;

    /**
      Max and min similarities in given tree
      */
    double maxSim, minSim;
};

#endif // CLUTOTREESCENE_H
