<?php
/*
* fasta.php
* http://tasuke.dna.affrc.go.jp/
*
* Author: Ryutaro Itoh
*
* Copyright (c) 2013 National Institute of Agrobiological Sciences   
*
*/

set_time_limit(1200);

//From http request or command line
if (!isset($_SERVER["HTTP_HOST"])) {
    parse_str($argv[1], $_POST);
    foreach($_POST as $key => $val){
        $_POST[$key] = rtrim($val);
    }
    chdir($_POST['path']);
    set_time_limit(0);
}

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

$redis;
if($useRedis === "enable"){
    $str = "";
    if($redis = new Redis()) {
        if(!$connRedis = $redis -> connect($redisHost,$redisPort)){
            error_log("Connection failed.\n");
            exit;
        }
        if(!$redis->select($redisDBName)){
            error_log("Database '".$redisDBName."' was not found.\n");
            exit;
        }
    }else{
        error_log("Can not use the PHP-Redis.\n");
        $useRedis = "disable";
    }
}

////////////////////////////////// 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_flk']) && !empty($_POST['prm_fa_flk'])) ? $prm_fa_flk=$_POST['prm_fa_flk']: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_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_fa_DN'])) ? $prm_DN=$_POST['prm_fa_DN'] : returnError("Error");
(isset($_POST['prm_fa_DN'])) ? $prm_DN=$_POST['prm_fa_DN'] : $prm_DN=0;
//(isset($_POST['prm_fa_DNnum'])) ? $prm_DNnum=$_POST['prm_fa_DNnum'] : returnError("Error");
(isset($_POST['prm_fa_DNnum'])) ? $prm_DNnum=$_POST['prm_fa_DNnum'] : $prm_DNnum=0;
(isset($_POST['prm_type']) && !empty($_POST['prm_type'])) ? $prm_type=$_POST['prm_type'] : returnError("Error");
//(isset($_POST['prm_epcrprms'])) ? $prm_epcrprms=$_POST['prm_epcrprms'] : returnError("Error");
(isset($_POST['prm_epcrprms'])) ? $prm_epcrprms=$_POST['prm_epcrprms'] : $prm_epcrprms="";
//(isset($_POST['pid'])) ? $pid=$_POST['pid'] : returnError("Error");
(isset($_POST['pid'])) ? $pid=$_POST['pid'] : $pid=0;
$prm_phpflg = (int) $_POST['prm_phpflg'];
//(isset($_POST['prm_numthread'])) ? $prm_numthread=$_POST['prm_numthread'] : returnError("Error");
(isset($_POST['prm_numthread'])) ? $prm_numthread=$_POST['prm_numthread'] : $prm_numthread=1;
(isset($_POST['prm_fa_rep_n'])) ? $prm_rep_n = (int) $_POST['prm_fa_rep_n'] : $prm_rep_n = 1;
(isset($_POST['prm_fa_use_amb_base'])) ? $prm_fa_use_amb_base = (int) $_POST['prm_fa_use_amb_base'] : $prm_fa_use_amb_base = 0;

if(!_validate_chrs($conn,$prm_chr)){exit;}
$primer3Path_checked="";
$primer3ThermPath_checked="";
if(isset($primer3Path)){
    $primer3Path_checked=$primer3Path;
}
if(isset($primer3ThermPath)){
    $primer3ThermPath_checked=$primer3ThermPath;
}

if (isset($_SERVER["HTTP_HOST"])) {
    if($prm_e-$prm_s>200000){  // Maximum size is 200K
    //if($prm_e-$prm_s>19999){  // Maximum size is 20K
        $prm_e=$prm_s+199999;
        //$prm_e=$prm_s+19999;
    } else if($prm_e-$prm_s < 0){
        $prm_e=$prm_s;
    }
}

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

