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

#include "dendrogramscene.h"
#include <QGraphicsTextItem>
#include <QGraphicsLineItem>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <cmath>

DendrogramScene::DendrogramScene(Ui::MainWindow *ui, QObject *parent) : QGraphicsScene(parent)
{
    this->ui = ui;
    this->setItemIndexMethod(QGraphicsScene::NoIndex);
}

void DendrogramScene::SetRoot(Node *root)
{
    this->root = root;
}

void DendrogramScene::DrawTree(size_t maxWidth)
{
    yoffset = 0;
    this->maxWidth = maxWidth - 60;
    this->clear();
    //Traverse tree
    DrawCluster(root);
}

double log(double x, double base)
{
    return (log10(x) / log10(base));
}

void DendrogramScene::DrawCluster(Node * node)
{
    if (node->HasChildren())
    {
	for (size_t i = 0; i < node->GetChildrenNo(); ++i)
	{
	    DrawCluster(node->GetChild(i));
	}
    }
    else
    {
	//Draw leaf ID or Label (to add)
	QGraphicsTextItem * text = new QGraphicsTextItem(QString::fromStdString(boost::lexical_cast<std::string>(node->GetID())));
	text->setPos(0, yoffset);
	node->SetOffsets(0, yoffset);
	yoffset += 50;
	this->addItem(text);
	return;
    }
    //Draw node with lines
    QGraphicsTextItem * text = new QGraphicsTextItem(QString::fromStdString(boost::lexical_cast<std::string>(node->GetID())));

    //Y-position of current node
    size_t ypos = (node->GetChild(0)->GetYOffset() + node->GetChild(1)->GetYOffset()) / 2;

//  Linear normalization (old)
//    double alfa = (node->GetSimilarity() - minSim) / (maxSim - minSim);

    //Logarithm normalization of similarities
    double base = ui->spinBox_4->value();
    double sim = 1 + (-1) * node->GetSimilarity();
    double max = 1 + (-1) * minSim;
    double min = 1 + (-1) * maxSim;

    //FIXME: alfa seems to be always the same value (independent from choosen log base)
    double alfa = (log(sim, base) - log(min, base)) / (log(max, base) - log(min, base));

    std::cout << "Node: " << node->GetID() << " sim: " << node->GetSimilarity() << " log: " << log(sim, base) << " alfa: " << alfa << " max: " << max << " min: " << min << std::endl;

    //X-position of current node
    size_t xpos = (alfa) * maxWidth;

    node->SetOffsets(xpos, ypos);
    text->setPos(xpos, ypos);
    this->addItem(text);

    //Create lines
    QGraphicsLineItem * line1 = new QGraphicsLineItem(node->GetChild(0)->GetXOffset() + 20, node->GetChild(0)->GetYOffset() + 10, xpos, node->GetChild(0)->GetYOffset() + 10);
    QGraphicsLineItem * line2 = new QGraphicsLineItem(node->GetChild(1)->GetXOffset() + 20, node->GetChild(1)->GetYOffset() + 10, xpos, node->GetChild(1)->GetYOffset() + 10);
    QGraphicsLineItem * line3 = new QGraphicsLineItem(xpos, node->GetChild(0)->GetYOffset() + 10, xpos, node->GetChild(1)->GetYOffset() + 10);

    this->addItem(line1);
    this->addItem(line2);
    this->addItem(line3);
}

void DendrogramScene::SetSims(double min, double max)
{
    minSim = min;
    maxSim = max;
}
