<?php
########################################################################################
########################################################################################
##Define paths

$sesspath ="/srv/www/htdocs/freedna/sessions/";
$baseDIR = "/srv/www/htdocs/freedna/";
$count = ("$baseDIR/hitcounter.txt");
$progDIR = "$baseDIR/prog/";
$dat = "/srv/www/htdocs/freedna/prog/DAT";
$dirX0 = "$dat/X0/";
$dirSeq = "$dat/../../sequences/";
$webdir = "http://dna.engr.latech.edu/freedna/sessions/";
$webdirSeq = "http://dna.engr.latech.edu/freedna/sequences/";


########################################################################################
########################################################################################
##Define variables

##define array $errors
if (isset($errors)) {}
else {$errors = array();}
##Define $SID

###$seqin = $_POST['seqin'];

#SEQ menu vars
if (isset($_POST['requpseq'])) {
   if ($_POST['requpseq'] == 1) {
   $requpseq = 1;
   }
elseif($_POST['requpseq'] == 0){
   $requpseq = 0;
   }
}
#NSS menu vars
if (isset($_POST['reqtypenss'])) {
   if ($_POST['reqtypenss'] == 1) {

       $reqtypenss = 1;}
}

else {$reqtypenss = 0;}

if (isset($seqform)) {}
else {$seqform = 0;}
$nssintype_1 = "";

if (isset($_POST['K'])){$K = $_POST['K'];} 
else {$K = "0";}
if (isset($_POST['linker'])){$linker = $_POST['linker'];} 
else {$linker ="0";}
if (isset($majortick)){} 
else {$majortick ="";}
if (isset($_POST['nss'])){$nss = $_POST['nss'];} 
else {$nss ="";}
if (isset($nuclength)){} 
else {$nuclength ="";}
if (isset($numnuc)){} 
else {$numnuc ="";}
if (isset($_POST['percentnucleo'])){$percentnucleo = $_POST['percentnucleo']/100;} 
else {$percentnucleo ="80";}
if (isset($_POST['seqin'])){$seqin = $_POST['seqin'];} 
if (isset($seqinlength)) {} 
else {$seqinlength ="";}
if (isset($validseq)){} 
else {$valid ="";}
if (isset($_POST['X'])){$X = $_POST['X'];} 
else {$X = "0";}
if (isset($_POST['X0'])){$X0 = $_POST['X0'];} 
else {$X0 ="0";}
if (isset($xmajortick)){} 
else {$xmajortick ="";}



########################################################################################
##########################################################################################Define Functions

function counter() {
##This function opperates the counter and cleans-up the sessions directory
global $SID, $count, $sesspath;
if ($SID == 0){
  ##Take the hits from the file $count
  $hits = file($count);
    ##Increment it by one
    $hits[0] ++;
  ##write the new number to the file $count
  $fp = fopen($count , "w");
          fputs($fp , "$hits[0]");
        fclose($fp);
$SID = $hits[0];
##Make directory for the new session
mkdir("$sesspath$SID", 0777);
#mkdir("$sesspath$SID/thumbs", 0777);
}

##The variable SIDmTen controls how many full session directories are kept and how many are archived
$SIDmTen = $SID - 500;
##move/rename the confin and seqin files
##rename("$sesspath/$SIDmTen/confin.txt", "$sesspath/archive/$SIDmTen.confin.txt");
##rename("$sesspath/$SIDmTen/seqin.txt", "$sesspath/archive/$SIDmTen.seqin.txt");
##empty directory for the session $SIDmTen, then remove it

$dir = "$sesspath/$SIDmTen";
$directory = escapeshellarg($dir);
exec("rm -rf $directory");

}

