
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
//#include "read_coherence_mapsembler/couple.h"
#include "commons.h"
#include "../minia/Bank.h"

extern "C" {
#include "read_coherence_mapsembler/hash.h"
#include "read_coherence_mapsembler/list.h"
  //#include "read_coherence_mapsembler/simplehash.h"
}

#ifndef _FRAGMENT_H
#define _FRAGMENT_H

/**
 * A fragment designes a sequence together with its comment and some coverage information.
 * A fragment stores reads mapped on itself
 **/
class Fragment{
 public: 
  /**
   * true = the fragment is read coherent, else fase 
   */
  bool read_coherent;
  /**
   * the initial sequence
   */
  char * fragment_sequence; // the fragment to be kmer-coherency-tested
  /**
   * the eventual comment of the fragment (from fasta or fastq file)
   */
  char * fragment_comment; // the comment of the fragment to be kmer-coherency-tested
  /**
   * the hash table storing the reads mapped. key = read, value = list of mapping positions
   */
  hash_t Mapped; // USED FOR MAPPING READS TO FRAGMENT 
  /**
   * Stores the initial sequence, a stores a generic "todo comment"
   */
  Fragment(char *fragment_sequence);
  Fragment(char *fragment_sequence, char *fragment_header);

  bool isPalindromic();

  /**
   * delete the hash table and free the fragment sequence
   */
  ~Fragment(); 

};

class Fragment_Starting : public Fragment{
public:
    long starting_id_in_the_boolean_vector; // used to know if the current tested read (during mapping) was already tested on this fragment at a given position
    Fragment_Starting(char *fragment_sequence);
    Fragment_Starting(char *fragment_sequence, char *fragment_header);
    ~Fragment_Starting();
};
//with CHARQUAL, use an unsigned char to store qual values. To avoid overflow, compute average value 'on the fly'
#ifndef INTQUAL  // if compilation was NOT done with CFLAGS=-DINTQUAL, use the CHARQUAL option
#define CHARQUAL
#endif

class Mapped_Fragment : public Fragment{
public:
    /**
     * for every set of reads, 1 if the fragment is detected as read coherent, else =0
     */
    char * read_coherent;
	/**
     * number of reads covering this position can be a char, min coverage required is low
     */
#ifdef CHARQUAL
    
    /**
     *  number of reads covering the kmer starting at this position
     */
    unsigned char ** coverage;
	unsigned char ** sum_quality_per_position;	//for every set of reads, " " sum of the qualitites of reads mapping at that position if read coherent
#else
    int ** coverage;
    int ** sum_quality_per_position;
#endif
    
    
    /**
     * for every set of reads, number of reads starting (REPLACE reads_starting)
     */
    int * number_mapped_reads;
    
    Mapped_Fragment(char * fragment_sequence, const int number_of_read_sets);
    Mapped_Fragment(Mapped_Fragment * clone);
    ~Mapped_Fragment();
    void alloc_coverage_quality(const int nb);
};

#endif //_FRAGMENT_H
