package org.fda.evaluator;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.fda.alignment.ScaffoldContig;
//import org.fda.data.Enums.QUALITYLEVEL;
import org.fda.data.QUAL;
import org.fda.data.ReferenceSet;
import org.fda.data.Utilities;

/**
 *
 * @author Gokhan.Yavas
 */
public class Processor {
    
    private final File outdir;

    //private final Map<QUALITYLEVEL, IntervalMerger> qualIntMergerMap;
    private final Map<QUAL, IntervalMerger> qualIntMergerMap;

    private final ReferenceSet refSet;
    private long totContigSizeWOgaps=0L;

    public long getTotContigSizeWOgaps() {
        return totContigSizeWOgaps;
    }
        
    public Processor(EvaluatorBase ev, ReferenceSet cset, File outdir){
        
        refSet = cset;

        this.outdir = outdir;

        this.qualIntMergerMap = new TreeMap<>();
        
        
        //for(QUALITYLEVEL c : QUALITYLEVEL.values()){
        for(QUAL c : Utilities.qlevel.getQlevels()){
            try {
                qualIntMergerMap.put(c, new IntervalMerger(cset, c, ev));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    
    public void process(ScaffoldContig ast){
        totContigSizeWOgaps+=ast.getContigLength()-ast.getNcount();
        //List<QUALITYLEVEL> levels = QUALITYLEVEL.allValidLevels(ast.getQuality());
        List<QUAL> levels = Utilities.qlevel.allValidLevels(ast.getQuality());
        //for(QUALITYLEVEL c : levels){
        for(QUAL c : levels){
            try {
                qualIntMergerMap.get(c).process(ast, true);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    
    private List<Double> getRatio(boolean rev, boolean diff, int cov){
        IntervalMerger im;
        List<Double> ret = new ArrayList<>();
        //QUALITYLEVEL  c = rev ? QUALITYLEVEL.maxLevel() : QUALITYLEVEL.minLevel();
        QUAL  c = rev ? Utilities.qlevel.getHighest() : Utilities.qlevel.getLowest();
        
        double p = 0;
        double curr=0;
        for(;true;){
            if(c==null)
                break;
            im = qualIntMergerMap.get(c);
            
            if(cov==0)
                curr = im.getTotCovRatio();
            else if(cov==1)
                curr = im.getInvDupRatio();
            else
                curr = im.getValidityRatio();
            if(diff) 
                ret.add((curr-p));
            else
                ret.add(curr);
            p = curr;
            c = rev ? c.getPrev() : c.getNext();
        }        
        return ret;
    }
    public void finalizeProcess(){
        for(IntervalMerger im : qualIntMergerMap.values())
            im.finalize_process(getTotContigSizeWOgaps());
    }
    public List<Double> getCoverageRatio(){
        return getRatio(true, false, 0);
    }
    public List<Double> getInvDupRatio(){
        return getRatio(true, false, 1);
    }
    public List<Double> getValidityRatio(){
        return getRatio(true, false, 2);
    }    
    
}
