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

	////////////////////////////////// Parameters
	(isset($_GET['prm_fa_chr']) && !empty($_GET['prm_fa_chr'])) ? $prm_chr=$_GET['prm_fa_chr']:returnError("Error");
	(isset($_GET['prm_fa_s']) && !empty($_GET['prm_fa_s'])) ? $prm_s=$_GET['prm_fa_s']:returnError("Error");
	(isset($_GET['prm_fa_e']) && !empty($_GET['prm_fa_e'])) ? $prm_e=$_GET['prm_fa_e']:returnError("Error");
	(isset($_GET['prm_fa_qual']) && !empty($_GET['prm_fa_qual'])) ? $prm_qual=$_GET['prm_fa_qual']:returnError("Error");
	(isset($_GET['prm_fa_dp']) && !empty($_GET['prm_fa_dp'])) ? $prm_dp=$_GET['prm_fa_dp']:returnError("Error");
	(isset($_GET['prm_fa_list']) && !empty($_GET['prm_fa_list'])) ? $prm_list=$_GET['prm_fa_list'] : returnError("Error");
	(isset($_GET['prm_fa_name']) && !empty($_GET['prm_fa_name'])) ? $prm_name=$_GET['prm_fa_name'] : returnError("Error");
	(isset($_GET['prm_fa_nameS']) && !empty($_GET['prm_fa_nameS'])) ? $prm_nameS=$_GET['prm_fa_nameS'] : returnError("Error");
	(isset($_GET['prm_fa_ref']) && !empty($_GET['prm_fa_ref'])) ? $prm_ref=$_GET['prm_fa_ref'] : returnError("Error");
	(isset($_GET['prm_fa_width_php']) && !empty($_GET['prm_fa_width_php'])) ? $prm_width=$_GET['prm_fa_width_php'] : 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);
	
	if ($prm_width == -1){
		$prm_width=0;
	}
	
    if($prm_e-$prm_s>9999){  // Maximum size is 10K
		$prm_e=$prm_s+9999;
	} else if($prm_e-$prm_s < 0){
		$prm_e=$prm_s;
	}
	
	//////////////////////////processing
	
	$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);
   
	$altpos =  _VAR($list,$prm_chr,$prm_s,$prm_e,$conn);
   
	echo ">REF_".$prm_ref."\n";
    $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 $pr_refseq."\n";
	
	$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){
		$var_array = array();
		$x=count($list);
		$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 <= ? ";
			$stmt->prepare($query);
			$stmt->bind_param("sii", $b, $c, $d); 
			$stmt->execute();
			$stmt->store_result();
			$stmt->bind_result($row0,$row1,$row2,$row3,$row4,$row5);
			while ($stmt->fetch()) {
				$var_array[$p.":".$row0]=$row1.":".strtoupper($row2).":".strtoupper($row3).":".$row4.":".$row5;
			}
			$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){
	$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()) {
			$str[$i] = $row0."_".$row1;
		}
		$stmt->free_result();
    }
	$stmt->close();
    return $str;
  }
  
  /////////////
  function returnError($str){
    echo $str;
  }

?>