########################################################################################
function makeconfig() {
global $confin, $errors, $K, $linker, $nuclength, $nss, $numnuc, $percentnucleo, $reqtypenss, $requpseq, $seqinlength,  $sesspath, $seqin, $SID, $validseq, $X, $X0;
## This function writes the sequence file and confirms that all user input data is valid, then writes the confin file
#make global variables
$seqinfile = "$sesspath$SID/seqin.txt";
$uploadfile = "$sesspath/$SID/uploaded.txt";

#Read nuclength from $X file
#$fh = fopen($X, 'r');
#$nuclength = fread($fh, 5);
#fclose($fh);


if (preg_match('/[^A,T,G,C,\s]/i', $seqin)) {
        ##if not A, T, G, C's add an error to the error array and re-print the form
	$errors['seqin'] = "Please fix your sequence to have only a, t, g, c, \n A, T, G, and C characters with spaces.";
        $validseq = FALSE;}
##otherwise make $validseq true as to use in determining if form should be reprinted
else {$validseq = TRUE;}
$seq4prog = trim(chunk_split(strtoupper(preg_replace('/[^A,T,G,C]/i','', $seqin)), 1, "\n"));
$seqinlength = strlen(preg_replace('/[^A,T,G,C]/i','', $seqin));
$fp = fopen($seqinfile, 'w+');
	{
   	  fwrite($fp, $seq4prog );
	  }
fclose($fp);
  #write confin
  #calc $numnuc
##  $numnuc = floor($percentnucleo*$seqinlength/($nuclength+$linker));
$confinE = "$X0\n$sesspath$SID/seqin.txt\n$sesspath$SID/eq.out.par\n";


  if (1 == $requpseq ) {
       uploader();
       $fh0 = fopen($uploadfile, 'r');
       $seqin = fread($fh0, filesize($uploadfile));
       fclose($fh0);
     if (1 == $reqtypenss) {
       $numnucnss = count($nss);
       $nss = implode("\n", explode(" ", $nss));
       $confin = "$X0\n$X\n$sesspath$SID/seqin.txt\n$numnuc\n$linker\n$sesspath$SID/wdna.par\n";
       pc_validate_nss();
       }
     elseif (0 == $reqtypenss) {
       $confin = $confinE; 
     }
  }
  elseif (0 == $requpseq) {
     $confin = $confinE;
  }

  $fp = fopen("$sesspath$SID/confin.txt", 'w+');
	{
        fwrite($fp, $confin );
	  }
	fclose($fp);}




########################################################################################
function uploader() {
##make global variables
global $SID, $sesspath;
//Сheck that we have a file
if((!empty($_FILES["uploadedfile"])) && ($_FILES['uploaded_file']['error'] == 0)) {
  //Check if the file is txt and it's size is less than 350Kb
  $filename = basename($_FILES['uploadedfile']['name']);
  $ext = substr($filename, strrpos($filename, '.') + 1);
  if (($ext == "txt") && ($_FILES["uploadedfile"]) && 
    ($_FILES["uploadedfile"]["size"] < 350000)) {
    //Determine the path to which we want to save this file
      $newname = "$sesspath$SID/" . "uploaded.txt";
      //Check if the file with the same name is already exists on the server
      if (!file_exists($newname)) {
        //move the uploaded file to uploads/
        if ((move_uploaded_file($_FILES['uploadedfile']['tmp_name'],$newname))) {
	   $requpseq = 1;
        } else {
           echo "Error: A problem occurred during file upload!";
        }
      } else {
         echo "Error: File ".$_FILES["uploadedfile"]["name"]." already exists; please save the file the file with another name and try again.";
      }
  } else {
     echo "Error: Only .txt files under 350Kb are accepted for upload";
  }
} else {
 echo "Error: No file uploaded";
}
}

