/*
 *  chimera.cpp
 *  Mothur
 *
 *  Created by Sarah Westcott on 8/11/09.
 *  Copyright 2009 Schloss Lab Umass Amherst. All rights reserved.
 *
 */

#include "mothurchimera.h"

//***************************************************************************************************************
//this is a vertical soft filter
string MothurChimera::createFilter(vector<Sequence*> seqs, float t) {
	try {
		filterString = "";
        int threshold = int (t * seqs.size());
		
		vector<int> gaps;	gaps.resize(seqs[0]->getAligned().length(), 0);
		vector<int> a;		a.resize(seqs[0]->getAligned().length(), 0);
		vector<int> t;		t.resize(seqs[0]->getAligned().length(), 0);
		vector<int> g;		g.resize(seqs[0]->getAligned().length(), 0);
		vector<int> c;		c.resize(seqs[0]->getAligned().length(), 0);
	
		filterString = (string(seqs[0]->getAligned().length(), '1'));
		
		//for each sequence
		for (int i = 0; i < seqs.size(); i++) {
		
			if (m->getControl_pressed()) { return filterString; }
		
			string seqAligned = seqs[i]->getAligned();
			
			if (seqAligned.length() != filterString.length()) {  m->mothurOut(seqs[i]->getName() + " is not the same length as the template sequences. Aborting!\n");  exit(1); }
		
			for (int j = 0; j < seqAligned.length(); j++) {
				//if this spot is a gap
				if ((seqAligned[j] == '-') || (seqAligned[j] == '.'))	{	gaps[j]++;	}
				else if (toupper(seqAligned[j]) == 'A')					{	a[j]++;		}
				else if (toupper(seqAligned[j]) == 'T')					{	t[j]++;		}
				else if (toupper(seqAligned[j]) == 'G')					{	g[j]++;		}
				else if (toupper(seqAligned[j]) == 'C')					{	c[j]++;		}
			}
		}
		
		//zero out spot where all sequences have blanks
		int numColRemoved = 0;
		for(int i = 0;i < seqs[0]->getAligned().length(); i++){
		
			if (m->getControl_pressed()) { return filterString; }
			
			if(gaps[i] == seqs.size())	{	filterString[i] = '0'; 	numColRemoved++;  }
			
			else if (((a[i] < threshold) && (t[i] < threshold) && (g[i] < threshold) && (c[i] < threshold))) {	filterString[i] = '0';	numColRemoved++;  }
		}

		if (threshold != 0) {  m->mothurOut("Filter removed " + toString(numColRemoved) + " columns.\n");    }
		
		return filterString;
	}
	catch(exception& e) {
		m->errorOut(e, "MothurChimera", "createFilter");
		exit(1);
	}
}
//***************************************************************************************************************
map<int, int> MothurChimera::runFilter(Sequence* seq) {
	try {
		map<int, int> maskMap;
		string seqAligned = seq->getAligned();
		string newAligned = "";
		int count = 0;
			
		for (int j = 0; j < seqAligned.length(); j++) {
			//if this spot is a gap
			if (filterString[j] == '1') { 
				newAligned += seqAligned[j]; 
				maskMap[count] = j;
				count++;
			}
		}
			
		seq->setAligned(newAligned);
		
		return maskMap;
	}
	catch(exception& e) {
		m->errorOut(e, "MothurChimera", "runFilter");
		exit(1);
	}
}
//***************************************************************************************************************
vector<Sequence*> MothurChimera::readSeqs(string file) {
	try {
		
		vector<Sequence*> container;
		int count = 0;
		length = 0;
		unaligned = false;
		
        
        m->mothurOut("Reading sequences from " + file + "..."); cout.flush();
        
        
        ifstream in;
        Utils util; util.openInputFile(file, in);
        
        //read in seqs and store in vector
        while(!in.eof()){
            
            if (m->getControl_pressed()) { return container; }
            
            Sequence* current = new Sequence(in);  util.gobble(in);
            
            if (count == 0) {  length = current->getAligned().length();  count++;  } //gets first seqs length
            else if (length != current->getAligned().length()) {   unaligned = true;	}
            
            if (current->getName() != "") { container.push_back(current); }
        }
        in.close();
        
        m->mothurOut("Done.\n"); 
        
        filterString = (string(container[0]->getAligned().length(), '1'));
		
		
		return container;
	}
	catch(exception& e) {
		m->errorOut(e, "MothurChimera", "readSeqs");
		exit(1);
	}
}
//***************************************************************************************************************
void MothurChimera::setMask(string filename) {
	try {
		
		if (filename == "default") {
			//default is from wigeon  236627 EU009184.1 Shigella dysenteriae str. FBD013
			seqMask = ".....................................................................................................[encoded data, 6749 characters]................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................";
		}else if (filename == "") {  //do nothing 
			seqMask = "";
		}else{
		
            ifstream infile;
            Utils util; util.openInputFile(filename, infile);
            
            if (!infile.eof()) {
                Sequence temp(infile);
                seqMask = temp.getAligned();
            }else {
                m->mothurOut("Problem with mask.\n"); 
                seqMask = "";
            }
            infile.close();
		}
	}
	catch(exception& e) {
		m->errorOut(e, "MothurChimera", "setMask");
		exit(1);
	}
}
//***************************************************************************************************************
Sequence* MothurChimera::getSequence(string name) {
	try{
		Sequence* temp;
		
		//look through templateSeqs til you find it
		int spot = -1;
		for (int i = 0; i < templateSeqs.size(); i++) {
			if (name == templateSeqs[i]->getName()) {  
				spot = i;
				break;
			}
		}
		
		if(spot == -1) { m->mothurOut("Error: Could not find sequence.\n");  return NULL; }
		
		temp = new Sequence(templateSeqs[spot]->getName(), templateSeqs[spot]->getAligned());
		
		return temp;
	}
	catch(exception& e) {
		m->errorOut(e, "MothurChimera", "getSequence");
		exit(1);
	}
}
//***************************************************************************************************************




