<?php
  
	require '../conf/config.php';
	set_time_limit(1200);//20min
	////////////////////////////////// Connecting with DB
	if( !$conn = new mysqli($host, $user, $pswd, $db)) {
		error_log("Connection failed.\n");
		exit;
	}

	////////////////////////////////// Parameters
	(isset($_POST['prm_fa_chr']) && !empty($_POST['prm_fa_chr'])) ? $prm_chr=$_POST['prm_fa_chr']:returnError("Error");
	(isset($_POST['prm_fa_s']) && !empty($_POST['prm_fa_s'])) ? $prm_s=$_POST['prm_fa_s']:returnError("Error");
	(isset($_POST['prm_fa_e']) && !empty($_POST['prm_fa_e'])) ? $prm_e=$_POST['prm_fa_e']:returnError("Error");
	(isset($_POST['prm_fa_tgt']) && !empty($_POST['prm_fa_tgt'])) ? $prm_tgt=$_POST['prm_fa_tgt']:returnError("Error");
	(isset($_POST['prm_fa_var']) && !empty($_POST['prm_fa_var'])) ? $prm_var=$_POST['prm_fa_var']:$prm_var=".";
	(isset($_POST['prm_fa_qual'])) ? $prm_qual=$_POST['prm_fa_qual']:returnError("Error");
	(isset($_POST['prm_fa_dp'])) ? $prm_dp=$_POST['prm_fa_dp']:returnError("Error");
	(isset($_POST['prm_fa_list']) && !empty($_POST['prm_fa_list'])) ? $prm_list=$_POST['prm_fa_list'] : returnError("Error");
	(isset($_POST['prm_fa_name']) && !empty($_POST['prm_fa_name'])) ? $prm_name=$_POST['prm_fa_name'] : returnError("Error");
	(isset($_POST['prm_fa_nameS']) && !empty($_POST['prm_fa_nameS'])) ? $prm_nameS=$_POST['prm_fa_nameS'] : returnError("Error");
	(isset($_POST['prm_fa_ref']) && !empty($_POST['prm_fa_ref'])) ? $prm_ref=$_POST['prm_fa_ref'] : returnError("Error");
	(isset($_POST['prm_fa_width'])) ? $prm_width=$_POST['prm_fa_width'] : returnError("Error");
	(isset($_POST['prm_fa_avd'])) ? $prm_avd=$_POST['prm_fa_avd'] : returnError("Error");
	(isset($_POST['prm_fa_p3prm'])) ? $prm_p3prm=$_POST['prm_fa_p3prm'] : returnError("Error");
	(isset($_POST['prm_fa_avd'])) ? $prm_avd=$_POST['prm_fa_avd'] : returnError("Error");
	(isset($_POST['prm_fa_Ns'])) ? $prm_Ns=$_POST['prm_fa_Ns'] : returnError("Error");
	(isset($_POST['prm_type']) && !empty($_POST['prm_type'])) ? $prm_type=$_POST['prm_type'] : returnError("Error");
	
	$prm_chr = $conn->real_escape_string($prm_chr);
	$prm_list = $conn->real_escape_string($prm_list);
	$prm_ref = $conn->real_escape_string($prm_ref);
	
	$primer3Path_checked="";
	$primer3ThermPath_checked="";
	
	if(isset($primer3Path)){
		$primer3Path_checked=$primer3Path;
	}
	if(isset($primer3ThermPath)){
		$primer3ThermPath_checked=$primer3ThermPath;
	}

	if($prm_type != "a" && $prm_type != "b" && $prm_type != "c"){
		error_log("Invalid value: type.\n");
		exit;
	}

    if($prm_e-$prm_s>19999){  // Maximum size is 20K
		$prm_e=$prm_s+19999;
	} else if($prm_e-$prm_s < 0){
		$prm_e=$prm_s;
	}
	
	//////////////////////////processing
	if($prm_type == "a"){
		$file=$prm_chr."_".(int)$prm_s."b-".(int)$prm_e."b_".date("Y-m-d").".fasta";
		header("Content-Disposition: attachment; filename=\"".$file."\"");
		header("Content-type: application/octet-stream");
    }
	
	$seqname = array();
	$list=explode(",",$prm_list);
    $list_cp=explode(",",$prm_list);
	
	$refseq = _GETREFSEQ($prm_chr, $prm_s, $prm_e,$conn);
	$seqname = _HEADERFA($list,$prm_s,$prm_e,$prm_name,$prm_nameS,$conn,$prm_type);
	$altpos =  _VAR($list,$prm_chr,$prm_s,$prm_e,$conn,$prm_type,$seqname,$prm_dp,$prm_qual);
    $pr_refseq="";
    
	if($prm_type == "a"){//gen fasta file
		$seqname_valid = _valRefName($prm_ref,$reference);
		if($seqname_valid == 0 ){
			returnError("Invalid reference name.");
			exit;
		}
		$pr_refseq = _rpl_REF("REFERENCE",$altpos,$prm_s,$prm_e,$refseq,$list_cp);
		if ($prm_width != 0){ 
			$pr_refseq = wordwrap($pr_refseq, $prm_width, "\n", true);
		}
		echo ">REF_".$prm_ref."\n";
		echo $pr_refseq."\n";
	}elseif($prm_type == "b"){//gen seq for web-primer3 http://primer3.ut.ee/
		$range=explode("-",$prm_tgt);
		$start=0;
		$end=0;
		if($prm_var=="DEL"){
			$start=$range[0]-1;
			$end=$range[1]-1;
		}else{
			$start=$range[0];
			$end=$range[1];
		}
		$targetLen=($end-$start)+1;
		$pr_refseq = _rpl_REF("REFERENCE",$altpos,$prm_s,$prm_e+$targetLen,$refseq,$list_cp);
		$pr_refseq = str_replace("-", "", $pr_refseq);
		$res = _genPrimer3Query($start,$end,$targetLen,$pr_refseq,$prm_s,$prm_width,$altpos,$prm_chr,$prm_avd,$prm_type,$prm_Ns);
		$resArray = explode("@",$res);
		echo $resArray[0];
		exit;
	}else{
		set_time_limit(0);
		$range=explode("-",$prm_tgt);
		$start=0;
		$end=0;
		if($prm_var=="DEL"){
			$start=$range[0]-1;
			$end=$range[1]-1;
		}else{
			$start=$range[0];
			$end=$range[1];
		}
		$targetLen=($end-$start)+1;
		$name=$prm_chr."_".$range[0]."-".$range[1];
		$pr_refseq = _rpl_REF("REFERENCE",$altpos,$prm_s,$prm_e+$targetLen,$refseq,$list_cp);
		$pr_refseq = str_replace("-", "", $pr_refseq);
		$res = _genPrimer3Query($start,$end,$targetLen,$pr_refseq,$prm_s,$prm_width,$altpos,$prm_chr,$prm_avd,$prm_type,$prm_Ns);
		$query = _prepareQuery($name,$res,$prm_p3prm,$primer3ThermPath_checked);
		$p3Res = _execPrimer3($query,$primer3Path_checked);
		$primerRes = _genResult($name,$res,$prm_p3prm,$p3Res);
		echo $primerRes;
		exit;
	}
	
	$t=count($seqname);
	
	for($i=0; $i<$t; $i++){
		$sn = array_shift($seqname);
		echo ">".$sn."\n";
		
		$altseq = strtoupper($refseq);
		
		$ac = array_shift($list);
		$empty_sites = _EMPDP($ac,$prm_chr,$prm_s,$prm_e,$conn);
		$altseq = _rpl_N($empty_sites,$prm_s,$altseq);
		$altseq = _rpl_VAR($ac,$altpos,$prm_s,$prm_e,$altseq,$list_cp,$prm_qual,$prm_dp);
		if ($prm_width != 0 ){ 
			$altseq = wordwrap($altseq, $prm_width, "\n", true);
		}
		echo $altseq."\n";
	}
	
	mysqli_close($conn);
	
   //-----------------------------------------functions------------------------------------------------------------//
   ///////////// template seq
    function _rpl_REF($a,$b,$c,$d,$e,$f){
	$rtnseq = $e;
	$list = $a;
	$strbuf=array();
	$x=count($f);
	
	$f_chk=$f;
	$lenmax=array();
	
	for($i=0;$i<$x;$i++){
		$each_acces = array_shift($f_chk);
		
		for($z=$c; $z<=$d; $z++){
			
			if(array_key_exists($each_acces.":".$z, $b)){
				$ins_inf = explode(":",$b[$each_acces.":".$z]);
				if($ins_inf[0] == "i"){
					
					$reflen = strlen($ins_inf[1]);
					$altlen = strlen($ins_inf[2]);
					$len_i = $altlen - $reflen;
					$replace_pos = $z + 1 - $c;

					if(array_key_exists($replace_pos, $lenmax)){
						if($len_i > $lenmax[$replace_pos]){
							$lenmax[$replace_pos]=$len_i;
						}
					}else{
						$lenmax[$replace_pos]=$len_i;
					}
					
				} 
			}
		}
	}
	
	for($i=0;$i<$x;$i++){
		$each_acces = array_shift($f);
		
		for($z=$c; $z<=$d; $z++){
			
			if(array_key_exists($each_acces.":".$z, $b)){
				$ins_inf2 = explode(":",$b[$each_acces.":".$z]);
				if($ins_inf2[0] == "i" and $list != $each_acces ){
					
					$reflen = strlen($ins_inf2[1]);
					$altlen = strlen($ins_inf2[2]);
					$len_i = $altlen - $reflen;
					$replace_pos = $z + 1 - $c;
					$gap="";
					
					if($lenmax[$replace_pos] > $len_i){
						$len_i=$len_i+($lenmax[$replace_pos]-$len_i);
					}
					
					for($i=0; $i<$len_i; $i++){
						$gap=$gap."-";
					}
						$strbuf[$replace_pos]=$gap.":".$len_i.":".$replace_pos;
				} else if($ins_inf2[0] == "i" and $list == $each_acces ){
					//
				}
			}
		}
	}
	$pointer=0;
	ksort($strbuf);
	$ct=count($strbuf);
	for($i=0; $i<$ct; $i++){
		$str = array_shift($strbuf);
		$str_array = explode(":",$str);
		$replace_pos = $str_array[2] + $pointer;
		$rtnseq = substr_replace($rtnseq, $str_array[0], $replace_pos ,0);
		$pointer +=$str_array[1];
	}
	return $rtnseq;
   }
    
   ///////////// INS _rpl_INS($list,$b,$c,$d,$rtnseq,$f,$ql,$dp);
   function _rpl_INS($a,$b,$c,$d,$e,$f,$ql,$dp){
	$rtnseq = $e;

	$list = $a;
	$strbuf=array();
	$ins_check=array();
	$x=count($f);
	$f_chk=$f;
	$lenmax=array();
	for($i=0;$i<$x;$i++){
		$each_acces = array_shift($f_chk);
		for($z=$c; $z<=$d; $z++){
			
			if(array_key_exists($each_acces.":".$z, $b)){
				$ins_inf = explode(":",$b[$each_acces.":".$z]);
				if($ins_inf[0] == "i"){
					
					$reflen = strlen($ins_inf[1]);
					$altlen = strlen($ins_inf[2]);
					$len_i = $altlen - $reflen;
					$replace_pos = $z + 1 - $c;

					if(array_key_exists($replace_pos, $lenmax)){
						if($len_i > $lenmax[$replace_pos]){
							$lenmax[$replace_pos]=$len_i;
						}
					}else{
						$lenmax[$replace_pos]=$len_i;
					}
					
				} 
			}
		}
	}
	
	for($i=0;$i<$x;$i++){
		$each_acces = array_shift($f);
		for($z=$c; $z<=$d; $z++){
			if(array_key_exists($each_acces.":".$z, $b)){
				$ins_inf = explode(":",$b[$each_acces.":".$z]);
				if($ins_inf[0] == "i" and $list != $each_acces and ! array_key_exists($z, $ins_check)){
					
					$reflen = strlen($ins_inf[1]);
					$altlen = strlen($ins_inf[2]);
					$len_i = $altlen - $reflen;
					$replace_pos = $z + 1 - $c;
					$gap="";
					
					if($lenmax[$replace_pos] > $len_i){
						$len_i=$len_i+($lenmax[$replace_pos]-$len_i);
					}
					for($l=0; $l<$len_i; $l++){
						$gap=$gap."-";
					}
						$strbuf[$replace_pos]=$gap.":".$len_i.":".$replace_pos;
				} else if($ins_inf[0] == "i" and $list == $each_acces ){
					$ins_check[$z]=1;
					$reflen = strlen($ins_inf[1]);
					$altlen = strlen($ins_inf[2]);
					$len_i = $altlen - $reflen;
					$replace_pos = $z + 1 - $c;
					
					if($ql <= $ins_inf[3] and $dp <= $ins_inf[4]){
						$gap="";
						
						if($lenmax[$replace_pos] > $len_i){

							for($m=0; $m<$lenmax[$replace_pos]-$len_i; $m++){
								$gap=$gap."-";
							}
							$len_org=$len_i;
							$len_i=$len_i+($lenmax[$replace_pos]-$len_i);
							
							$strbuf[$replace_pos]=substr($ins_inf[2], 1, $len_org).$gap.":".$len_i.":".$replace_pos;
							
						}else{
							$strbuf[$replace_pos]=substr($ins_inf[2], 1, $len_i).":".$len_i.":".$replace_pos;
						}
						
					}else{
						$gap="";
						
						if($lenmax[$replace_pos] > $len_i){
							$len_i=$len_i+($lenmax[$replace_pos]-$len_i);
						}
						
						for($n=0; $n<$len_i; $n++){
							$gap=$gap."N";
						}
						$strbuf[$replace_pos]=$gap.":".$len_i.":".$replace_pos;
					}
					
				}
			}
		}
	}
	$pointer=0;
	ksort($strbuf);
	$ct=count($strbuf);
	for($o=0; $o<$ct; $o++){
		$str = array_shift($strbuf);
		$str_array = explode(":",$str);
		$replace_pos = $str_array[2] + $pointer;
		$rtnseq = substr_replace($rtnseq, $str_array[0], $replace_pos ,0);
		$pointer +=$str_array[1];

	}
	return $rtnseq;
   }
   
   ///////////// SNP  _rpl_VAR($ac,$altpos,$prm_s,$prm_e,$altseq,$list_cp,$prm_qual,$prm_dp);
   function _rpl_VAR($a,$b,$c,$d,$e,$f,$ql,$dp){
	$rtnseq = $e;
		$list = $a;
		$pointer=0;
		$strbuf=array();
		for($y=$c; $y<=$d; $y++){
			if(array_key_exists($list.":".$y, $b)){
				$var_inf = explode(":",$b[$list.":".$y]);
				
				if($var_inf[0] == "s"){
					
					if($ql <= $var_inf[3] and $dp <= $var_inf[4]){
						$replace_pos = $y - $c + $pointer;
						$rtnseq = substr_replace($rtnseq, $var_inf[2], $replace_pos, 1 );

					}else{
						$replace_pos = $y - $c + $pointer;
						$rtnseq = substr_replace($rtnseq, "N", $replace_pos, 1 );

					}
					
				} else if ($var_inf[0] == "i"){
					
					$reflen = strlen($var_inf[1]);
					$altlen = strlen($var_inf[2]);
					$len_i = $altlen - $reflen;
					$replace_pos = $y + 1 - $c + $pointer;
					
					if($ql <= $var_inf[3] and $dp <= $var_inf[4]){
						
						$strbuf[$replace_pos]=substr($var_inf[2], 1, $len_i).":".$len_i.":".$replace_pos;
						
					}else{
						$gap="";
						for($i=0; $i<$len_i; $i++){
							$gap=$gap."N";
						}
						$strbuf[$replace_pos]=$gap.":".$len_i.":".$replace_pos;
						
					}
					
				} else if ($var_inf[0] == "d"){
					
					$reflen = strlen($var_inf[1]);
					$altlen = strlen($var_inf[2]);
					$len_d = $reflen - $altlen;
					$replace_pos = $y - $c + $pointer;
					
					if($ql <= $var_inf[3] and $dp <= $var_inf[4]){
						for($i=0; $i<$len_d; $i++){
							$rtnseq = substr_replace($rtnseq, "-", $replace_pos, 1 );
							$replace_pos++;
						}
					}else{
						for($i=0; $i<$len_d; $i++){
							$rtnseq = substr_replace($rtnseq, "N", $replace_pos, 1 );

							$replace_pos++;
						}
					}
				}
				
			}
		}
		
	 $pr_rtnseq = _rpl_INS($list,$b,$c,$d,$rtnseq,$f,$ql,$dp);
	
	return $pr_rtnseq;
   }
   
   /////////////"N" postion _rpl_N($empty_sites,$prm_s,$altseq);
   function _rpl_N($a,$b,$c){
	$rtnseq = $c;
	$x=count($a);
	for($i=0;$i<$x;$i++){
		$Npos=array_shift($a);
		$replace_pos = $Npos - $b;
		$rtnseq = substr_replace($rtnseq, "N", $replace_pos, 1 );
	}
	return $rtnseq;
   }
   
   /////////////variants  _VAR($list,$prm_chr,$prm_s,$prm_e);
   function _VAR($list,$b,$c,$d,$conn,$mode,$seqname,$dp,$qual){
		/*
		This function gets ARRAY has variant position about each accession.
		*/
		$var_array = array();
		$x=count($list);
		if($mode == "a"){
			$dp=0;
			$qual=0;
		}
		$stmt = $conn->stmt_init();
		for($i=0;$i<$x;$i++){
			$p=array_shift($list);
			$query = "SELECT pos,variant,ref,substring_index(alt, ',', 1),qual,dp FROM ".$p."_variant WHERE chr= ? and pos >= ? and pos <= ? and dp >= ? and qual >= ? ";
			$stmt->prepare($query);
			$stmt->bind_param("siiii", $b, $c, $d, $dp, $qual); 
			$stmt->execute();
			$stmt->store_result();
			$stmt->bind_result($row0,$row1,$row2,$row3,$row4,$row5);
			while ($stmt->fetch()) {
				if($mode == "a"){
					$var_array[$p.":".$row0]=$row1.":".strtoupper($row2).":".strtoupper($row3).":".$row4.":".$row5;
				}else{
					if(array_key_exists($row0, $var_array)){
						$var_array[$row0]=$var_array[$row0].",".$seqname[$p];
					}else{
						$var_array[$row0]=$row0."\t".strtoupper($row2)."/".strtoupper($row3)."\t".$row1."\t".$seqname[$p];
					}
				}
			}
			$stmt->free_result();
		}
		$stmt->close();
		return $var_array;
  }
   
   /////////////ummapped postion  _EMPDP($ac,$prm_chr,$prm_s,$prm_e);
   function _EMPDP($a, $b, $c, $d,$conn){
		$null=array();
		$stmt = $conn->stmt_init();
		$param=$b."_b";
		$query="SELECT pos FROM ".$a."_accession WHERE ".$param." is null and pos >= ? and pos <= ? ";
		$stmt->prepare($query);
		$stmt->bind_param("ii",  $c, $d); 
		$stmt->execute();
		$stmt->store_result();
		$stmt->bind_result($row0);
		while ($stmt->fetch()) {
			$null[]=$row0;
		}
		$stmt->free_result();
		$stmt->close();
		return $null;
  }

   /////////////ref-seq _GETREFSEQ($prm_chr, $prm_s, $prm_e);
   function _GETREFSEQ($a,$b,$c,$conn){
		$refseq="";
		$query = "SELECT ".$a."_f FROM sys_fasta WHERE pos >= ? and pos <= ?";
		$stmt = $conn->stmt_init();
		$stmt->prepare($query);
		$stmt->bind_param("ii", $b, $c); 
		$stmt->execute();
		$stmt->store_result();
		$stmt->bind_result($row0);
		while ($stmt->fetch()) {
			$refseq = $refseq.$row0;
		}
		$stmt->free_result();
		$stmt->close();
		return $refseq;
   }
   
   /////////////seq_name _rpl_REF("REFERENCE",$altpos,$prm_s,$prm_e,$refseq,$list_cp)
  function _HEADERFA($a,$b,$c,$d,$e,$conn,$mode){
	$str=array();
	if ($d == "id" ) {
        $d="accession_id";
    } else if ( $d == "name"  ) {
        $d="accession_name";
    }
	if ($e == "subvariety" ) {
        $e="sub_variety";
    } 
	$d = $conn->real_escape_string($d);
	$e = $conn->real_escape_string($e);
	$query = "SELECT ".$d.", ".$e." FROM sys_accession WHERE accession_db= ? ";
	$stmt = $conn->stmt_init();
	$stmt->prepare($query);
	
    for($i=0;$i<count($a);$i++){
		$stmt->bind_param("s", $a[$i]); 
		$stmt->execute();
		$stmt->store_result();
		$stmt->bind_result($row0,$row1);
		while ($stmt->fetch()) {
			if($mode == "a"){
				$str[$i] = $row0."_".$row1;
			}else{
				$str[$a[$i]]=$row0;
			}
		}
		$stmt->free_result();
    }
	$stmt->close();
    return $str;
  }
  
  function _genPrimer3Query($range0,$range1,$targetLen,$pr_refseq,$prm_s,$prm_width,$altpos,$prm_chr,$prm_avd,$prm_type,$prm_Ns){
		/* 
		This function generates template sequence for primer3web or query for primer3 on your server.
		--template sequence ($prm_type==b)=> the function generates HTML included the sequence for primer3Web.
		--run primer3 on the server ($prm_type==c)=> the function generates template sequence for primer3 and target position. $res = SEQ|target|targetLength|$prm_avd
		*/
		$pointer=0;
		$numarray = count($altpos);
		
		if($prm_Ns){
			if($numarray > 1){
				$seqarray = str_split($pr_refseq,1);
				$numNs=0;
				for ($i=0; $i<$numarray; $i++){
				$key = key($altpos);
				$varOnFlk=explode("\t", $altpos[$key]);
				if($key != $range0){
					$varOnFlk=explode("\t", $altpos[$key]);
					if($varOnFlk[2]=="d"){
						$targetSeq=explode("/", $varOnFlk[1]);
						$numNs = abs(strlen($targetSeq[0])-strlen($targetSeq[1]));
						for($a=0; $a<$numNs; $a++){
							$seqarray[$key-$prm_s+$a]="N";
						}
					}elseif($varOnFlk[2]=="i"){
						$rplNs="";
						$targetSeq=explode("/", $varOnFlk[1]);
						$numNs = abs(strlen($targetSeq[1])-strlen($targetSeq[0]));
						if($key < $range0){
							$pointer = $pointer+($numNs);
						}
						$seqarray[$key-$prm_s]=$seqarray[$key-$prm_s].str_repeat("N", $numNs);
						//}
					}else{
						$seqarray[$key-$prm_s]="N";
					}
				}
				next($altpos);
				}
				reset($altpos);
				$pr_refseq = implode("",$seqarray);
			}
		}
		
		$fivePrm = substr($pr_refseq, 0, ($range0-$prm_s+$pointer));
		$tgt = substr($pr_refseq, ($range0-$prm_s+$pointer), $targetLen);
		$threePrm = substr($pr_refseq, ($range0-$prm_s+$targetLen+$pointer));

		$header="<div style=\"margin-left:75px;\">TARGET: ".$prm_chr.":".$range0."-".$range1."</div>";
		$tablehead="<table class=\"fontCourierNew\" width=\"585px\" cellspacing=\"0\" border=\"1\" style=\"margin-left:60px;\" ><tr><td width=\"82%\">";
		$tabletail="</td></tr></table>";
		
		if($prm_avd){
			$fivePrmLeft = substr($fivePrm, 0, strlen($fivePrm)-$prm_avd);
			$fivePrmRight = substr($fivePrm, strlen($fivePrm)-$prm_avd);
			$threePrmLeft = substr($threePrm,  0, $prm_avd);
			$threePrmRight = substr($threePrm, $prm_avd);
			
			if($prm_type=="c"){// for runPrimer3()
				$res = $fivePrmLeft.$fivePrmRight.$tgt.$threePrmLeft.$threePrmRight;
				$res = $res."|".($range0-$prm_s+1+$pointer)."|".$targetLen."|".$prm_avd;
				return $res;
			}
			$res = $fivePrmLeft.";".$fivePrmRight.":[".$tgt."];".$threePrmLeft.":".$threePrmRight;
			$res = wordwrap($res, $prm_width, "<br>", true);
			$res = preg_replace("/\];/", "]</font>;", $res);
			$res = preg_replace("/:\[/", ":<font color='#ff0000'>[", $res);
			$res = preg_replace("/;/", "<font color='#0000ff'>;", $res);
			$res = preg_replace("/:/", ":</font>", $res);
			$res = preg_replace("/;/", "&lt;", $res);
			$res = preg_replace("/:/", "&gt;", $res);
			$res = preg_replace("/N/", "<font color='#ffa500'>N</font>", $res);
			$res=$header.$tablehead.$res.$tabletail."<br>";
		}else{
			$res = $fivePrm."[".$tgt."]".$threePrm;
			
			if($prm_type=="c"){// for runPrimer3()
				$res = $fivePrm.$tgt.$threePrm;
				$res = $res."|".($range0-$prm_s+1+$pointer)."|".$targetLen."|".$prm_avd;
				return $res;
			} 
			$res = wordwrap($res, $prm_width, "<br>", true);
			$res = preg_replace("/\]/", "]</font>", $res);
			$res = preg_replace("/\[/", "<font color='#ff0000'>[", $res);
			$res = preg_replace("/;/", "&lt;", $res);
			$res = preg_replace("/:/", "&gt;", $res);
			$res = preg_replace("/N/", "<font color='#ffa500'>N</font>", $res);
			$res = $header.$tablehead.$res.$tabletail."<br>";
		}
		$res=$res."<div style=\"margin-left:75px;\">Primer3Web: <a href=\"http://primer3.ut.ee/\" target=\"_blank\">http://primer3.ut.ee/</a><br><br>";
		//$numarray = count($altpos);
		if($numarray > 1){
			$res = $res."<font color=\"#ffa500\">Caution!</font> Flanking region has ".($numarray-1)." variant(s).<br>";
			if($numarray > 10){
				$res=$res."Only 10 variants are displayed.<br></div>";
				$numarray = 10;
			}else{
				$res=$res."</div>";
			}
			$res=$res."<table class=\"fontCourierNew\" width=\"585px\" cellspacing=\"0\" border=\"1\" style=\"margin-left:60px;\" >
			<tr bgcolor=\"#CCCCCC\"><td width=\"55%\">Accession</td><td width=\"15%\">Position</td><td width=\"30%\">REE/ALT</td>";
			
			for ($i=0; $i<$numarray; $i++){
				$key = key($altpos);
				$varOnFlk=explode("\t", $altpos[$key]);
				if($varOnFlk[2]=="d"){
					$key--;
				}
				if($key != $range0){
					$res=$res."<tr><td>".wordwrap($varOnFlk[3],"40","<br>",true)."</td><td>".$varOnFlk[0]."</td><td>".wordwrap($varOnFlk[1],"20","<br>",true)."</td></tr>";
				}
				next($altpos);
			}
			$res=$res."</table><br><br>";
		}
		return $res;
  }
  
  
  function _prepareQuery($name,$res,$prm_p3prm,$primer3ThermPath){
	$param = explode(",", $prm_p3prm);
	$resArray = explode("|", $res);
	
	$targetStart=$resArray[1]-1;
	$exStart=$targetStart-$resArray[3];
	$exEnd=$targetStart+$resArray[2];
	
	$query = <<< EOT
SEQUENCE_ID={$name}
SEQUENCE_TEMPLATE={$resArray[0]}
SEQUENCE_TARGET={$targetStart},{$resArray[2]}
SEQUENCE_EXCLUDED_REGION={$exStart},{$resArray[3]} {$exEnd},{$resArray[3]}
PRIMER_TASK=pick_detection_primers
PRIMER_PICK_LEFT_PRIMER=1
PRIMER_PICK_INTERNAL_OLIGO=0
PRIMER_PICK_RIGHT_PRIMER=1
PRIMER_OPT_SIZE={$param[2]}
PRIMER_MAX_SIZE={$param[3]}
PRIMER_MIN_SIZE={$param[4]}
PRIMER_OPT_TM={$param[5]}
PRIMER_MAX_TM={$param[6]}
PRIMER_MIN_TM={$param[7]}
PRIMER_MAX_DIFF_TM={$param[8]}
PRIMER_MAX_NS_ACCEPTED=1
PRIMER_PRODUCT_SIZE_RANGE={$param[0]}-{$param[1]}
PRIMER_THERMODYNAMIC_PARAMETERS_PATH={$primer3ThermPath}
PRIMER_EXPLAIN_FLAG=1
PRIMER_MAX_NS_ACCEPTED=0
PRIMER_LOWERCASE_MASKING={$param[9]}
=
EOT;
	return $query;
  }
  
  function _execPrimer3($query,$primer3Path){
	
	if (!file_exists($primer3Path) || preg_match("/^\S*primer3_core$/", $primer3Path) != 1) {
		echo "Error: Primer3 was not found.";
		exit;
	} 
	
	$fp = tmpfile();
	fwrite($fp, $query);
	rewind($fp);
	$tmparray = stream_get_meta_data($fp);
	
	$resArray=Array();
	exec(sprintf("%s %s < %s", $primer3Path, "-format_output", $tmparray["uri"]), $resArray, $return);
	$primer = implode("\n", $resArray);
	
	fclose($fp);
	
	if($return == 1){
		echo "Error: Can not execute Primer3.";
		exit;
	}
		return $primer;
  } 
  
    function _genResult($name,$res,$prm_p3prm,$p3Res){
		$param = explode(",", $prm_p3prm);
		$resArray = explode("|", $res);
		//error_log($res);
		$targetStart=$resArray[1]-1;
		$exStart=$targetStart-$resArray[3];
		$exEnd=$targetStart+$resArray[2];
		$pointer=0;
		
		$printseq="";
		$printseq = wordwrap($resArray[0], 80, "<br>", true);
		
		if($resArray[3] != 0){
			$printseq = substr_replace($printseq,"<font color='#0000ff'>",$exStart+$pointer+(((int)($exStart/80))*4),0);
			$pointer = $pointer+22;
			$printseq = substr_replace($printseq,"</font>",$exStart+$resArray[3]+$pointer+(((int)(($exStart+$resArray[3])/80))*4),0);
			$pointer = $pointer+7;
		}
		
		$printseq = substr_replace($printseq,"<font color='#ff0000'>",$targetStart+$pointer+(((int)($targetStart/80))*4),0);
		$pointer = $pointer+22;
		$printseq = substr_replace($printseq,"</font>",$targetStart+$resArray[2]+$pointer+(((int)(($targetStart+$resArray[2])/80))*4),0);
		$pointer = $pointer+7;
		
		if($resArray[3] != 0){
			$printseq = substr_replace($printseq,"<font color='#0000ff'>",$exEnd+$pointer+(((int)($exEnd/80))*4),0);
			$pointer = $pointer+22;
			$printseq = substr_replace($printseq,"</font>",$exEnd+$resArray[3]+$pointer+(((int)(($exEnd+$resArray[3])/80))*4),0);
			$pointer = $pointer+7;
		}
		$printseq = preg_replace("/N/", "<font color='#ffa500'>N</font>", $printseq);
		
	$leftArray = Array();
	$rightArray = Array();
	$p3resArray = Array();
	$p3resArray = explode("\n", $p3Res);
	
	$pattern_done = "/NO PRIMERS FOUND/";
	$pattern_prmL = "/.*LEFT PRIMER\s+(\d+)\s+(\d+).*\s+(\w+)$/";
	$pattern_prmR = "/.*RIGHT PRIMER\s+(\d+)\s+(\d+).*\s+(\w+)$/";
	
	$t=count($p3resArray);
	for($i=0; $i<$t; $i++){
		if(preg_match($pattern_done, $p3resArray[$i], $match_done) != 0){
			$i=$t-1;
		}
		if(preg_match($pattern_prmL, $p3resArray[$i], $match_done) != 0){
			$leftArray[$i]=$match_done[1].":".$match_done[2].":".$match_done[3];
		}
		if(preg_match($pattern_prmR, $p3resArray[$i], $match_done) != 0){
			$rightArray[$i]=$match_done[1].":".$match_done[2].":".$match_done[3];
		}
	}
		$lprmPos = implode("-", $leftArray);
		$rprmPos = implode("-", $rightArray);
		
		$primer=$p3Res."---SPLIT---".$printseq."--split--".$lprmPos."--split--".$rprmPos;
		return $primer;
	}
	
	function _valRefName($prm_ref,$reference){
		$ret=0;
		if($prm_ref==$reference){$ret=1;}
		echo $prm_ref.":".$reference;
		return $ret;
	}
  
	function returnError($str){
		echo $str;
	}

?>