########################################################################################
## This function opens the nss file and confirms that all user input data is valid.
function pc_validate_nss() {

global  $errors, $linker, $nss, $nuclength, $numnuc, $percentnucleo, $seqinlength, $sesspath, $SID, $validnss, $X;


	##verify entry contains only  numerical entries
	if (preg_match('/[^0-9,\s]/i', $_POST['nss']) == TRUE)
	{
	$nsscond1 = FALSE;
	$errors['nss'] = "Please fix your listing to have only nucleosome start sites \n (numerical entries only) separated  by spaces";
	}else{
	##opening file to be read as to obtain the length of the nucleosome selected.
	$fh = fopen($X, 'r');
	$nuclength = fread($fh, 5);
	fclose($fh);
if ($nss == ""){
$nsscond2 = FALSE;
$errors['nssempty'] = "If the energy function is to be bypassed at least one nucleosome start site must be specified.";}
else {
	##trim whitespace
	$trimmednss = trim($nss);
	##replace spaces with commas
	$nssuni = str_replace(" ",",",$trimmednss); 
	##explode array into a string for sorting
	$nssarr = explode(",", $nssuni);
	sort($nssarr, SORT_NUMERIC);
	##delete duplicate values
	$nss = array_unique($nssarr);
	$last = end($nss);
	$maxnss = $seqinlength - $nuclength;
	if ($last > $maxnss) {
	  if ($seqinlength < $nuclength) {
	  $nsscond3 = FALSE;
	  $errors['nssseq'] = "Using this X value, each nucleosome is $nuclength" . "bp in length. \nPlease specify a sequence that is greater than $nuclength" . "bp long.";
          }
	  elseif ($seqinlength > $nuclength) {
	  $nsscond4 = FALSE;
	  $errors['nssend'] = "You have requested a nucleosome start site that is less than \n $nuclength from the end of your sequence.  The last nucleosome start \n sites for this sequence must be less than $maxnss";
	  }
        }
	$zeros = range(1, $seqinlength);
	## from [0] to [n-1] in the array $nss subtract the value [i+1] from the value [i]
	$i=0;
	while($i < count($nss) -1) {
	  $diff = $nss[$i+1] - $nss[$i];
	  $i++;
	## if $diff is less than the $nuclength condition is false, otherwise condition is true
	    if ($diff < $nuclength ) {
	    $tooclose[] = $nss[$i-1]; 
	    $tooclose[] = $nss[$i];
	    $gtnuclength = false;
	    }else $gtnuclength = true;
	}
	#if there is not sufficient space between nucleosomes print an error message
	if ($gtnuclength = false) {
	$tooclose = join(', ', array_unique($tooclose));
	$errors['nssclose'] = "Please fix your nucleosome start sites as to insure there \n are at least $nuclength bp between each nucleosome. The nucleosomes \n at: " . $tooclose . " are less than $nuclength bp apart.";
	$nsscond5 = FALSE;
	}}}
if($nsscond1 = FALSE || $nsscond2 = FALSE || $nsscond3 = FALSE || $nsscond4 = FALSE || $nsscond5 = FALSE){$validnss = FALSE;}
else{$validnss = TRUE; }
}

########################################################################################
function print_form(){
global $dirK, $dirX, $dirX0, $dirSeq, $Energy, $errors, $nssintype_1, $reqtypenss, $requestnss,  $requpseq, $seqin, $SID, $webdirSeq;
##Determine if directions or the user's sequence should be printed in the textbox
$directions = <<<END

Enter a sequence of A's,C's, G's, and T's  
then  click "Go" .

END;

if (isset($seqin)) {}
else {$seqin = "$directions";}


##Define whether or not the user will see the text box to insert NSS's, or if they will see a button requesting to the text box.  The function is simmiliar to the seqtype() function

##These are the var that prints the default button
$nssintype0 = '';
$requestnss0 = "<span class=\"style2\">If you prefer specifying your nucleosome start sites (bypassing our \nenergy calculations) click the button below." . "<FORM action=\"$_SERVER[PHP_SELF]\" method=\"post\" ><input type=\"hidden\" name= \"reqtypenss\" value= \"1\"><input type=\"hidden\" name= \"requpseq\" value= \"$requpseq\"><INPUT TYPE=\"submit\" VALUE=\" Specify NSS \"style=\"height:25px;width:105px;font-weight: bold; font-size:14px;font-family:'Times New Roman';\"></FORM></span>";

##These are the var for the the upload button
$nssintype1 = '
<input type="hidden" name= "reqtypenss" value= "1"><TEXTAREA name="nss" rows="7" cols="40" STYLE="background:white; color:#000000;
font-family: arial; font-size:14px; padding-left: 6px; padding-right: 6px; border: 10px">
Directions: 
****************
1) Replace the text in this box with the nucleosome start sites for the strand of dna to be viewed as folded by jmol.
</TEXTAREA>';
$requestnss1 ='';

