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


var delta=new Array(16);
var init=new Array(4);
var simple_mismatch=new Array(16);
var tetra_loop=new Array(13);

//......................................................................
//initialisation en dur des données de thermodynamique

function Watson_crick(){
	
	for(i=0;i<16;i++)
		delta[i]=new Array(2);
		delta[0]=new Array(-8400,-1020);
		delta[1]=new Array(-8600,-1430);
		delta[2][0]=-6100;delta[2][1]=-1160;
		delta[3][0]=-6500;delta[3][1]=-730;
		delta[4][0]=-7400;delta[4][1]=-1380;
		delta[5][0]=-6700;delta[5][1]=-1770;
		delta[6][0]=-10100;delta[6][1]=-2090;
		delta[7][0]=-6100;delta[7][1]=-1160;
		delta[8][0]=-7700;delta[8][1]=-1460;
		delta[9][0]=-11100;delta[9][1]=-2280;
		delta[10][0]=-6700;delta[10][1]=-1770;
		delta[11][0]=-8600;delta[11][1]=-1430;
		delta[12][0]=-6300;delta[12][1]=-600;
		delta[13][0]=-7700;delta[13][1]=-1460;
		delta[14][0]=-7400;delta[14][1]=-1380;
		delta[15][0]=-8400;delta[15][1]=-1020;
		init[0]=new Array(0,2800);
		init[1]=new Array(0,2800);
		init[2]=new Array(0,1820);
		init[3]=new Array(0,1820);          
		for(i=0;i<16;i++){
		simple_mismatch[i]=new Array(3);
		for(j=0;j<3;j++)
			simple_mismatch[i][j]=new Array(2);
		}
		simple_mismatch[0][0][0]=1200;simple_mismatch[0][0][1]=610;
		simple_mismatch[0][1][0]=2300;simple_mismatch[0][1][1]=880;
		simple_mismatch[0][2][0]=-600;simple_mismatch[0][2][1]=140;
		simple_mismatch[1][0][0]=5300;simple_mismatch[1][0][1]=770;
		simple_mismatch[1][1][0]=0;simple_mismatch[1][1][1]=1330;
		simple_mismatch[1][2][0]=700;simple_mismatch[1][2][1]=640;
		simple_mismatch[2][0][0]=-700;simple_mismatch[2][0][1]=20;
		simple_mismatch[2][1][0]=-3100;simple_mismatch[2][1][1]=-130;
		simple_mismatch[2][2][0]=1000;simple_mismatch[2][2][1]=710;
		simple_mismatch[3][0][0]=-1200;simple_mismatch[3][0][1]=730;
		simple_mismatch[3][1][0]=2500;simple_mismatch[3][1][1]=70;
		simple_mismatch[3][2][0]=-2700;simple_mismatch[3][2][1]=690;
		simple_mismatch[4][0][0]=-900;simple_mismatch[4][0][1]=430;
		simple_mismatch[4][1][0]=1900;simple_mismatch[4][1][1]=750;
		simple_mismatch[4][2][0]=-700;simple_mismatch[4][2][1]=30;
		simple_mismatch[5][0][0]=600;simple_mismatch[5][0][1]=790;
		simple_mismatch[5][1][0]=-1500;simple_mismatch[5][1][1]=700;
		simple_mismatch[5][2][0]=-800;simple_mismatch[5][2][1]=620;
		simple_mismatch[6][0][0]=-4000;simple_mismatch[6][0][1]=110;
		simple_mismatch[6][1][0]=-4900;simple_mismatch[6][1][1]=-110;
		simple_mismatch[6][2][0]=-4100;simple_mismatch[6][2][1]=-470;
		simple_mismatch[7][0][0]=-1500;simple_mismatch[7][0][1]=400;
		simple_mismatch[7][1][0]=-2800;simple_mismatch[7][1][1]=-320;
		simple_mismatch[7][2][0]=-5000;simple_mismatch[7][2][1]=-120;
		simple_mismatch[8][0][0]=-2900;simple_mismatch[8][0][1]=170;
		simple_mismatch[8][1][0]=5200;simple_mismatch[8][1][1]=810;
		simple_mismatch[8][2][0]=-600;simple_mismatch[8][2][1]=-250;
		simple_mismatch[9][0][0]=-700;simple_mismatch[9][0][1]=470;
		simple_mismatch[9][1][0]=3600;simple_mismatch[9][1][1]=790;
		simple_mismatch[9][2][0]=2300;simple_mismatch[9][2][1]=620;
		simple_mismatch[10][0][0]=500;simple_mismatch[10][0][1]=-520;
		simple_mismatch[10][1][0]=-6000;simple_mismatch[10][1][1]=-1110;
		simple_mismatch[10][2][0]=3300;simple_mismatch[10][2][1]=80;
		simple_mismatch[11][0][0]=5200;simple_mismatch[11][0][1]=980;
		simple_mismatch[11][1][0]=-4400;simple_mismatch[11][1][1]=-590;
		simple_mismatch[11][2][0]=-2200;simple_mismatch[11][2][1]=450;
		simple_mismatch[12][0][0]=4700;simple_mismatch[12][0][1]=690;
		simple_mismatch[12][1][0]=3400;simple_mismatch[12][1][1]=920;
		simple_mismatch[12][2][0]=700;simple_mismatch[12][2][1]=420;
		simple_mismatch[13][0][0]=7600;simple_mismatch[13][0][1]=1330;
		simple_mismatch[13][1][0]=6100;simple_mismatch[13][1][1]=1050;
		simple_mismatch[13][2][0]=1200;simple_mismatch[13][2][1]=970;
		simple_mismatch[14][0][0]=3000;simple_mismatch[14][0][1]=740;
		simple_mismatch[14][1][0]=1600;simple_mismatch[14][1][1]=440;
		simple_mismatch[14][2][0]=-100;simple_mismatch[14][2][1]=430;
		simple_mismatch[15][0][0]=1000;simple_mismatch[15][0][1]=750;
		simple_mismatch[15][1][0]=-1300;simple_mismatch[15][1][1]=340;
		simple_mismatch[15][2][0]=200;simple_mismatch[15][2][1]=680;
		for(i=0;i<tetra_loop.length;i++)
		tetra_loop[i]=-2000;
}
	
