#!/usr/bin/perl

######################################################
# STAINFINDER PROGRAM
# Author : Wijan Prapong 
#
# This program takes input from a TreeView file and 
# allows users to view various stains simultaneously
######################################################

use strict;
use CGI qw/:standard/;
use CGI::Carp qw (fatalsToBrowser);

$|=1;

my $query = new CGI;

# The $rootDir, $webDir, and $mainDir variables are used to allow 
# easy updates if the scans should ever move to a different location

my $rootDir = '/share/tissue/archive/';
my $webDir = '/scans/Composites/';
my $mainDir = '/share/tissue/archive/scans/Composites/';
my %jpgAndAbHash;

my $submit = $query->param('Display checked images');
my $submit2 = $query->param('Reset to default');
my $submit3 = $query->param('Clear all checkboxes');

my @imageSize = (1504,1440); #default image size of Bliss jpgs
my $resizeFactor = $query->param('resizeFactor');
my $screenSize = $query->param('screenSize');
my @cookieValue = ($resizeFactor, $screenSize); 
my @cookieParams = $query->cookie('cookieParams');
my @cookieAntibodies = $query->cookie('cookieAntibodies');
my @defaultParams = @cookieParams || ('12.5%','1024x768');

my $uniqID = $query->param('uniqid') || die "A uniqid must be passed into the Stain Finder.  Check your Tree View settings.\n";

my @cdtAntibodies = split("!",$uniqID);
my $jpgName = shift(@cdtAntibodies);
$jpgName =~ s/.jpg//g;
my $fpNum = shift(@cdtAntibodies);
my ($fpFile, @fpVars, @paraffinFile);

#--Read paraffin file data exported from FileMaker Pro--#
opendir (DIR, "$mainDir") || die "Cannot open directory $mainDir: $!\n";
@paraffinFile = grep /par_block/, readdir(DIR);
closedir (DIR);

if (@paraffinFile && $fpNum){
    open(FILE, "$mainDir"."@paraffinFile") || die "can't open file: $!";
    while (<FILE>){
	@fpVars = split("\t", $_); #expects tab delimited file
	$fpFile = shift(@fpVars);
	if ($fpFile == $fpNum){
	    $fpFile = join (" | ", @fpVars);
	    last;
	    close FILE;
	}else{
	    $fpFile = "";
	}
   }
    close FILE;
}


my (@allAntibodyNames, @goodAntibodyNames, @badAntibodyNames);

my @jpgParts = split ("_", $jpgName);
my $sector = $jpgParts[0];
my $tissueArray = $jpgParts[1];
my $column = $jpgParts[2];
my $row = $jpgParts[3];

#--These variables are not actually used by the program--#
# my $slice = $jpgParts[4];
# my $blissCode = $jpgParts[5];
# my $scannerPos = $jpgParts[6];


@allAntibodyNames = &GetAntibodyNamesFromDirectories;
if(@cookieAntibodies){
    @cdtAntibodies = @cookieAntibodies;
}
&CheckAntibodyNames;

my @antibodyChoices = $query->param('antibodyChoices');
@antibodyChoices = sort(@antibodyChoices);


#---------------------Cookie Setup----------------------#
my $setCookie1 = $query->param('setCookie1');
my $deleteCookie1 = $query->param('deleteCookie1');
my $setCookie2 = $query->param('setCookie2');
my $deleteCookie2 = $query->param('deleteCookie2');

my ($cookie1, $cookie2);
if ($setCookie1){ # set cookie if box is checked 
    $cookie1 = $query->cookie(-name=>'cookieParams',
			      -value=>\@cookieValue,
			      -expires=>'+10y'); 
}elsif($deleteCookie1){ 
    $cookie1 = $query->cookie(-name=>'cookieParams',
			      -value=>\@cookieParams,
			      -expires=>'-10y');
    $query->param(-name=>'resizeFactor',
		  -value=>'12.5%');
    $query->param(-name=>'screenSize',
		  -value=>'1024x768');
}

if ($setCookie2){ # set cookie if box is checked 
    $cookie2 = $query->cookie(-name=>'cookieAntibodies',
			      -value=>\@antibodyChoices,
			      -expires=>'+10y'); 
}elsif($deleteCookie2){ 
    $cookie2 = $query->cookie(-name=>'cookieAntibodies',
			      -value=>\@cookieAntibodies,
			      -expires=>'-10y'); 
}

if (($setCookie1 || $deleteCookie1) && ($setCookie2 || $deleteCookie2)){
    print $query->header(-cookie=>[$cookie1, $cookie2]);
}elsif($setCookie1 || $deleteCookie1){
    print $query->header(-cookie=>$cookie1);
}elsif($setCookie2 || $deleteCookie2){
    print $query->header(-cookie=>$cookie2);
}else{
    print $query->header;
}

print $query->start_html("Stain Finder");

#---------------------Form Setup----------------------#
print $query->start_form();    
print "Display initial images at ";
print $query->popup_menu(-name=>'resizeFactor',
			 -value=>['12.5%', '25%', '50%', '100%'],
                         -default=>$defaultParams[0]);