///Data Validating///
if ( $prm_type === "a") {   ///for ExportFasta, PhylogeneticTree
	$prm_DNnum=0;
	$prm_DN=0;
	if (!(ctype_digit($prm_tgt)) || !(is_numeric($prm_s)) || !(is_numeric($prm_e)) || !(is_numeric($prm_qual)) || !(is_numeric($prm_dp)) || !(is_numeric($prm_width)) || !(is_numeric($prm_avd)) || !(is_numeric($prm_Ns)) || !(is_numeric($prm_DN)) || !(is_numeric($prm_DNnum))) {
                 $errmsg = "<div align=\"center\"><font color=\"red\" style=\"font-size:18px;\">Invalid Value!!</font></div>";
                  echo $errmsg;
                  exit;
        }
//	_pregMatch($prm_fa_flk);
	_pregMatch($prm_list);
	_pregMatch($prm_name);
	_pregMatch($prm_nameS);
	_pregMatch($prm_var);
	_pregMatch($prm_p3prm);
	_pregMatch($prm_epcrprms);
	if(!_validate_chrs($conn,$prm_chr)){_stopError("||Invalid value");}
	//if($prm_ref != $reference && $prm_ref != "Reference"){_stopError("||Invalid value");}
	if($prm_ref != $reference){_stopError("||Invalid value");}
} else if ($prm_type === "b") { ///for Exporting sequence
            $prm_DNnum=0;
            $prm_DN=0;
            list($tgt,$tgte) = explode('-',$prm_tgt);
//	    list($tgt,$tgte) = split('-',$prm_tgt);
	    if (!(ctype_digit($tgt)) || !(ctype_digit($tgte)) || !(is_numeric($prm_s)) || !(is_numeric($prm_e)) || !(is_numeric($prm_qual)) || !(is_numeric($prm_dp)) || !(is_numeric($prm_width)) || !(is_numeric($prm_avd)) || !(is_numeric($prm_Ns)) || !(is_numeric($prm_DN)) || !(is_numeric($prm_DNnum)) || !(is_numeric($pid))) {
                 $errmsg = "<div align=\"center\"><font color=\"red\" style=\"font-size:18px;\">Invalid Value!!</font></div>";
                  echo $errmsg;
                  exit;
	}
	if(!_validate_chrs($conn,$prm_chr)){_stopError("||Invalid value");}
	_pregMatch($prm_name);
        _pregMatch($prm_nameS);
	if($prm_ref !== "REFERENCE"){_stopError("||Invalid value");}
	_pregMatch($prm_fa_p3prm);
	_pregMatch($prm_epcrprms);
	_pregMatch($prm_list);
	_pregMatch($prm_var);
} else if ($prm_type === "c") { ///Primer3
        list($tgt,$tgte) = explode('-',$prm_tgt);
//	list($tgt,$tgte) = split('-',$prm_tgt);
	if(!_validate_chrs($conn,$prm_chr)){_stopError("||Invalid value");}
	if (!(ctype_digit($tgt)) || !(ctype_digit($tgte)) || !(is_numeric($prm_s)) || !(is_numeric($prm_e)) || !(is_numeric($prm_qual)) || !(is_numeric($prm_dp)) || !(is_numeric($prm_width)) || !(is_numeric($prm_avd)) || !(is_numeric($prm_Ns)) || !(is_numeric($prm_DN)) || !(is_numeric($prm_DNnum)) ) {
                 $errmsg = "<div align=\"center\"><font color=\"red\" style=\"font-size:18px;\">Invalid Value!!</font></div>";
                  echo $errmsg;
                  exit;
        }
	_pregMatch($prm_name);
        _pregMatch($prm_nameS);
	_pregMatch($prm_list);
        if($prm_ref != "REFERENCE"){_stopError("||Invalid value");}
	_pregMatch($prm_var);
	_validate_p3prm($prm_p3prm);
	_validate_p3prm($prm_epcrprms);
}
//////////////////////////processing
$seqname = array();
$refseq = "";
$list=explode(",",$prm_list);
if(!_validate_each_acc($list)){
    error_log("Invalid accession list.\n");
    exit;
}

$list_cp=explode(",",$prm_list);
if($useRedis === "enable"){
    $refseq = _getRefseqRedis($prm_chr, $prm_s, $prm_e, $connRedis);
}else{
    $refseq = _GETREFSEQ($prm_chr, $prm_s, $prm_e, $conn); 
}

$seqname = _HEADERFA($list,$prm_s,$prm_e,$prm_name,$prm_nameS,$conn,$prm_type);
if(count($seqname) == 0) {
    error_log("Contains accession not in the order list.");
    exit;
}
$altpos =  _VAR($list,$prm_chr,$prm_s,$prm_e,$conn,$prm_type,$seqname,$prm_dp,$prm_qual);
$num = ceil(count($seqname)/$prm_numthread);
$part_seq = array_slice($seqname,$num*$pid,$num);
$seqname = $part_seq;
$part_list = array_slice($list,$num*$pid,$num);
$list = $part_list;

//error_log("Count(". $pid. "):". count($seqname));