//......................................................................
// fonctions de recherche des double liasons
function doublon(a,b){

	i=0;
	switch(a){
		case 0 :i=0;break;
		case 1 :i=4;break;
		case 2 :i=8;break;
		case 3 :i=12;break;
		default  :i=-4;
	}
	switch(b){
		case 0 :i+=0;break;
		case 1 :i+=1;break;
		case 2 :i+=2;break;
		case 3 :i+=3;break;
		default  :i=-1;
	}
	if(i>=0)
		return delta[i];
	else
		return (0,0);
}

function mismatch(a,b,c){
	i=b;
	j=c;
	if(j>(3-i))
		j--;
	i+=4*a;
	if ((j>=0)&&(i>=0)&&(i<simple_mismatch.length)&&(j<simple_mismatch[0].length))
		return simple_mismatch[i][j];
	else
		return (0,0);
}

function existe_init(a,b){
	if((a==0)&&(b==3))
		return init[0];
	if((a==3)&&(b==0))
		return init[1];
	if((a==2)&&(b==1))
		return init[2];
	if((a==1)&&(b==2))
		return init[3];

	return (0,0);
}

function existe(a,b,c,d){
	if(existe_init(a,c).length==2)
		if(existe_init(b,d).length==2)
			return doublon(a,b);
		else
			return mismatch(a,b,d);		//on a un mismatch en second couple
	else
		if(existe_init(b,d).length==2)
			return mismatch(d,c,a);		//on a un mismatch en premier couple
		else
			return (0,0);			//on a un double mismatch
}


//......................................................................
//recherche des tetraloop destabilisantes

function tetraloop(a,b,c,d){
	if((a==0)&&(b==3)&&(c==3)&&(d==3))
	return tetra_loop[0];
	if((a==1)&&(b==3)&&(c==3)&&(d==2))
	return tetra_loop[1];
	if(a==3){
	if((b==0)&&(c==1)&&(d==2))
		return tetra_loop[2];
	if((b==1)&&(c==1)&&(d==2))
		return tetra_loop[3];
	if((b==3)&&(c==1)&&(d==2))
		return tetra_loop[4];
	if((b==3)&&(c==3)&&(d==0))
		return tetra_loop[5];
	}
	if(a==2){
	if((c==0)&&(d==0)){
	if(b==0)
		return tetra_loop[6];
	if(b==1)
		return tetra_loop[8];
	if(b==2)
		return tetra_loop[10];
	if(b==3)
		return tetra_loop[11];
	}
	if((c==2)&&(d==0)){
	if(b==0)
		return tetra_loop[7];
	if(b==1)
		return tetra_loop[9];
	if(b==3)
		return tetra_loop[12];
	}
	}
	return (0);
}

