/*
 * Edge.cpp
 *
 * Implementacja klasy opisanej w pliku nagłówkowym
 *
 *  Created on: 2010-01-07
 *      Author: Piotr Gwizdała
 */

#include "Edge.h"
#include <sstream>

Edge::Edge(int startIndex, int endIndex, Node *startNode) {
	this->startInd = startIndex;
	this->endInd = endIndex;
	this->startN = startNode;
	this->endN = new Node(startNode->tree, NULL, this);
	this->insertToParentEdgeList();
}

Edge::~Edge() {

}


Node* Edge::split(Suffix *s) {
	//usunięcie tej krawędzi z węzła-ojca
	this->removeFromParentEdgeList();
	//utworzenie nowej krawędzi zgodnie z dodawanym sufiksem (niejawnie powstaje nowy węzeł - liść)
        Edge* ne = new Edge(this->startInd, this->startInd + s->getPhraseLength(), s->originNode);
	//ustawienie wskaźnika na następny mniejszy sufiks w drzewie
	ne->endN->suffixNode = s->originNode;
	//wycięcie starego początku tekstu (teraz jest on na nowej krawędzi) i dodanie nowego znaku
	this->startInd += s->getPhraseLength() + 1;
	//podpięcie tej krawędzi na koniec nowopowstałej krawędzi
	this->startN = ne->endN;
	this->insertToParentEdgeList();
	//Zwracany jest nowy węzeł
	return ne->endN;
}


void Edge::insertToParentEdgeList() {
	this->startN->addEdge(this->startInd, this);
}

void Edge::removeFromParentEdgeList() {
	this->startN->removeEdge(this->startInd);
}

int Edge::getPhraseLength() {
	return this->endInd - this->startInd;
}

int Edge::getFullSuffixLength() {
    int mtl = startN->tree->text.length();

    int realEnd = (this->endInd < 0 ? mtl : this->endInd);
    if (realEnd > mtl) realEnd = mtl-1;

    int tt = realEnd - startInd+1;
    int pt = 0;
    if (startN->parentEdge != NULL) pt = startN->parentEdge->getFullSuffixLength();
    return pt+tt;
}

string Edge::getEdgeText() {
        string text = startN->tree->text;
        int realEnd = (this->endInd < 0 ? text.length() : this->endInd);
        if (realEnd > (int)text.length()) realEnd = text.length()-1;
        text = text.substr(this->startInd, realEnd - this->startInd +1);
        return text;
}


string Edge::getEdgeFullText() {
    string tt = getEdgeText();
    string pt;
    if (startN->parentEdge != NULL) pt = startN->parentEdge->getEdgeFullText();
    return pt+tt;
}

string Edge::toString() {
	stringstream ss;
	string text = startN->tree->text;
	int realEnd = (this->endInd < 0 ? text.length() : this->endInd);
	if (realEnd > (int)text.length()) realEnd = text.length()-1;
	text = text.substr(this->startInd, realEnd - this->startInd +1);
	ss<<startInd<<"\t"<<realEnd<<"\t";
	ss<<this->startN->toString()<<"\t"<<this->endN->toString()<<"\t"<<text;
	return ss.str();
}