if ($reqtypenss == 1) {
 $requestnss = $requestnss1;
 $Energy = FALSE;
 if ($requpseq == 1) {
   $nssin_type = $nssintype1;
   $nssintype_1 = $nssintype1; }
 elseif ($requpseq == 0) {
   $nssin_type = "";
   $nssintype_1 = $nssintype1;
   $requestnss = $requestnss1;}}
elseif ($reqtypenss == 0) { 
 $nssin_type = $nssintype0;
 $requestnss = $requestnss0;
 $Energy = TRUE;}

##This function defines whether or not the user will see the button to browse their file system for a sequence file, or if they will see a button requesting to upload a file.

$seqintype0 = "";
$requestseq0 = "<span class=\"style2\">If you prefer uploading your DNA sequence (in lieu of typing it in) \nclick the button below.</span><FORM action=\"$_SERVER[PHP_SELF]\"  onReset=\"return allowReset()\" method=\"post\" ><input type=\"hidden\" name= \"requpseq\" value= \"1\"><input type=\"hidden\" name= \"reqtypenss\" value= \"$reqtypenss\"><input type=\"hidden\" name= \"seqin\" value= \"\$seqin\"><INPUT TYPE=\"submit\" VALUE=\"Upload Sequence\" style=\"height:25px;width:150px;font-weight: bold; font-size:14px;font-family:'Times New Roman';\"></p></FORM>";
$seqform0 = "<TEXTAREA name=\"seqin\" rows=\"20\" cols=\"50\" STYLE=\"background:white; color:#000000;
font-family: Arial; font-size:14px; padding-left: 6px; padding-right: 6px; border: 10px  #FFFFFF;\">
$seqin
</TEXTAREA></p>
</p>
$nssintype_1
</th>
</td>
<td>";

$seqintype1 = '
Choose a DNA sequence to upload: </p> </p>
<input name="MAX_FILE_SIZE" value="350000" type="hidden">
<input name="uploadedfile" type="file" style="height:25px;width:150px;font-weight: bold; font-size:14px;font-family:\'Times New Roman\'</p></FORM>";>
';
$requestseq1 = "";
$seqform1 = "";
if ($requpseq == 1) {
  $seqin_type = $seqintype1;
  $requestseq = $requestseq1;
  $seqform = $seqform1;}
elseif ($requpseq == 0) { 
  $seqin_type = $seqintype0;
  $requestseq = $requestseq0;
  $seqform = $seqform0;}

##Begin printing form
echo <<<BEGINHTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
 <title>Nucleosome Maker</title>
  <meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
  <link href="../bishop.css" rel="stylesheet" type="text/css">
  <script type="text/JavaScript">
<!--
function MM_jumpMenu(targ,selObj,restore){ //v3.0
eval(targ+".location='"+selObj.options[selObj.selectedIndex].value+"'");
if (restore) selObj.selectedIndex=0;
}
//-->
  </script>
</head>
<body>
</html>
BEGINHTML;

echo <<<END
</p>
</p>
<span class="style1">
Simple Models of DNA
</span>
<span class= "style2">
</h2>
<table align="center" border="0">
<tr>
<td>
<th align="left" width=400>
<FORM enctype="multipart/form-data" action="$_SERVER[PHP_SELF]"  onReset="return allowReset()" method="post" >
<input type="hidden" name="stage" value="process">
<input type="hidden" name= "requpseq" value= "$requpseq">
$seqform
</p>
<h3 align="center">
$nssin_type
END;
if ($Energy == TRUE){
echo "<span class=\"style2\"> Model Options:
</p> ";
 }

