/******************************************************************/
// Need:
//	- list of oligomers (ID and sequences), automatique get from html form
//	- list of sequences (ID and aligned sequences), automatique get from html form
//
// Return: array "data":
//		data[ID][oligo] = oligomer
//		data[ID][seq_list] = idseq1:seq1£idseq2: seq2 ... 
//		data[ID][pos1] = first position for oligomer in sequence set
//		data[ID][pos2] = second position for oligomer in sequence set
//		data[ID][sens] = 0 or 1 (=forward or reverse oligomer)
//
/******************************************************************/



/***************************************************************/

function dedegenerate(tab_primers) {

	for (i=0; i<tab_primers.length; i++) {
	
		if  ( (d_pos = tab_primers[i].search(/R/i)) != - 1 ) {

			tab_primers.push(tab_primers[i].replace(/R/i, "A"));
			tab_primers.push(tab_primers[i].replace(/R/i, "G"));
			tab_primers.splice(i,1);
			break;

		}
		
		if  ( (d_pos = tab_primers[i].search(/Y/i)) != - 1 ) {
			
			tab_primers.push(tab_primers[i].replace(/Y/i, "C"));
			tab_primers.push(tab_primers[i].replace(/Y/i, "T"));
			tab_primers.splice(i,1);
			break;
			
		}

		if  ( (d_pos = tab_primers[i].search(/S/i)) != - 1 ) {
			
			tab_primers.push(tab_primers[i].replace(/S/i, "C"));
			tab_primers.push(tab_primers[i].replace(/S/i, "G"));
			tab_primers.splice(i,1);
			break;
			
		}


		if  ( (d_pos = tab_primers[i].search(/W/i)) != - 1 ) {
			
			tab_primers.push(tab_primers[i].replace(/W/i, "T"));
			tab_primers.push(tab_primers[i].replace(/W/i, "A"));
			tab_primers.splice(i,1);
			break;
			
		}

		if  ( (d_pos = tab_primers[i].search(/K/i)) != - 1 ) {
			
			tab_primers.push(tab_primers[i].replace(/K/i, "T"));
			tab_primers.push(tab_primers[i].replace(/K/i, "G"));
			tab_primers.splice(i,1);
			break;
			
		}

		if  ( (d_pos = tab_primers[i].search(/M/i)) != - 1 ) {
			
			tab_primers.push(tab_primers[i].replace(/M/i, "A"));
			tab_primers.push(tab_primers[i].replace(/M/i, "C"));
			tab_primers.splice(i,1);
			break;
			
		}
		
		if  ( (d_pos = tab_primers[i].search(/B/i)) != - 1 ) {
			
			tab_primers.push(tab_primers[i].replace(/B/i, "C"));
			tab_primers.push(tab_primers[i].replace(/B/i, "G"));
			tab_primers.push(tab_primers[i].replace(/B/i, "T"));
			tab_primers.splice(i,1);
			break;
			
		}

		if  ( (d_pos = tab_primers[i].search(/D/i)) != - 1 ) {
			
			tab_primers.push(tab_primers[i].replace(/D/i, "A"));
			tab_primers.push(tab_primers[i].replace(/D/i, "T"));
			tab_primers.push(tab_primers[i].replace(/D/i, "G"));
			tab_primers.splice(i,1);
			break;
			
		}

		if  ( (d_pos = tab_primers[i].search(/V/i)) != - 1 ) {
			
			tab_primers.push(tab_primers[i].replace(/V/i, "A"));
			tab_primers.push(tab_primers[i].replace(/V/i, "C"));
			tab_primers.push(tab_primers[i].replace(/V/i, "G"));
			tab_primers.splice(i,1);
			break;
			
		}

		if  ( (d_pos = tab_primers[i].search(/H/i)) != - 1 ) {
			
			tab_primers.push(tab_primers[i].replace(/H/i, "A"));
			tab_primers.push(tab_primers[i].replace(/H/i, "C"));
			tab_primers.push(tab_primers[i].replace(/H/i, "T"));
			tab_primers.splice(i,1);
			break;
			
		}

		if  ( (d_pos = tab_primers[i].search(/N/i)) != - 1 ) {
			
			tab_primers.push(tab_primers[i].replace(/N/i, "C"));
			tab_primers.push(tab_primers[i].replace(/N/i, "G"));
			tab_primers.push(tab_primers[i].replace(/N/i, "T"));
			tab_primers.push(tab_primers[i].replace(/N/i, "A"));
			tab_primers.splice(i,1);
			break;
			
		}

	}
	
	
	test = 0;
	
	for (i=0; i<tab_primers.length; i++) {
		if ( tab_primers[i].search(/N|R|Y|S|W|K|M|B|D|V|H/i) != - 1) { test = 1; break;}
	}
	
	
	if (test==1) { tab_primers = dedegenerate(tab_primers); }
	else { return tab_primers; }
	

}


/****************************************************************/
/***** return positions for a primer into aligned sequences set ******/