$pr_refseq="";
if($prm_type === "a"){//gen fasta file
    if ($pid == 0) {
        $seqname_valid = _valRefName($prm_ref,$reference);
        if($seqname_valid == 0 && isset($_SERVER["HTTP_HOST"])){
            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,$prm_DN,$prm_list,$prm_tgt);
    $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,$prm_DN,$prm_DNnum,$prm_list,$prm_e,$prm_tgt);
    $query = _prepareQuery($name,$res,$prm_p3prm,$primer3ThermPath_checked);
    $epcrparam = explode(",", $prm_epcrprms);
    list($MFERes,$p3Res) = _execPrimer3($query,$epcrparam,$primer3Path,$prm_chr);
    $primerRes = _genResult($name,$res,$prm_p3prm,$p3Res);
    if($epcrparam[0] == 1) {
        $primerRes = $primerRes."---MFESPLIT---".$MFERes;
    }
    echo $primerRes;
    exit;
}

$t = count($seqname);
for($i=0; $i<$t; $i++){
    if ($prm_phpflg == 1) {
	$sn = $list[$i];
//        $sn = array_shift($list);
	$ac = $sn;
    } else {
	$sn = $seqname[$i];
	$ac = $list[$i];
//        $sn = array_shift($seqname);
//        $ac = array_shift($list);
    }
//file_put_contents("/tmp/fasta_multi_php_post".$pid, ">".$sn."\n", FILE_APPEND);
    echo ">".$sn."\n";
    $altseq = strtoupper($refseq);
    $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, $prm_rep_n);
    if ($prm_width != 0 ){ 
        $altseq = wordwrap($altseq, $prm_width, "\n", true);
    }
//file_put_contents("/tmp/fasta_multi_php_post".$pid, $altseq."\n", FILE_APPEND);
    echo $altseq."\n";
}
//mysqli_refresh($conn, MYSQLI_REFRESH_TABLES);
$conn->close();

//-----------------------------------------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();

    foreach($b as $key => $var) {
		$keys = explode(":",$key);
		if(count($keys)<2) continue;

		$ins_inf = explode(":",$var);
		$arr_ins_inf = explode(",", $ins_inf[2]);
		$ins_inf[2] = $arr_ins_inf[0];	// ex. "A,GTC" => "A"
                $z = $keys[1];
                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;
                    }
                } 
    }
    foreach($b as $key => $var) {
		$keys = explode(":",$key);
		if(count($keys)<2) continue;

                $ins_inf2 = explode(":", $var);
                $arr_ins_inf2 = explode(",", $ins_inf2[2]);
                $ins_inf2[2] = $arr_ins_inf2[0];
                $each_acces = $keys[0];
                $z = $keys[1];
                if($ins_inf2[0] === "i" && $list !== $each_acces ){
                    $reflen = strlen($ins_inf2[1]);
                    $altlen = strlen($ins_inf2[2]);
                    $len_i = $altlen - $reflen;
                    $replace_pos = $z + 1 - $c;
                    if($lenmax[$replace_pos] > $len_i){
//                        $len_i=$len_i+($lenmax[$replace_pos]-$len_i);
                        $len_i = $lenmax[$replace_pos];
                    }
                    $gap = str_repeat("-", $len_i);
                    $strbuf[$replace_pos]=$gap.":".$len_i.":".$replace_pos;
                } else if($ins_inf2[0] == "i" && $list == $each_acces ){
                    //pass
                }
    }
    $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,$rep_n);