echo "</select> </p>
X<sub>0</sub> =";  

##XO value menu
$files = array();
$handle = opendir($dirX0);
  while($filename = readdir($handle))
  { if ( substr( $filename, -4 ) == ".par" ) {
        $files[] = $filename;}  }
   closedir($handle);
   sort( $files );
## Output results
echo "<select name=\"X0\" style=\height:30px;width:180px;font-weight: bold; font-size:14px;font-family:\'Times New Roman\'>";
foreach( $files AS $name ) {
    echo "<option value=\"$dirX0$name\">" . substr($name,0,20) . "</option>";
}
echo  "</select> </h3>";
echo <<<END

<h5 align="center">
<INPUT type="submit" value="Go" style="height:30px;width:50px;font-weight: bold; font-size:16px;font-family:'Times New Roman';">
<INPUT TYPE="BUTTON" VALUE="Reset" style="height:30px;width:65px;font-weight: bold; font-size:16px;font-family:'Times New Roman';" ONCLICK="window.location.href='$_SERVER[PHP_SELF]'"> 
           </FORM>
</h5>
         </td>
        </tr>
       </table>
     </P> 

 </P>
$requestseq
</span>
<span style="color:FF9900;">Try one of our
samples here:&nbsp;</span>

END;

##Sample Sequence Menu
$files = array();
$handle = opendir($dirSeq);
  while($filename = readdir($handle))
  { if ( substr( $filename, -4 ) == ".txt" ) {
        $files[] = $filename;}  }
   closedir($handle);
   sort( $files );
## Output results
echo "<form id=\"seqmenu\">
  <div align=\"center\">
  <select name=\"seqmenu\" onchange=\"window.open(this.options[this.selectedIndex].value,'_blank');\">
  <option value=\" \"> </option>";
foreach( $files AS $name ) {
    echo "<option value=\"$webdirSeq$name\">" . substr($name,0,10) . "</option>";
}

echo  "</select> </h3>
    </body>
  </html>
";
}