//..........................................................................................

function primer2int(st){
	var l=st.length;
	var code=new Array(l);
	for(i=0;i<l;i++)
		code[i]=char2int(st.charAt(i));
	return code;
}


function int2primer(tab){

	var l=tab.length;
	var str=new Array(l);
	for(i=0;i<l;i++)
		str[i]=int2char(tab[i]);
	return str;
	
}

function char2int(lettre){
	switch (lettre){
		case 'A' : inverse=0;break;
		case 'C' : inverse=1;break;
		case 'G' : inverse=2;break;
		case 'T' : inverse=3;break;
		default : inverse=4;break;
		}
	return inverse;
}

function int2char(num){
	
	switch (num){
                	case 0 : inverse='A';break;
                	case 1 : inverse='C';break;
                	case 2 : inverse='G';break;
                	case 3 : inverse='T';break;
                	default : inverse='.';break;                	
        	}
        return inverse;

}

//......................................................................

function simple_affiche(inter){


	var max_temp=0;
	var max_energie=0;
	var max_entro=0;


	if(inter[0].length>inter[1].length){
		var tmp=inter[0];
		inter[0]=inter[1];
		inter[1]=tmp;
	}
		
	var largeur=inter[0].length;
	var hauteur=inter[1].length;
	var matrice=new Array(hauteur);
	var score_inter=new Array(largeur+hauteur-1);
	
	for(i=0;i<hauteur;i++){
		matrice[i]=new Array(largeur);	
		for(j=0;j<hauteur;j++)
			matrice[i][j]=new Array(0,0);
	}
	
	for(i=0;i<score_inter.length;i++)
		score_inter[i]=new Array(0,0);
		
	
	//on commence par les tetras loops..
	if(inter[5]==0){	
		for(i=2;i<inter[0].length-6;i++){
			score_inter[i+5][0]=0;
			score_inter[i+5][1]=tetraloop(inter[0][i],inter[0][i+1],inter[0][i+2],inter[0][i+3]);
		}
	}
	//integrer l effet déstabilisant des bords
	
	//on recherche les énergies pour toutes les liaisons
	for(k=0;k<inter[1].length-1;k++){
		for(l=0;l<inter[0].length-1;l++){		
			matrice[k][l]=existe(inter[0][l],inter[0][l+1],inter[1][k+1],inter[1][k]);
		}
	}

	// on somme les diagonales
	for(i=0;i<score_inter.length;i++){
		if(i<inter[1].length){
			if(i<inter[0].length){
				j=i;
				while(j>=0){
					if(matrice[i-j][j].length==2){
						score_inter[i][0]+=matrice[i-j][j][0];
						score_inter[i][1]+=matrice[i-j][j][1];
					}
					j--;
				}
			}
			else {
				j=i;
				while(i-j<inter[0].length){
					if(matrice[i-j][j].length==2){
						score_inter[i][0]+=matrice[i-j][j][0];
						score_inter[i][1]+=matrice[i-j][j][1];
					}
					j--;
				}
			}
		}
		else{
			if(i<inter[0].length){
				j=inter[1].length-1;
				while(j>=0){
					if(matrice[i-j][j].length==2){
						score_inter[i][0]+=matrice[i-j][j][0];
						score_inter[i][1]+=matrice[i-j][j][1];
					}
					j--;
				}
			}
			else{
				j=inter[1].length-1;
				while((i-j)<inter[0].length){
					if(matrice[i-j][j].length==2){
						score_inter[i][0]+=matrice[i-j][j][0];
						score_inter[i][1]+=matrice[i-j][j][1];
					}
					j--;
				}
			}
		}
	}

	//on recherche le max
	var concentration_sel=inter[3];
	var concentration_amorce=inter[4];
	var l_r=inter[0].length;
	if(l_r<inter[1].length)
		l_r=inter[1].length;
	var max=0;
	var max_temp=0;
	var max2=0;
	var max_energie=0;

	for(i=0;i<score_inter.length;i++){
		
		entalpie=score_inter[i][0];
		entropie=score_inter[i][1];
		
		if((entalpie<0)&&(entropie<0)){
			temperature=entalpie*4.18/((entalpie-entropie)/310.15*4.18+8.31*Math.log(concentration_amorce/4))+0.368*(l_r-concentration_sel)*Math.log(concentration_sel)-273.15;
			if(temperature>max_temp){
				max=i+2;
				max_temp=Math.round(temperature*Math.pow(10,2))/Math.pow(10,2);
			}
		}
		if(max_energie>entalpie){
			max_energie=entalpie;
			max_entro=entropie;
			max2=i+2;
		}		
	}

if(max==0) {max=max2;}

	// *********dessin des interactions *********//

	var j=max+hauteur;

	/**************///gggttatcgtgcaaggc
	reduc = 0;
	
	if (hauteur<max) { reduc = hauteur; } else { reduc = max; }
	
	chaine1="";
	chaine2="";
	chaine3="";

	for(i=0;i<hauteur-reduc;i++) { chaine1 += "&nbsp;"; }
	for(i=0;i<largeur;i++) { chaine1 += int2char(inter[0][i]); }
	var j=max-largeur;

	for(i=0;i<max-reduc;i++) { chaine2 += "&nbsp;"; } 
	for(i=0;i<hauteur;i++) {
		if((max+i)>=hauteur) {
			if((max+i)<(hauteur+largeur)) {
				switch(inter[0][max+i-hauteur]){
					case 0 :
						if(inter[1][hauteur-i-1]==3) { chaine2 += "|"; }
						else { chaine2 += "&nbsp;"; } 
						break;
					case 1 : if(inter[1][hauteur-i-1]==2)
						chaine2 += "|";
						else
						chaine2 += "&nbsp;";break;
					case 2 : if(inter[1][hauteur-i-1]==1)
						chaine2 += "|";
						else
						chaine2 += "&nbsp;";break;
					case 3 : if(inter[1][hauteur-i-1]==0)
						chaine2 += "|";
						else
						chaine2 += "&nbsp;";break;
					default : chaine2 += "&nbsp;";break;
				}
			}
			else { chaine2 += "&nbsp;"; }
		}
		else { chaine2 += "&nbsp;"; }
	}

	for(i=0;i<max-reduc;i++) { chaine3 += "&nbsp;"; }
	for(i=0;i<hauteur;i++) { chaine3 += int2char(inter[1][hauteur-i-1]); }	

	//raccourci les chaines
	l=0;

/*	resultat1 = chaine1.match(/^&nbsp;+/gi);
	if(resultat1) { l = resultat.length; } else { l=0; }
	alert (reduc);l
  	resultat2 = chaine3.match(/^\s+/gi);
	if(resultat2) {
		if (resultat2.length<l) { l=resultat2.length; }
	}
	else { l=0; }
	
	//alert (l);
	*/
	
	picture = chaine1+"<br />"+chaine2+"<br />"+chaine3
	
	//*************//
	
	return new Array(max_entro, max_energie, max_temp, picture);


}