print "of their original size<br>";

print "Monitor resolution of your computer ";
print $query->popup_menu(-name=>'screenSize',
			 -value=>['640x480',
				  '800x600',
				  '1024x768',
				  '1280x1024',
				  '1600x1024'],
			 -default=>$defaultParams[1]);

print br;
if (!@cookieParams){ # parameter cookie does not exist
    if ($setCookie1){
	print font({-color=>'red'},
		   "A cookie has been set on your computer with
                    the default settings of images at $resizeFactor 
                    and a screen size of $screenSize");
    }else{
	print $query->checkbox(-name=>'setCookie1',
			       -label=>'Save these settings as the default 
                                        on this computer (a cookie will be
                                        set on your computer)');
    }
}else{
    if ($deleteCookie1){
	print font({-color=>'red'},
		   "All cookies have been removed from your computer 
                    and the default settings have been returned to 12.5% 
                    and a screen size of 1024x768");
    }else{
	print $query->checkbox(-name=>'deleteCookie1',
			       -label=>'Remove saved settings from this
                                        computer (Return to defaults of
                                        12.5% and 1024x768)');
    }
}

print br, hr;

$resizeFactor =~ tr/%//d;
my $imageWidth = $imageSize[0] * ($resizeFactor / 100);
my $imageHeight = $imageSize[1] * ($resizeFactor / 100);
$screenSize = substr($screenSize, 0,  index($screenSize, "x"));

print "Show stains from the following antibodies:<br>";
if($submit2){
    print $query->checkbox_group(-name=>'antibodyChoices',
				 -values=>\@allAntibodyNames,
				 -default=>\@goodAntibodyNames,
				 -override=>1,
				 -columns=>4);
}elsif($submit3){
    @goodAntibodyNames=();
    print $query->checkbox_group(-name=>'antibodyChoices',
				 -values=>\@allAntibodyNames,
				 -default=>\@goodAntibodyNames,
				 -override=>1,
				 -columns=>4);
}else{
    if(@cookieAntibodies){
	print $query->checkbox_group(-name=>'antibodyChoices',
				     -values=>\@allAntibodyNames,
				     -default=>\@cookieAntibodies,
				     -override=>1,
				     -columns=>4);
    }else{
	print $query->checkbox_group(-name=>'antibodyChoices',
				     -values=>\@allAntibodyNames,
				     -default=>\@goodAntibodyNames,
				     -columns=>4);	
    }
}

print br;
print $query->hidden(-name=>'uniqid',
		     -value=>$uniqID);

if (!@cookieAntibodies){ # cookie does not exist
    if ($setCookie2){
	print font({-color=>'red'},
		   "A cookie has been set on your computer.  
                    All subsequent displays will default to 
                    the antibodies currently chosen."
		   );
    }else{
	print $query->checkbox(-name=>'setCookie2',
			       -label=>'Save these antibodies as the 
                                        default choices on this computer
                                        (a cookie will be set on your
                                         computer)'
			       );
    }
}else{
    if ($deleteCookie2){
	print font({-color=>'red'},
		   "The cookie with the default antibody choices has 
                    been removed from your computer.");
    }else{
	print $query->checkbox(-name=>'deleteCookie2',
			       -label=>'Remove saved antibody choices from 
                                        this computer (Use antibodies passed
                                        in from the CDT file);');
    }
}

print br;
print $query->submit(-name=>'Display checked images');
print "&nbsp";
print $query->submit(-name=>'Reset to default');
print "&nbsp";
print $query->submit(-name=>'Clear all checkboxes');


if (@badAntibodyNames){
    my $displayBadNames = join("; ", @badAntibodyNames);
    print br, br;
    print font({-color=>'red'},
	       b('NOTE:').'The following antibodies from the CDT file are 
                           not checked because there were no matching 
                           directories available:'
	       .br
	       .b($displayBadNames)
	       .br);
}

print $query->end_form;

my (@jpgsWithFullPath);
if ($submit){
    &GetFullJpgName(\%jpgAndAbHash);
    &CreateTable;
}
print $query->end_html;

#################################################
sub GetAntibodyNamesFromDirectories{
#################################################
# This subroutine checks for directories that match the same sector and
# tissue array as the uniqid that is passed in.  It returns the names of
# all the valid antibodies as determined from the directory structure.

    my (@availableABs, @dirTemp, $dirRegExp, $tmpHolder);

    $dirRegExp = "C-TA-0*$tissueArray-0*$sector.";
    opendir (DIR, "$mainDir") || die "Cannot open directory $mainDir: $!\n";
    @dirTemp = grep /$dirRegExp/, readdir(DIR);
    closedir (DIR);

    foreach (@dirTemp){
	$tmpHolder = substr($_, rindex($_, ".")+1);
	push (@availableABs, substr($_, rindex($_, ".")+1));
	$_ = "$webDir"."$_";
	$jpgAndAbHash{substr($_, rindex($_, ".")+1)} = $_;
    }

    @availableABs = sort keys (%jpgAndAbHash);
    return @availableABs;

}

#################################################
sub CheckAntibodyNames{
#################################################
# This subroutine is called when antibodies are passed in from the CDT 
# file. It checks the CDT antibody names against the antibody names from
# the directory structure, and splits the CDT antibodies into two arrays 
# of good names and bad names.

    foreach (@cdtAntibodies){ # strip anything that comes after a parentheses
	if(index($_, "(") != -1){
	    $_ = substr($_, 0,  index($_, "("));
	}
    }

    foreach (@cdtAntibodies) {
	if($jpgAndAbHash{$_}) {
	    push(@goodAntibodyNames, $_);
	}else{
	    push(@badAntibodyNames, $_);
	}
    }

}

#################################################
sub GetFullJpgName{
#################################################
# This subroutine takes the chosen antibodies and appends the jpg name 
# to the directory value of the corresponding hash pairs

    my (@directories, $tmpHolder, @jpgTemp, $jpgRegExp);
    $jpgRegExp = "$sector"."_"."$tissueArray"."_"."$column"."_"."$row"."_";
    foreach (@antibodyChoices){
	$tmpHolder = $jpgAndAbHash{$_};
	push (@directories, $jpgAndAbHash{$_});
	opendir (JPG, "$rootDir"."$tmpHolder") || die "Cannot open directory $tmpHolder $!\n";
	@jpgTemp = grep /$jpgRegExp/, readdir(JPG);
	closedir (JPG);
	if (@jpgTemp){
	    $jpgAndAbHash{$_} = "$tmpHolder"."/"."@jpgTemp";
	}else{
	    $jpgAndAbHash{$_} = "No image found";
	}
    }
}
    
#################################################
sub CreateTable{
#################################################
# This subroutine takes the jpg names and creates a table in
# HTML for browser display
    
    if($fpNum){	
        print br,b("Slides from FP#$fpNum $fpFile");
    }

    my (@rows, $row);	
    my $numImagesPerRow = int($screenSize/$imageWidth);
    $numImagesPerRow = 1 if ($numImagesPerRow < 1);

    my $numRows = int(@antibodyChoices/$numImagesPerRow)+1;

    my $i = 0; #number of stains displayed
    my $j = 0; #number of row elements displayed

    while($i < @antibodyChoices){
	$row .= td(&MakeOneStainTable($antibodyChoices[$i]));
	$j++;
	if ($j == $numImagesPerRow){
	    push(@rows, $row);
	    $j = 0;
	    $row = undef;
	}
	$i++;
    }

    #--this section unneeded if filler cells not desired--#
    my $numFillerCells;
    if ($numRows > 1 && @antibodyChoices%$numImagesPerRow){
	$numFillerCells = $numImagesPerRow-(@antibodyChoices%$numImagesPerRow);
    }
    while($numFillerCells > 0){ #if filler cells needed
	$row .= td({-bgcolor=>'silver'},'&nbsp');
	$numFillerCells--;
	if ($numFillerCells == 0){
	    push(@rows, $row);
	    $row = undef;
	}
    }



    push(@rows, $row) if defined $row;
    print table({-cellpadding=>'0',
		 -border=>3,
		 -bordercolor=>'black'},
		 Tr([@rows])
		 );

}

#################################################
sub MakeOneStainTable{
#################################################
# This subroutine makes a table that contains one individual
# stain (meaning rows containing image, antibody name, and
# other formatting)

    my ($antibodyName) = @_;
    my (@rows);

    push(@rows, td({-bgcolor=>'black'}, '&nbsp' ));
    push(@rows, &GetAbNameCell($antibodyName));
    push(@rows, &GetImageCell($antibodyName));
    push(@rows, td({-bgcolor=>'black'}, '&nbsp' ));

    return table({-border=>1,
		  -bordercolor=>'black'},
		 Tr([@rows])
		 );

}

#################################################
sub GetImageCell{
#################################################
# This subroutine creates a table element containing the image
# or an image not found list if the image is missing

    my ($antibodyName) = @_;
    if ($jpgAndAbHash{$antibodyName} eq "No image found"){
	return td({-align=>'CENTER',
		   -valign=>'MIDDLE',
		   -width=>$imageWidth,
		   -height=>$imageHeight},
		  'No image found'
		  );
    }else{
	return td({-align=>'CENTER'},
		  img {src=>'/tissue'."$jpgAndAbHash{$antibodyName}",
		       width=>$imageWidth,
		       height=>$imageHeight}
		  );
    }

}

#################################################
sub GetAbNameCell{
#################################################
# This subroutine prints the name of the antibody as a clickable
# link within one table data element

    my ($antibodyName) = @_;
    if ($jpgAndAbHash{$antibodyName} eq "No image found"){
	return td({-align=>'CENTER',
		   -bgcolor=>'silver'},
		  b($antibodyName)
		  );
    }else{
	return td({-align=>'CENTER',
		   -bgcolor=>'silver'},
		  a({-href=>'/tissue'."$jpgAndAbHash{$antibodyName}",
		     -target=>'_blank'},
		    b($antibodyName)
		    )
		  );
    }



}