########################################################################################
########################################################################################
function print_output() {
global $seqin, $SID,  $webdir, $curvature;

$fh = fopen("/srv/www/htdocs/freedna/sessions/$SID/curv.dat", 'r');
$bend  = fgets($fh);
$shear = fgets($fh);
$score = fgets($fh);
fclose($fh);

echo <<<END
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <script src="https://dna.engr.latech.edu/freedna/jmol/jsmol/js/JSmol.js"
 type="text/javascript"></script>
  <link type="text/css" rel="stylesheet"
 href="https://dna.engr.latech.edu/freedna/output.css">
  <title>output.html</title>
</head>
<body>
<div style="text-align: left;" id="wrap">
<span style="color:FF9900;"> &nbsp;
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp;</span><span
 style="color:FF9900;"></span>

<table
 style="width: 100%; text-align: left; margin-left: 0px; margin-right: auto;"
 border="1" cellpadding="2" cellspacing="2">
        <tbody>
          <tr>
            <td>
            <h3 align="left"> Centerline Model<br>
            <script>
jmolInitialize("/freedna/jmol/jsmol/js/"); // REQUIRED
jmolApplet(150, value= "load https://dna.engr.latech.edu/freedna/sessions/$SID/eq.out.xyz; select elemno=20; spacefill 478; spin on");
jmolBr(); // a button
jmolButton("reset", "Reset");
            </script>
            </h3>
            <h3 align="center">
            <form><a =""><input
 value="Larger Window"
 onclick="window.open('$webdir$SID/simple.html','JmolSimple','width=525,height=600')"
 type="button"></a></form>
            </h3>
            </td>
            <td>
            <h3 align="right"> All Atom Model<br>
            <script>
jmolApplet(150, value= "load https://dna.engr.latech.edu/freedna/sessions/$SID/dna.pdb; spin on");
jmolBr(); // a button
jmolButton("reset", "Reset");
            </script>
            </h3>
            <h3 align="center">
            <form><a =""><input
 value="Larger Window"
 onclick="window.open('$webdir$SID/allatom.html','JmolAllAtom','width=525,height=600')"
 type="button"></a></form>
            </h3>
            </td>
          </tr>
        </tbody>
</table>
<h3 align="center">
The average bend  per basepair is :  $bend degrees </br>
The average shear per basepair is :  $shear nanometers </br>
The combined score for this sequence is:  $score </br>
</br>
NOTE: you have complete control over the rotating display. Really click it  ! </br>
Google: Jmol for tutorials.
</h3>


</div>
</div>
</body>
</html>
END;
}
################################################################################################################################################################################
function jmol_html() {
global $sesspath, $SID;
$simplehtml = "$sesspath$SID/simple.html";
$allatomhtml = "$sesspath$SID/allatom.html";

$string2 = 
<<<END
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <script src="https://dna.engr.latech.edu/freedna/jmol/jsmol/js/JSmol.js"
 type="text/javascript">
  </script>
  <meta content="text/html; charset=ISO-8859-1"
 http-equiv="content-type">
  <title>Bishop Lab -</title>
</head>
<body>
        <script>
jmolInitialize("/freedna/jmol/jsmol/js/"); // REQUIRED
jmolApplet(500, value = "load https://dna.engr.latech.edu/freedna/sessions/$SID/dna.pdb; spin on");
jmolBr(); // a button
jmolButton("reset", "Reset to original orientation");
            </script>
</body>
</html>
END;
$fp2 = fopen($allatomhtml, 'w+');
	{fwrite($fp2, $string2 );}
       fclose($fp2);

$string1 = 
<<<END
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <script src="https://dna.engr.latech.edu/freedna/jmol/jsmol/js/JSmol.js"
 type="text/javascript">
  </script>
  <meta content="text/html; charset=ISO-8859-1"
 http-equiv="content-type">
  <title>Bishop Lab -</title>
</head>
<body>
<script>
jmolInitialize("/freedna/jmol/jsmol/js/"); // REQUIRED
jmolApplet(500, value = "load https://dna.engr.latech.edu/freedna/sessions/$SID/eq.out.xyz; select elemno=20; spacefill; spin on");
jmolBr(); // a button
jmolButton("reset", "Reset to original orientation");
            </script>
</body>
</html>
END;
$fp1 = fopen($simplehtml, 'w+');
	{fwrite($fp1, $string1 );}
       fclose($fp1);

}

########################################################################################
##CALL FUNCTIONS AS NEEDED
function conditionsmet(){
global $numnuc, $progDIR, $sesspath, $SID;
exec("cd $sesspath$SID ; cat $sesspath$SID/confin.txt | /usr/local/src/ICM/bin/eq-conf");
exec("cd $sesspath$SID ; $progDIR/make-xyz-from-par.tcsh ");
exec("cd $sesspath$SID; $progDIR/curvature.tcsh  $sesspath$SID/eq.out.par > $sesspath$SID/curv.dat " );
print_output();
jmol_html();
}

counter();

if (isset($_POST['stage']) && ('process' == $_POST['stage'])) { 
 if (empty($errors)) {
makeconfig();
     if ($reqtypenss == 1)      { 
        pc_validate_nss();
        if(($validseq = TRUE) && ($validnss = TRUE)){
           echo "Here is my attempt at running the program with NSS specified.  Anything you can see? <p><p><p><p>";
      }
        elseif(($validseq = FALSE) || ($validnss = FALSE))  {printform();}
      }
     elseif ($reqtypenss == 0){
	if (TRUE == $validseq)  {conditionsmet();}
        elseif (FALSE == $validseq)  {print_form();}
     }
}
else {print_form();}
}
else {print_form();
}
?>