//......................................................................

//function apercu_simple(amorce_L, amorce_R, p, sel, amorce){

function apercu_simple(amorce_L, amorce_R) {

	//if (typeof p != 'undefined' ) p = 0;
	//if (typeof sel != 'undefined' ) sel = 1;
	//if (typeof amorce != 'undefined' ) amorce = 1e-10;
	
	// delete uncorrect caracters
	amorce_L = amorce_L.replace(/-/g, "");
	amorce_R = amorce_R.replace(/-/g, "");

	p =0;
	sel = 1;
	amorce = 0.0000000001;

	if (document.getElementById('salt_conc').value!="") { sel=document.getElementById('salt_conc').value/1000; }
	if (document.getElementById('dna_conc').value!="") { amorce=document.getElementById('dna_conc').value+"e-9";
		amorce = parseFloat(amorce); 
	}

	//var p=0,sel=1,amorce=1e-10;
	
	if(amorce_L.length==0){
		var chaine_amorce_L=amorce_R.toUpperCase();
		var chaine_amorce_R="";
	}
	else{
		var chaine_amorce_L=amorce_L.toUpperCase();
		var chaine_amorce_R=amorce_R.toUpperCase();
	}
	var pos=p;
	var concentration_amorce=amorce;
	var concentration_sel=sel;
	if(chaine_amorce_L.length>0){
		if(chaine_amorce_R.length==0){
			var gauche=primer2int(chaine_amorce_L);
			var gauche_gauche=new Array(gauche,gauche,pos,concentration_sel,concentration_amorce,0);
			Watson_crick();
			return simple_affiche(gauche_gauche);
		}
		else{
			var gauche=primer2int(chaine_amorce_L);
			var droite=primer2int(chaine_amorce_R);
			var gauche_droite=new Array(gauche,droite,pos,concentration_sel,concentration_amorce,1);
			Watson_crick();
			return simple_affiche(gauche_droite);
		}
	}

}