function find_primer (set, primer) {

	// hack for degenerated primers
	var tab_primers = new Array();
	tab_primers[0] = primer; 
	 
	if ( tab_primers[0].search(/N|R|Y|S|W|K|M|B|D|V|H/i) != - 1) { tab_primers = dedegenerate(tab_primers); }
	
	for (i=0; i<tab_primers.length; i++) {
		
		var primer = tab_primers[i];
		
		for (id in set) {
			
			var POS1 = -1;
			var POS2 = -1;
			
			primer = primer.toLowerCase();
			var seq = set[id].toLowerCase();
			
			tmp_pos = seq.indexOf(primer);
			if (tmp_pos !=-1 ) { return Array(tmp_pos, tmp_pos+primer.length); }
			
			seq0 = seq.replace(/-/g, "");
			
			pos0 = seq0.indexOf(primer);
			pos1 = pos0 + primer.length;
		
			if (pos0 != -1) {

				tab_chaine = seq.split("");

				for (var i=0; i<seq.length; i++) {
		
					base = seq.charAt(i);
					if (base != "-" && pos0 !=0) { pos0--; }
					if (base != "-" && pos1 !=0) { pos1--; }
					
					if (pos0 == 0 && POS1== -1 ) { POS1 = i+1; }
					if (pos1 == 0 && POS2 == -1 ) { POS2 = i;  break;}
					
				}

				return new Array(POS1, POS2+1);
				
			}				
			
		}
	
	}

	return new Array(POS1, POS2+1);

}


/***********************************************************************/
/******** extract sequences that will be match with oligomers ****************/

function  extract_from_seq (seq, pos1, pos2) {


	var oligo = seq.substring(pos1,pos2);
	
	// we want to get neighbors nucleotids if oligo start or/and finish with some "-" caracters

	var expr = /^(-+)/;
	var resultat = expr.exec(oligo);
			
	if (resultat) { 
	
		i = RegExp.$1.length;
		seq1 = seq.substring(0,pos1-1);
		seq1 = seq1.replace(/-/g, "");
		seq1 = seq1.substring(-i, i);
	
		if (seq1>0) { oligo = seq1+""+oligo; }
	
	}

	expr = /(-+)$/;
	resultat = expr.exec(oligo);
			
	if (resultat) { 
	
		i = RegExp.$1.length;
		seq2 = seq.substring(0,pos1-1);
		seq2 = seq2.replace(/-/g, "");
		seq2 = seq2.substring(-i, i);
	
		if (seq2>0) { oligo = seq2+""+oligo; }
	
	}

//	return oligo.replace(/-/g, "");
	return oligo;

}


/**************************************************************/
/************ main function, return "data" array *******************/

function cut_seq () {


	var data = new Array();
	var sens = 0;
	var seq_length = 0;
	var hash = new Array();	// hash is the tab with id_sequences as key, and sequences as values
	
	
	// implement hash array with sequences
	for ( var j=0; j<document.getElementById('seq_list').length; j++ )  {
		hash[document.getElementById('seq_list').options[j].innerHTML] = document.getElementById('seq_list').options[j].value;
	}
	
	// get maximum length
	
	for (id in hash) {
		seq = hash[id];
		if ( seq.length > seq_length) { seq_length = seq.length; }
	}
	
	// check that all sequences has the same length and correct length
	
	for (id in hash) {
	
		seq = hash[id];
		if ( seq.length < seq_length ) {
			diff =  seq_length - seq.length;
			string = "";
			for (i=0; i<diff; i++) { string += "-"; }
			hash[id] = seq+""+string;
		}
	
	}
		
	
	for (var  i=0; i<document.getElementById('oligo_list').length; i++ ) {

		id_primer = document.getElementById('oligo_list').options[i].innerHTML;
		primer = document.getElementById('oligo_list').options[i].value;
		
		// try to find oligomer in the sequences set
	
		args = find_primer(hash , primer);
		pos1 = args[0];
		pos2 = args[1];

		// if none are found, try to find invert-complement oligomer
		
		sens = 0;
	
		if (pos1==-1) {
			
			primer0 = invert_complement(primer);
			args = find_primer(hash, primer0);
			pos1 = args[0];
			pos2 = args[1];
			sens = 1;

		}
		
		// if oligomer is found, extract cutted sequence
			
		if (pos1!=-1) {

			data[id_primer] = new Array();
			
			data[id_primer]["oligo"] = primer;
			data[id_primer]["pos1"] = pos1;
			data[id_primer]["pos2"] = pos2;
			data[id_primer]["seq_list"] = "";
			data[id_primer]["sens"] = sens;

			for (id in hash ) {
			
				seq = hash[id];
				seq = extract_from_seq (seq, pos1, pos2); 


				if (seq.replace(/-/g, "") != "" && seq.length<400) {
				
					if (data[id_primer]["seq_list"] == "") { data[id_primer]["seq_list"] = id+":"+seq; }
					else { data[id_primer]["seq_list"] += "£" +id+":"+seq; }
		
				}
			
			}
		
	
		}
		

	}
	
	return data;

}
