#ifndef MAF_H
#define MAF_H

#include "iterator.h"
#include "alias.h"
#include <string>
class MafBlock;

class MafRow {
	// holds a SINGLE ROW from a multiple alignment
	public:
		MafRow(MafBlock *p);
		char operator[] (int p);
		char left(int p); // left flank
		char right(int p); // right flank
		int hasflanks(int p);
		void setspecies(std::string s);
		void setstart(int s);
		void setsize(int s);
		void setstrand(char s);
		void setsrcSize(int s);
		void setText(std::string s);
		void setChar(char s, int pos);
		void setChr(std::string s);
		std::string get_nucs(int pos);
		int legal_nuc(int pos);
	private:
		std::string species; // index into PARENT species alias
		int count;
		double frac;
		int start;
		int size;
		char strand;
		int srcSize;
		int chromsize;
		std::string chr;
		std::string text;
		MafBlock *parent;
		friend class MafBlock;
		int score;
};

class MafBlock {
	// holds onto a SINGLE BLOCK from a multiple alignment
	public:
		MafBlock(Alias *a, int u);
		void addRow(std::string &s, std::string r);
		void setSister(std::string r, int s);
		int species(std::string &s);
		Iterator *build_iterator(Iterator *m, pfunc p);
		int set_nucs(Iterator *i);
		int operator++(int i);
		int positions();
		int legal_position();
		int currpos();
		int Size() {return size;}
		std::string key();
		int genomes() {return rows.size()-1+useref;}
		int hasref() {return ri != -1;}
		int hassister(int s) {return si[s] != -1;}
		int refstart();
		int refsize();
		void collapse_gaps();
		void strip_missing();
		void init();
		void build_consensus();
		int getStart(std::string spec, int coord);
		int getEnd(std::string spec, int coord);
		std::string getChr(std::string c);
	private:
		Alias *ali;
		int ri;
		int si[2];
		int size;
		int pos;
		int truepos;
		int useref;
		std::vector<MafRow> rows;
};

class MafTree {
	public:
		MafTree();
		~MafTree();
		void addBlock(MafBlock *block);
		void sortByRef();
		void operator++(int i);
		int hasMaf();
		MafBlock *current() { return blocks[curr]; }
	private:
		std::vector<MafBlock *> blocks;
		int curr;
};

#endif
