package glycoMain;


import java.util.ArrayList;
import java.util.Hashtable;
import glycoMain.EnzymeProperties;

public class InputTreatment {

	String inputSugar;
	String outputSugar;
	String[] sugarTab;
	ArrayList<String> enz;
	boolean unklink;
	boolean iupac;
	boolean pbDigestion;
	EnzymeProperties dico;

	private Hashtable<String, Integer> section = new Hashtable <String, Integer> ();
	
	public InputTreatment(String inputSugar, ArrayList<String> enz, boolean unklink, boolean iupac){
		this.inputSugar = inputSugar;
		outputSugar = "";
		this.enz = enz;
		this.unklink = unklink;
		this.iupac = iupac;
		dico = new EnzymeProperties();
		pbDigestion=false;
		initDico(dico);
	}

	public void initDico(EnzymeProperties dico){
		/*
		 * INITIALIZE THE DICTIONNARY AND CREATE THE CORRESPONDANCE BETWEEN ENZYMES, RESIDUES AND LINK
		 */
//		TODO pk pas mettre tout dans le constructeur de enzymeProperties et ne pas faire ca? a voir
		dico.createDic_res();
		dico.createDic_link();
		dico.createFamily();
	}
	
	public boolean dataLoading (){
//		TODO ŕ voir si on ne peux pas faire une vérification mieux, tout en ne bloquant pas la digestion si il y a un probleme de ligne ds l'input
		/* 
		 * CREATE AN ARRAY WITH ALL THE GLYCANS (1 OR +) 
		 * from the textArea in the GUI
		 */		
//		ok checks if sequence is in a good format. if iupac is selected : no format check : we suppose that sequence is good
		boolean ok = true;
		if (!iupac){
			ok = false;		
			String[] eachLine = inputSugar.split("\n");	
			for (int i=0; i<eachLine.length; i++){
				boolean blank = eachLine[i].isEmpty();
				boolean sect = eachLine[i].equals("RES") | eachLine[i].equals("LIN") | eachLine[i].equals("UND") | eachLine[i].equals("ALT") |eachLine[i].equals("REP");
				boolean numb = false;
				for (int j=1; j<10; j++)
					if (eachLine[i].startsWith(String.valueOf(j))){
							 numb = true;
							 break;
					}
				if (blank || sect || numb)
					ok = true;
			}
		}
		sugarTab = inputSugar.trim().split("\n\n+");
		return ok;
	}			
	
	public void sectionCreation (String sugar){
		/*
		 * FILL THE DICTIONNARY 'SECTION' WITH 0 OR 1 IF THE DIFFERENT SECTIONS EXIST OR NOT
		 * REP : REPETITION
		 * ALT : ALTERNATIVE
		 * UND : UNDERDETERMINED
		 */
		section.put("LIN", 0);
		section.put("REP", 0);
		section.put("ALT", 0);
		section.put("UND", 0);
		if (sugar.contains("LIN\n"))
			section.put("LIN", 1);
		if (sugar.contains("REP\n"))
			section.put("REP", 1);
		if (sugar.contains("ALT\n"))
			section.put("ALT", 1);
		if (sugar.contains("UND\n"))
			section.put("UND", 1);
	}	
	

	public String getCurrentSugar(String[] sugarTab, int i) {
//		get the glycoCT sequence of current sugar to be treated: depending on format input.
//		avoid a big main glycanTreatment method
		String s = "";
		if (iupac)
			s = "RES" + sugarTab[i].split("RES",2)[1];
		else
			s = sugarTab[i];	
		s = s.trim();
		return s;
		
	}
	public String glycanFormatage(ArrayList<String> currentEnz, String currentSugar, String digestedCurrentSugar){
//		put all information together on the output : used enzymes, no change if no change and the digested sugar
		String enzList = "enzyme : " + currentEnz.get(0);
		for (int j = 1; j<currentEnz.size(); j++)
			enzList = enzList + " + " + currentEnz.get(j);
		outputSugar = outputSugar + "\n" +enzList;
		if (currentSugar.equals(digestedCurrentSugar))
			outputSugar = outputSugar + "\nno change";
		//caution : sometimes, there a change (remove 1 repetition but the numb is unknown...)
		outputSugar = outputSugar + "\n" + digestedCurrentSugar + "\n" ;
		currentEnz.clear();
		return digestedCurrentSugar;
	}
	
	public String glycanTreatment(){
		ArrayList<String> currentEnz = new ArrayList<String>();		
		String currentSugar = "";
		String digestedCurrentSugar = "";
		boolean goodFormat = dataLoading();

		if (goodFormat){
//			TREAT EACH GLYCAN ONE BY ONE
			for (int i = 0; i<sugarTab.length; i++){		
				currentEnz.clear();
				currentSugar = getCurrentSugar(sugarTab, i);
				sectionCreation(currentSugar);			
				try{

					outputSugar = outputSugar + "\n\nGLYCAN N° " + (i+1) + "\n\nUNDIGESTED\n" + currentSugar + "\n";
					
					//FOR EACH GLYCAN, DIGESTION WITH ALL COMBINATION OF ENZYMES
					int enzymeCounter = 1;
					while (enzymeCounter <= enz.size()){ 
						for (int en = 0; en<enzymeCounter; en++){							
							currentEnz.add(enz.get(en));
						}
											
						System.out.println(" \n------------------enz1 : " + currentEnz + "\nsugar : \n" + currentSugar +"\n---------------------------");
						SugarDigestion sugtreat = new SugarDigestion (currentSugar, dico, currentEnz, section, unklink);
						digestedCurrentSugar = sugtreat.digestion();		
						currentSugar = glycanFormatage(currentEnz, currentSugar, digestedCurrentSugar);
						
						//TODO peut-etre mettre un stop si la liste d'enzyme est finie
						sectionCreation(currentSugar);
						enzymeCounter++;	
					}	
				}
				catch (Exception ex){
					pbDigestion = true;
				}	
			}
		}		
		return outputSugar.trim();
	}
}
