//
//  genometree.h
//  tree
//
//  Created by Nhan Ly-Trong on 09/02/2022.
//
#ifndef GENOMETREE_H
#define GENOMETREE_H

#include "genomenode.h"
#include "utils/timeutil.h"
#include <queue>
// using namespace std;

/**
A Genome Tree to present a genome by genome entry (each is a set of sites)
 */
class GenomeTree {
private:
    /**
        find a node that contains a given position
     */
    GenomeNode* findNodeByPos(GenomeNode* node, Insertion* insertion, int num_cumulative_gaps_from_parents, int num_cumulative_converts_from_parents);
    
    /**
        insert gaps into a sequence node
     */
    void insertGapsIntoSequenceNode(GenomeNode* node, Insertion* insertion, bool attach_insertion);
    
    /**
        convert gaps into normal characters
     */
    void convertGapsIntoNormal(GenomeNode *start_node);
    
public:
    /**
        starting pos in the original genome
     */
    GenomeNode* root;

    /**
        constructor
     */
    GenomeTree();
    
    /**
        init a root genome node
     */
    GenomeTree(int length);
    
    /**
        deconstructor
     */
    ~GenomeTree();
    
    /**
        build a genome tree from an insertion forward the insertion list
     */
    void buildGenomeTree(Insertion* insertion, int ori_seq_length, bool attach_insertion = false);
    
    /**
        update tree by accepting gaps (generated by a set of previous insertions) as normal characters
     */
    void updateGenomeTree(Insertion* start_insertion, Insertion* end_insertion);
    
    /**
        export new genome from original genome and genome tree
     */
    vector<short int> exportNewGenome(vector<short int> &ori_seq, int seq_length, int UNKOWN_STATE);
    
    /**
     export readable characters (for writing to file) from original genome and genome tree
     */
    void exportReadableCharacters(vector<short int> &ori_seq, int num_sites_per_state, vector<string> &state_mapping, string &output);

};
#endif