function _rpl_INS($a,$b,$c,$d,$e,$f,$ql,$dp,$rep_n){
    $rtnseq = $e;
    $list = $a;
    $strbuf=array();
    $ins_check=array();
    $x=count($f);
    $f_chk=$f;
    $lenmax=array();
    foreach($b as $key => $var) {
    	//$ins_inf = explode(":",$b[$each_acces.":".$z]);
        $ins_inf = explode(":",$var);
	$keys = explode(":",$key);
	$z = $keys[1];
        if($ins_inf[0] === "i"){
		$arr_ins_inf = explode(",", $ins_inf[2]);
		$ins_inf[2] = $arr_ins_inf[0];	// ex. "A,GTC" => "A"

        	$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;
                }
	} 
    }
	foreach($b as $key => $var) {
                $ins_inf = explode(":",$var);
        	$keys = explode(":",$key);
		$each_acces = $keys[0];
        	$z = $keys[1];

                if($ins_inf[0] === "i") {
                  $arr_ins_inf = explode(",", $ins_inf[2]);
                  $ins_inf[2] = $arr_ins_inf[0];  // ex. "A,GTC" => "A"

                  if($list !== $each_acces && ! 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 = $lenmax[$replace_pos];
                    }
		    $gap = str_repeat("-",$len_i);
                    $strbuf[$replace_pos]=$gap.":".$len_i.":".$replace_pos;
                  } else if($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] && $dp <= $ins_inf[4]){
                        $gap="";
                        if($lenmax[$replace_pos] > $len_i){
			    $gap = str_repeat("-", $lenmax[$replace_pos]-$len_i);
                            $len_org=$len_i;
                            $len_i = $lenmax[$replace_pos];
                            $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{
//error_log("Filter INS: $list, $rep_n");
                        if($lenmax[$replace_pos] > $len_i){
                            $len_i = $lenmax[$replace_pos];
                        }
			$gap = "";
			if($rep_n === 1) {
				$gap = str_repeat("N", $len_i);
			} else {
				$gap = str_repeat("-", $len_i);
			}
                        $strbuf[$replace_pos] = $gap. ":". $len_i. ":". $replace_pos;
                    }
                  }
                }
    }

    $pointer=0;
    ksort($strbuf);
    $ct=count($strbuf);
    foreach($strbuf as $key => $val) {
        $str = $strbuf[$key];
        $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,$prm_rep_n);
