import java.util.ArrayList;

/**
 * Class for reconstructing a genome out of several shotgunned
 * sequences. This version is slow in that it checks for merges
 * and containment separately.
 * 
 * @author Owen Astrachan
 */
public class ShotgunReconstructor {
    private ArrayList myStrands;
    
    public ShotgunReconstructor(ArrayList list){
        myStrands = list;
    }
    
    /**
     * Return true if list of strands has been altered by merging,
     * returns false otherwise. In the case that true is returned, the
     * number of strands has decreased based on a merge.
     * @return true iff a merge of strands occurred
     */
    public boolean merge(){

        for(int j=0; j < myStrands.size(); j++){
            IStrand sj = (IStrand) myStrands.get(j);
            for(int k=0; k < myStrands.size(); k++){
                if (j != k){
                    IStrand sk = (IStrand) myStrands.get(k);
                    IStrand m = (IStrand) sj.merge(sk,12);
                    if (m != null){
                        if (j > k){
                            int temp = j;
                            j = k;
                            k = temp;
                        }
                        // remove strands k and j, add strand m
                        // TODO: add code to do this
                         
                        return true;
                    }
                } 
            }
        }
        return false;
    }
    
    /**
     * Return true if list of strands reduced by containment, e.g.,
     * one strand contained in another. If so, the contained strand (shorter)
     * is removed from the list.
     * @return true if list of strands reduced via containment.
     */
    public boolean reduce(){
        int osize = myStrands.size();
        for(int j=0; j < myStrands.size(); j++){
            IStrand sj = (IStrand) myStrands.get(j);
            for(int k=0; k < myStrands.size(); k++){
                if (j != k){
                    IStrand sk = (IStrand) myStrands.get(k);
                    if (sk.contains(sj)){
                        myStrands.remove(j);
                        break;
                    }
                }
            }
        }
        return myStrands.size() != osize;
    }
    
    /**
     * Do whole shotgun reconstruction, return time for doing it.
     * @return time of shotgun reconstruction
     */
    public double doGun(){
        double start = System.currentTimeMillis();
        while (reduce() || merge()){
            System.out.println("now size = "+myStrands.size());
        }
        double end = System.currentTimeMillis();
        return (end-start)/1000;
    }
    
    public ArrayList getStrands(){
        return myStrands;
    }
}
