#ifndef PROBTREE_H
#define PROBTREE_H
#include "ProbModel.h"
#include <fstream>
#include <vector>
#include <string>
using namespace std;


//#define MAX_CHR 100

#define MIN_THRES 1e-4

class Tree{
		int Num_Seqs;
		int Num_Children;
		REAL thres;
		Tree *Child;
		Tree *TailChild;
		Tree *Brother;
		Tree *Parent;
		ProbString TCenter;

	public:
		int SingleSeq;
		unsigned int UID;

		Tree();
		~Tree();
		Tree(unsigned int uid, int frq=1);
		Tree(ProbString & seq, int frq=1);
		void AddChild(Tree * subtree,bool recount=true);
		void DeleteChild(Tree *subtree);
		void SetThres(REAL th) {thres=th;};
		REAL GetThres() {return thres;};
		ProbString & Center() {return TCenter;};
		int & NumSeqs() {return Num_Seqs;};
		int NumChildren(){return Num_Children;};
		bool IsLeaf(){ return (Child==NULL);};
		bool BottomLevel() {if (Child==NULL) return true; else return Child->IsLeaf();};
		REAL FindSpanChild(Tree *node,Tree *&subtree,int id1=-1,int id2=-1,int sq1=0,int sq2=0);
		REAL FindSpanChild(unsigned int UID,Tree *&subtree);

		void AppendProbVect(ProbString &my_al,ProbString &seq_al,int numseq);

		void SubstractProbVect(ProbString &my_al,ProbString &seq_al,int numseq); 
		
		Tree *FirstChild() {return Child;};
		Tree *GetParent() {return Parent;};
		void BuildKmerCode();
		
		REAL KmerDist(REAL *kcode,int slen);
		REAL KmerDist(int *kcode,int *kseqs,int slen);
		REAL KmerDist(Tree *node);
		REAL NeedleDist(Tree *node);
		
//		void Expand(REAL minlevel);
		void Collapse(unsigned int uid);
		
		void Print( fstream & out);
		int Brief( fstream & out,int myid, int childid);
		
		void ListChildren(vector<Tree *> & tvec);
		void ListChildrenAt(REAL thres, vector<Tree *> & tvec);
		void ListLeaf(vector<Tree *> & tvec);
		void PrintAllSeqs( fstream & out);
		void CountUID(int *counter);
};
#endif