// The length of $altseq does not change within this function.
function _rpl_VAR($a,$b,$c,$d,$e,$f,$ql,$dp,$rep_n){
    global $prm_fa_use_amb_base;

    $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] && $dp <= $var_inf[4]){
                    $replace_pos = $y - $c + $pointer;
                    $alt_base = $var_inf[2];
                    $gt = $var_inf[5];
                    if($prm_fa_use_amb_base !== 0 && ($gt === "0/1" || $gt === "1/2")) {
			if($gt === "0/1") {
                            // Use only 1-char each for REF and ALT
                            $alt_base = convBases2IupacFromArr(array($var_inf[1][0], $alt_base[0]));
                        } else {
                            // GT:1/2
                            $base_arr = explode(",", $alt_base);
//error_log("Test:". $alt_base. " => ". implode("|", $base_arr));
                            if(count($base_arr) > 1 && strlen($base_arr[0]) === strlen($base_arr[1])) {
                                // nonRef SNP-SNP hetero
                                $alt_base = convBases2IupacFromArr(array($base_arr[0][0], $base_arr[1][0]));
                            } else {
								$arr_alt_base = explode(",", $alt_base);
                                $alt_base = $arr_alt_base[0];
                            }
                        }
                    } else {
                        $arr_alt_base = explode(",", $alt_base);
                        $alt_base = $arr_alt_base[0];
                    }
                    $rtnseq = substr_replace($rtnseq, $alt_base, $replace_pos, strlen($alt_base));	// Even SNPs may have a length of 2 or more due to VCF notation
//                    $rtnseq = substr_replace($rtnseq, $var_inf[2], $replace_pos, 1 );
                }else{
                    if($rep_n === 1) {
                        $replace_pos = $y - $c + $pointer;
                        $rtnseq = substr_replace($rtnseq, "N", $replace_pos, 1 );
                    }
                }
            } else if ($var_inf[0] === "i"){
		// Insertions are processed in _rpl_INS().
/*
                $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] && $dp <= $var_inf[4]){
                    $strbuf[$replace_pos]=substr($var_inf[2], 1, $len_i).":".$len_i.":".$replace_pos;
                }else{
                    $gap = str_repeat("N", $len_i);
                    $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] && $dp <= $var_inf[4]){
                    for($i=0; $i<$len_d; $i++){
                        $rtnseq = substr_replace($rtnseq, "-", $replace_pos, 1 );
                        $replace_pos++;
                    }
                }else{
//error_log("Filter DEL: $a, $rep_n");
                    if($rep_n === 1) {
                        for($i=0; $i<$len_d; $i++){
                            $rtnseq = substr_replace($rtnseq, "N", $replace_pos, 1 );
                            $replace_pos++;
                        }
                    }
                }
            }
        }
    }
    $pr_rtnseq = $rtnseq;
    $pr_rtnseq = _rpl_INS($list,$b,$c,$d,$rtnseq,$f,$ql,$dp,$rep_n);
    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);
	$Npos=$a[$i];
        $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();
    if($mode === "a"){
        $dp=0;
        $qual=0;
    }
//    $stmt = $conn->stmt_init();
    $x=count($list);
    for($i=0;$i<$x;$i++){
	$p = $list[$i];
//        $p=array_shift($list);

        $stmt = $conn->stmt_init();

#	$query = "SELECT pos,variant,ref,substring_index(alt, ',', 1),qual,dp,GT FROM ".$p."_variant WHERE ". getGtNotZeroSql(). " and chr= ? and pos >= ? and pos <= ? and dp >= ? and qual >= ? ";
        $query = "SELECT pos,variant,ref,alt,qual,dp,GT FROM ".$p."_variant WHERE ". getGtNotZeroSql(). " and 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,$gt);
        while ($stmt->fetch()) {
            if(_isTransposon($row3)) continue;
//            $row3 = explode(",", $row3)[0];	// Test code
       	    $row3 = preg_replace("/\*/", "-", $row3);	//20190614 add because error appears in clustalw.
            if($mode === "a"){
                $var_array[$p.":".$row0] = $row1. ":". strtoupper($row2). ":". strtoupper($row3). ":". $row4. ":". $row5. ":". $gt;
            }else{
                $arr_row3 = explode(",", $row3);
                $row3 = $arr_row3[0];
                if(array_key_exists($row0, $var_array)){
                    $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();
    }
//    $stmt->close();
    return $var_array;
}

/////////////ummapped postion  _EMPDP($ac,$prm_chr,$prm_s,$prm_e);
function _EMPDP($a, $b, $c, $d,$conn){
    global $db;

    $null=array();
    $stmt = $conn->stmt_init();
    $param=$b."_b";
    $table = getSerialTableByColumn($conn, $db, $a."_accession", $param);
    $query="SELECT pos FROM ". $table. " WHERE `". $param. "` is null and pos >= ? and pos <= ? ";    
//    $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;
}

///Getting template sequences using Redis (prm_chr, prm_s, prm_e, connRedis)
function _getRefseqRedis($a,$b,$c,$redis){
    $refseq = "";
    $key = "";
    $field = 0;
    for($x=$b; $x<$c+1; $x++){
        $key = $a.":".(int)($x/100);
        $field = $x%100;
        if($redis->exists($key)){
            $refseq .= $redis->hGet($key,$field);
        }
    }
    return $refseq;
}

/////////////ref-seq _GETREFSEQ($prm_chr, $prm_s, $prm_e, $conn);
function _GETREFSEQ($a,$b,$c,$conn){
    global $db;
    $refseq="";

    $table = getSerialTableByColumn($conn, $db, "sys_fasta", $a."_f");
    $query = "SELECT `".$a."_f` FROM ". $table. " WHERE pos >= ? and pos <= ?";
//    $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 .= $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){
    $orders = array();
    if (file_exists( "../conf/order.conf")) {
        $line = file_get_contents("../conf/order.conf");
        $accids = explode("\n",$line);
        foreach ($accids as $accid) {
            $accid = trim($accid);
            if(empty($accid)) {continue;}
            $orders[$accid] = 1;
        }
    }

    $str=array();
    $d = _validate_name($d);
    $e = _validate_group($e);
    $query = "SELECT ".$d.", ".$e.",accession_db,accession_id FROM sys_accession WHERE accession_db= ? ";
    $stmt = $conn->stmt_init();
    $stmt->prepare($query);
    $num_orders = count(array_keys($orders));
    $aLen = count($a);
    for($i=0;$i<$aLen;$i++){
        $stmt->bind_param("s", $a[$i]); 
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($row0,$row1,$row2,$accid);
        while ($stmt->fetch()) {
            if($num_orders > 0 && !array_key_exists($accid, $orders)) {
                $stmt->free_result();
                $stmt->close();
                return array();
            }
            if($mode === "a"){
                if (!isset($_SERVER["HTTP_HOST"])) {
                    $str[$i] = $row2;
                }else{
                    $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,$prm_DN,$prm_DNnum,$prm_list,$prm_e,$prm_tgt){
    /* 
    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
    */
  require '../conf/config.php';
  //////////////////////////////////  Connecting with DB
  if( !$conn = new mysqli($host, $user, $pswd, $db)) {
    error_log("Connection failed.\n");
    exit;
  }
  /////////////////////////////////
    $pointer=0;
    list($tgt,$tgte) = explode('-',$prm_tgt);
//    list($tgt,$tgte) = split('-',$prm_tgt);
//    $numarray = count($altpos);
    if($prm_type === "b") {
	$prm_DN = "0";
    }
    $seqstr="";
    if($prm_DN == 1) {
      // Number of "DEPTH = NA" accessions
      $pos = array();
      $db_lists = explode(",",$prm_list);
      $x = count($db_lists);
      for($i=0;$i<$x;$i++){
	$table = getSerialTableByColumn($conn, $db, $db_lists[$i]."_accession", $prm_chr."_b");
        $query = "SELECT pos FROM ". $table. " WHERE `". $prm_chr. "_b` is NULL and pos between ? and ?";
//    	$query = "SELECT pos FROM ". $db_lists[$i]. "_accession where `". $prm_chr. "_b` is NULL and pos between ? and ?";
        $stmt = $conn->stmt_init();
    	$stmt->prepare($query);
    	$stmt->bind_param("ii", $prm_s, $prm_e);
    	$stmt->execute();
    	$stmt->store_result();
    	$stmt->bind_result($row0);
    	while ($stmt->fetch()) {
	    if(array_key_exists($row0,$pos)) {
		$pos[$row0]++;
//		$pos[$row0] = $pos[$row0] + 1;
	    } else {
		$pos = $pos + array($row0 => '1');
	    }
    	    //$lposition[] = $row0;
    	}
      }
      foreach ($pos as $key => $v) {
	if($v > $prm_DNnum) {
		$lposition[] = $key;
	}
      }
      //$lresult = array_unique($lposition);
      //$lresult = implode(",",$lresult);
      $result = implode(",",$lposition);
      $pr_refseqLen = strlen($pr_refseq);
      for ($i=0; $i<$pr_refseqLen; $i++) {
	$pos = $prm_s + $i;
	if(preg_match('/'.preg_quote($pos,'/').'/',$result)) {
		if(!($pos > $tgt-1 && $pos < $tgte+1)) {
	  		$seqstr .= "N";
		} else {
			$seqstr .= $pr_refseq[$i];
		}
	} else {
	  $seqstr .= $pr_refseq[$i];
	}
      }
      $pr_refseq = $seqstr;
    }

    $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);	// Variant pos
                $varOnFlk=explode("\t", $altpos[$key]);
                if($key != $range0){
                    $varOnFlk=explode("\t", $altpos[$key]);
                    if($varOnFlk[2]=="d"){
			// Deletion
                        $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"){
			// Insertion
//                        $rplNs="";
                        $targetSeq=explode("/", $varOnFlk[1]);
                        $numNs = abs(strlen($targetSeq[1])-strlen($targetSeq[0]));
                        if($key < $range0){
                            $pointer = $pointer+($numNs);
                        }
			$seqarray[$key - $prm_s + 1] = "N";
//                        $seqarray[$key-$prm_s]=$seqarray[$key-$prm_s].str_repeat("N", $numNs);
                    }else{
			// SNP
                        $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>";
    
//    $oriRefTargetStart = $range0 - $prm_s + 1;
    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>";
    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];
    // create primer3 query file.
$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_FIRST_BASE_INDEX=0
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,$epcrparam,$primer3Path,$prm_chr){ 
    global $MFE3path, $MFE3DBpath, $MFEpath, $MFEDBpath;

    if (!file_exists($primer3Path) || preg_match("/^\S*primer3_core$/", $primer3Path) != 1) {
        echo "Error: Primer3 was not found.";
        echo $primer3Path;
        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(empty($resArray)){
        echo "Error: Can not execute Primer3.";
        exit;
    }
    if($epcrparam[0] == 1) { //run MFEprimer if ePCR is selected ON
        $epcr_prdmi = $epcrparam[1];
        $epcr_prdmx = $epcrparam[2];
        $epcr_tmmx = $epcrparam[3];
        $epcr_tmmi = $epcrparam[4];
        $epcr_monoconc = $epcrparam[5];
        $epcr_divaconc = $epcrparam[6];
        $epcr_dNTP = $epcrparam[7];
        $epcr_anneal = $epcrparam[8];
		
        $leftArray = Array();
        $rightArray = Array();
        $p3resArray = Array();
        $p3resArray = explode("\n", $primer);
        $t=count($p3resArray);
        $pattern_prmL = "/.*LEFT PRIMER\s+(\d+)\s+(\d+).*\s+(\w+)$/";
        $pattern_prmR = "/.*RIGHT PRIMER\s+(\d+)\s+(\d+).*\s+(\w+)$/";
        $lcount = 0;
        $rcount = 0;
        for($i=0; $i<$t; $i++){
                if(preg_match($pattern_prmL, $p3resArray[$i], $match_done) != 0){
                    $leftArray[$lcount]=$match_done[3];
                        $lcount++;
                }
                if(preg_match($pattern_prmR, $p3resArray[$i], $match_done) != 0){
                    $rightArray[$rcount]=$match_done[3];
                        $rcount++;

                }
        }
	$mfeVer; $mfeExe; $mfeDb; 
//	if(false) {
	if(isset($MFE3path) && file_exists($MFE3path) && isset($MFE3DBpath) && file_exists($MFE3DBpath)) {
		$mfeVer = 3;
		$mfeExe = $MFE3path;
		$mfeDb = $MFE3DBpath;
	} else if(file_exists($MFEpath) && file_exists($MFEDBpath)) {
		$mfeVer = 2;
		$mfeExe = $MFEpath;
		$mfeDb = $MFEDBpath;
	} else {
		$errmsg = "Error: MFEprimer or Database was not found.";
		echo $errmsg;
		exit;
	}
/*
        if (!file_exists($MFEpath) || preg_match("/^\S*MFEprimer.py$/", $MFEpath) != 1) {
                $errmsg = "Error: MFEprimer was not found.";
                echo $errmsg;
                exit;
        }
*/
	$MFEprimer = "";
	if ($lcount == 0 ) {
		$MFEprimer ="<strong>PRIMER NOT FOUND</strong>";
	} else {
		for ($i=0; $i<$lcount;$i++) {
			$query=">left\n".$leftArray[$i]."\n>right\n".$rightArray[$i];
			$fp = tmpfile();
			fwrite($fp, $query);
			rewind($fp);
			$tmparray = stream_get_meta_data($fp);
			$resArray2 = array();
			if($mfeVer !== 2) {
				// >=MFEprimer3
				$resPath = $tmparray['uri']. "_res";
				$jsonPath = $resPath. ".json";
				$MFE_Cmd = $mfeExe. " spec --json -i ". $tmparray['uri']. " -d ". $mfeDb. " -o ". $resPath.
//					" --tm ". $epcr_tmmi.
					" --minSize ". $epcr_prdmi. " --maxSize ". $epcr_prdmx. " --mono ". $epcr_monoconc. " --diva ". $epcr_divaconc.
					" --dntp ". $epcr_dNTP. " --oligo ". $epcr_anneal;
//error_log($MFE_Cmd);
				_pregMatch($MFE_Cmd);
				$errorOccur = false;
				try {
					exec($MFE_Cmd,$resArray2,$return);
					if(!file_exists($jsonPath)) throw new Exception("Error: Can not execute MFEprimer.");
					$jsonStr = file_get_contents($jsonPath);
					$jsonObj = json_decode($jsonStr, true);
					$resArray2[] = implode("\t", array("AmpID","FpID","RpID","HitID","PPC","Size","AmpGC","FpTm","RpTm","FpDg","RpDg","BindingStart","BindingStop","AmpSeq"));
					if(array_key_exists("AmpList", $jsonObj) && count($jsonObj["AmpList"])) {
						$procNum = count($jsonObj["AmpList"]);
						$resArray2 = array();
						for($j=0; $j<$procNum; $j++) {
							$procObj = $jsonObj["AmpList"][$j];
							$onerow = implode("\t", array(
								$j+1,
								$procObj["F"]["Seq"]["ID"],
								$procObj["R"]["Seq"]["ID"],
								$procObj["Hid"],
								round($procObj["PPC"], 2),
								$procObj["Size"],
								round($procObj["GC"], 2),
								round($procObj["F"]["Tm"], 2),
								round($procObj["R"]["Tm"], 2),
								round($procObj["F"]["Dg"], 2),
								round($procObj["R"]["Dg"], 2),
								$procObj["F"]["BindingStart"],
								$procObj["R"]["BindingStart"],
								trim($procObj["P"]["Seq"]["Seq"])
							));
							$resArray2[] = $onerow;
						}
					}
				} catch(Exception $e) {
					error_log($e->getMessage());
					echo "Error: Can not execute MFEprimer.";
					$errorOccur = true;
				}
				// "finally" cannot be used <PHP5.5

				if(file_exists($resPath)) unlink($resPath);
				if(file_exists($jsonPath)) unlink($jsonPath);
				if($errorOccur) exit;
			} else {
				// MFEprimer2
				$MFE_Cmd="python ". $mfeExe. " -i ".$tmparray['uri']." -d ".$mfeDb.
					" --size_start ".$epcr_prdmi." --size_stop ".$epcr_prdmx.
					" --tm_stop ".$epcr_tmmx." --tm_start ".$epcr_tmmi." --mono_conc ".$epcr_monoconc." --diva_conc ".$epcr_divaconc.
					" --dntp_conc ".$epcr_dNTP." --oligo_conc ".$epcr_anneal." --tab";
//error_log($MFE_Cmd);
				_pregMatch($MFE_Cmd);
				exec($MFE_Cmd,$resArray2,$return);
				if(count($resArray2) === 0) {
					echo "Error: Can not execute MFEprimer.";
					exit;
				}
			}
			$MFEprimer = $MFEprimer. $query. "---QUERY---". implode("\n", $resArray2). "---MFERES---";
		}
	}
        return array($MFEprimer,$primer);
    } else {
        return array("",$primer);
    }
}

function _genMFEResult($name,$res,$p3Res,$leftArray,$rightArray){
    $resArray = explode("|", $res);
    $p3ResArray = explode("\n",$p3Res);
    $t=count($p3ResArray);
    $count=0;
    $qnum=-1;
    for ($i=0;$i<$t;$i++) {
        if (strstr($p3ResArray[$i], 'AmpID')) {
                if($count==0) {
                        $count=0;
                        $qnum++;
                } else {
                        $temp=$temp."Left:".$leftArray[$qnum]." Right:".$rightArray[$qnum]." Amp:".$count."\n";
                        $count=0;
                        $qnum++;
                }
        } else if (! (strstr($p3ResArray[$i], 'AmpID')) ) {
                $count++;
                $resArray = explode("\t",$p3ResArray[$i]);
        }
    }
        $temp=$temp."Left:".$leftArray[$qnum]." Right:".$rightArray[$qnum]." Amp:".$count."\n";

}
function _genResult($name,$res,$prm_p3prm,$p3Res){
    $param = explode(",", $prm_p3prm);
    $resArray = explode("|", $res);
    $targetStart=$resArray[1]-1;
    $insertOffset = $resArray[4];
    $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."--split--".$insertOffset;
    return $primer;
}

function _validate_chrs($conn, $prm_Chr){
    $flag = false;
    $query = "select seq from sys_chromosome where id=? limit 1";
    $stmt = $conn->stmt_init();
    $stmt->prepare($query);
    $stmt->bind_param("s", $prm_Chr); 
    $stmt->execute();
    $stmt->store_result();
    $stmt->bind_result($row0);
    while ($stmt->fetch()) {
        $flag = true;
    }
    $stmt->free_result();
    $stmt->close();
    if($flag){
       return true;
    }else{
       return false;
    }
}

function _validate_each_acc($list){
    $num = count($list);
    for($a=0;$a<$num;$a++){
        if (preg_match("/^d\d+$/i", $list[$a])) {
            //pass
        }else{
           return false;
        }
    }
    return true;
}
function _validate_name($str){
    if($str === "id"){
        $str="accession_id";
    }else if($str === "name"){
        $str="accession_name";
    }else{
        return false;
    }
    return $str;
}

function _validate_group($str){
    $keys = array(
	"accession_id" => 1,
	"accession_name" => 1,
        "variety" => "1",
        "sub_variety" => "1",
        "origin" => "1",
        "origin_2" => "1",
        "type" => "1",
        "other_1" => "1",
        "other_2" => "1"
    );
    if($str === "subvariety" ){
	$str = "sub_variety";
    } else if($str === "id") {
	$str = "accession_id";
    } else if($str === "name") {
	$str = "accession_name";
    }
    if(array_key_exists($str, $keys)){
        return $str;
    }else{
        return false;
    }
}

function _validate_p3prm($str) {
	$prms = explode(",",$str);
        $num = count($prms);
        for ($i = 0; $i < $num; $i++) {
                if(!is_numeric($prms[$i])) {
                        $errmsg = "<div align=\"center\"><font color=\"red\" style=\"font-size:18px;\">Invalid Value!!</font></div>";
                        echo $errmsg;
                        exit;
                }
        }
}

function _valRefName($prm_ref,$reference){
    $ret=0;
    if($prm_ref==$reference){$ret=1;}
    return $ret;
}

function returnError($str){
    echo $str;
}

function _stopError($str){
    echo $str;
    exit;
}
?>
