package org.fda.inputdataparser;

import org.fda.data.Utilities;
import org.fda.exceptions.IllegalIntervalException;
import org.fda.intervaltree.Interval;
import org.fda.intervaltree.IntervalSearchTree;

/**
 *
 * @author Gokhan.Yavas
 */
public class FastaRecord extends ReadRecord{
    private IntervalSearchTree nIntervalsTree=null;
    
    private byte[] hashValue;
    private byte[] seqHashValue;

    public byte[] getHashValue() {
        return hashValue;
    }
    public byte[] getSeqHashValue() {
        return seqHashValue;
    }    
    
    public IntervalSearchTree getnIntervalsTree() {
        return nIntervalsTree;
    }
    public FastaRecord(String header, String read, int gc_count){
        this.header = header;
        this.read = read;
        name = header.split("\\s+")[0].substring(1);
        this.gc_count = gc_count;
        this.gc_percent = Utilities.calcPercentage(gc_count, read.length());
        //this.hashValue = hashValue;
    }
    
    public FastaRecord(String header, String read, int gc_count, byte[] hashValue){
        this(header, read, gc_count);
        this.hashValue = hashValue;
    }
    public FastaRecord(String header, String read){
        //this.hashValue = hashValue;
        this.header = header;
        this.read = read;
        this.nIntervalsTree = new IntervalSearchTree();
        name = header.split("\\s+")[0].substring(1);
        
        // now find the n count and gc count
        boolean insideN=false;
        int stN=0,endN;
        for(int i=0; i<read.length(); i++){
            if(read.charAt(i)=='N' || read.charAt(i)=='n'){
                ncount++;                
                if(!insideN){
                    stN=i+1;
                }
                insideN=true;
            }
            else{
                if(insideN){
                    try {
                        insideN=false;
                        endN=i;
                        nIntervalsTree.put(new Interval(stN, endN, false));
                    } catch (IllegalIntervalException ex) {
                        ex.printStackTrace();
                    }
                }
                if(read.charAt(i)=='G' || read.charAt(i)=='g' || read.charAt(i)=='C' || read.charAt(i)=='c'){
                    gc_count++;
                }                
            }
        }
        if(insideN){
            try{
                nIntervalsTree.put(new Interval(stN, read.length(), false));
            } catch (IllegalIntervalException ex) {
                        ex.printStackTrace();
            }
        }
        nratio = (double)ncount / (double)getReadRecordLength();
        this.gc_percent = Utilities.calcPercentage(gc_count, read.length());
        //System.out.println(ncount);
    }    
    public FastaRecord(String header, String read, byte[] hashValue){
        this(header, read);
        this.hashValue=hashValue;
        
    }
    public FastaRecord(String header, String read, byte[] hashValue, byte[] seqHashValue){
        this(header, read, hashValue);
        this.seqHashValue = seqHashValue;                
    }
    
    public String formatRead(int linelength){
        if(linelength<=0)
            return name+Utilities.ls+read;
            

        StringBuilder sb = new StringBuilder(name+Utilities.ls);
        int rep = getReadRecordLength() / linelength;
        int st=0;
        int end=0;
        for(int i=0; i < rep ; i++){
            end = st + linelength;
            sb.append(read.substring(st, end)+Utilities.ls);
            st = end;
        }
        // Do the leftover
        if(st<getReadRecordLength())
            sb.append(read.substring(st));
        
        return sb.toString();            
    }
    @Override
    public String toString(){
        return formatRead(-1);
    }
    
}
