#!/usr/bin/perl
package sdevTwoPointUserPage;

#######################################################################
##### Author :	Shuai Weng
##### Date   :  March 2001
##### Description : This package contains all necessary methods for 
#####               displaying two_point data to user. 
#####              
#######################################################################
use strict;
use DBI;
use CGI qw/:all/;
use CGI::Carp qw(fatalsToBrowser);

use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase/Objects";
use ConfigURLdictyBase;
use ConfigPathdictyBase;
use Two_point;
use Reference;
use Locus;

use lib "/usr/local/dicty/www_dictybase/db/lib/common";
use Login qw (ConnectToDatabase);
use TextUtil qw (DeleteUnwantedChar);
use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase";
use dictyBaseCentralMod qw(:formatPage);
use dictyBaseObject;


#######################################################################
#################### global variables #################################
#######################################################################

my $dbh;
my $dblink; 
my $downloadfile;
my $downloadUrl;
my $configUrl;

#######################################################################
sub new {      ############ constructor ###############################
#######################################################################
       
	my ($self, %args) = @_;

	$self = {};
	bless $self;

      	$self->{'_database'} = $args{'database'};
	$self->{'_gene'}     = $args{'gene'};
	$self->{'_ACEname'} = $args{'ACEname'};
	$self->{'_twoPointNm'}     = $args{'twoPointNm'};
    	return $self;
}

sub help { $_[0]->{_help} }
sub database { $_[0]->{_database} }
sub title { $_[0]->{_title} }
sub gene { $_[0]->{_gene} }

######################################################################
sub DESTROY {   ############ destructor ##############################
######################################################################
    	if (defined $dbh) {
		$dbh->disconnect;
    	}
}

######################################################################
sub start{
######################################################################

    	my ($self) = @_;
	$configUrl = ConfigURLdictyBase->new;
	$dblink = $configUrl->dblink($self->database);
	$self->setDownloadfile;
	my $gene = $self->{'_gene'};
	&DeleteUnwantedChar(\$gene);
	$self->{'_gene'} = $gene;
	if (!$self->{'_gene'} && !$self->{'_twoPointNm'} 
	    &&!$self->{'_ACEname'}) {
	    $self->{'_title'} = "Genetic Mapping Data Search";
	    $self->printEntryForm;
	    exit;
	}
	if ($self->gene) {
	    my $dictyBase = dictyBaseObject->new(database=>$self->database,
				     query=>$self->gene);
	    if ($dictyBase->locusName) { 
		$self->{'_gene'} = $dictyBase->locusName;
		$self->{'_locusNo'} = $dictyBase->locusNo;
	    }
	    elsif ($dictyBase->featureName){
		 $self->err_report("There is no gene name associated with	 ".$self->gene.".");
		 exit;
	    }
	    else {
	         $self->err_report("The locus/feature you entered is not found in database. Please correct it and try again.");
		 exit;
	    }
        }
	$dbh = &ConnectToDatabase($self->database);
	if ($self->gene) {
	    $self->{'_title'} = "Genetic Mapping Data ".$self->gene;
	    $self->{'_help'} = "allexpthelp.html";
	    $self->displayAllExpt;
	}
	else {
	    if ($self->{'_twoPointNm'}) {
		 $self->{'_title'} = "Tetrad Data for ".$self->{'_twoPointNm'};
	    }
	    else {
		 $self->{'_title'} = "Tetrad Data for ".$self->{'_ACEname'};
	    }
	    $self->{'_help'} = "tetradhelp.html";
	    $self->displayDetails;
	}
	exit;
}

#######################################################################
sub printEntryForm {
#######################################################################
        my ($self) = shift;

	&printStartPage($self->database, $self->title, $self->help);

	print center(table({-border=>3,
                        -cellpadding=>4,
                        -cellspacing=>4},
                       
                       Tr({-align=>'LEFT'},
                          [
                           td({-bgcolor=>"#b7d8e4",
                               -width=>350},
                              table({-border=>0},
                                    Tr({align=>'LEFT'},
                                       [
                                        td(start_form,
                                           "Enter locus name : ").
                                        td(textfield(-name=>'locus',
                                                     -size=>'15')),
                                        td("&nbsp;").td(submit, reset, end_form)
                                        ]))
                              )
                           ])));

	&printEndPage;
}


########################################################################
sub displayAllExpt {
########################################################################
    my ($self) = @_;
    &printStartPage($self->database, $self->title, $self->help);

    my $locusObj = Locus->new(dbh=>$dbh,
			      locus_no=>$self->{'_locusNo'});

    my $found;
    my (%count, %distanceSum, %twoPointNo);
    my $twoPointNm;

    foreach my $rowRef (@{$locusObj->twoPointInfoArrayRef}) {
	my ($two_point_no, $two_point_name, $distance) = @$rowRef;
	if ($two_point_name =~ /^([^\-]+\-[^\-]+)\-[0-9]+/) {
	    $found++;
	    $twoPointNm = $1;
	    $count{$twoPointNm}++;
	    $distanceSum{$twoPointNm} += $distance;
	    $twoPointNo{$twoPointNm} = $two_point_no;
	}
    }
    if (!$found) {
	print "No genetic mapping data was found for ".$self->gene." Please check the gene name and try again.";
        &printEndPage;
        exit;
    }
    $self->{'_gene'} = lc ($self->{'_gene'});
    $self->topLink4allExpt;

    print p, "This table summarizes the available genetic mapping data for a particular gene in dictyBase.  Click on the gene names in the ".b("Locus")." columns to go to a gene's locus page.  Click on the number listed in the ".b("# of Experiments")." column to retrieve detailed data from the crosses between each set of markers in a particular row.  See the ".a({-href=>$configUrl->breadServerRoot."Dictyostelium/help/allexpthelp.html"}, "Help")." for more information. ", p;

    my $rows;
    open(XLS, ">$downloadfile") || 
	die "Can't open '$downloadfile' for writing:$!\n";
    print XLS "Locus \#1\tLocus \#2\t\# of Experiments\tAverage Distance\tGenetic Map Distance\n";
    my ($exptNum, $aveDistance, $locus1, $locus2, $geneticMapDist);
    my ($stdNm1, $stdNm2);
    my $bgcolor= "white";
    foreach $twoPointNm (sort(keys %count)) {
	$exptNum = $count{$twoPointNm};
	$aveDistance = $distanceSum{$twoPointNm}/$exptNum;
	if ($aveDistance =~ /^([0-9]+\.[0-9])/) {
	    $aveDistance = $1;
	}
	my $two_point_no = $twoPointNo{$twoPointNm};
	my ($THISlocus1, $THISlocus2) = 
	    $self->getLociBYtwoPointNo($two_point_no);
	($locus1, $locus2) = split(/-/, $twoPointNm);
	$locus1 = uc $locus1;
	$locus2 = uc $locus2;
        if ($locus1 eq $THISlocus1) {
	    $locus2 = $THISlocus2;
        }
	elsif ($locus1 eq $THISlocus2) {
	    $locus2 = $THISlocus1;
	}
	elsif ($locus2 eq $THISlocus1) {
	    $locus1 = $THISlocus2;
	}
	elsif ($locus2 eq $THISlocus2) {
	    $locus1 = $THISlocus1;
	}
	else {
	    ($locus1, $locus2) = ($THISlocus1, $THISlocus2);
	}
	$stdNm1 = $locus1;
	$stdNm2 = $locus2;
	my $cm1 = $self->getCmBYlocus($stdNm1);
	my $cm2 = $self->getCmBYlocus($stdNm2);
	if ($cm1 =~ /^not found/i || $cm2 =~ /^not found/i) {
	    next;
	}
	if ($cm1 ne '' && $cm2 ne '') {
	    $geneticMapDist = $cm2 - $cm1;
	}
	else {
	    $geneticMapDist = "unknown";
	}	
	$geneticMapDist =~ s/^-(.+)$/$1/;
	if ( $geneticMapDist =~ /^(.+\.[0-9]{2})([0-9])/) {
	    $geneticMapDist = $1;
	    my $tail = $2;
	    if ($tail >= 5) {
		$geneticMapDist += 0.01;
	    }
	}
	$locus1 = lc $locus1;
	$locus2 = lc $locus2;
	$rows .= Tr({-bgcolor=>"$bgcolor"},
		      td({-width=>'20%',
			  -align=>'center'},
			 font({-size=>'-1'},
			      a({-href=>$configUrl->dictyBaseCGIRoot."gene_page.pl?gene_name=$stdNm1"},
				$locus1))).
		      td({-width=>'20%',
			  -align=>'center'},
			 font({-size=>'-1'},
			   a({-href=>$configUrl->dictyBaseCGIRoot."gene_page.pl?gene_name=$stdNm2"},
			   $locus2))).
		      td({-width=>'20%',
			  -align=>'center'},
			 font({-size=>'-1'},
			      a({-href=>url."?twoPointNm=$twoPointNm"},
				$exptNum))).
		      td({-width=>'20%',
			  -align=>'center'},
			 font({-size=>'-1'}, 
			      $aveDistance)).
		      td({-width=>'20%',
			  -align=>'center'},
			 font({-size=>'-1'}, 
			      $geneticMapDist)));
	     
	if ($bgcolor eq "white") { $bgcolor = "#d8d8d8"; }
	else { $bgcolor = "white"; }
        print XLS "${locus1}\t${locus2}\t${exptNum}\t${aveDistance}\t${geneticMapDist}\n";
    }
    print table({-align=>'center',
		 -border=>'0',
		 -cellpadding=>'2',
		 -cellspacing=>'3' 
		 -width=>'590'},
		Tr(td({-width=>'15%', 
		       -bgcolor=>'#a4abc2',
		       -align=>'center'},
		      "Locus \#1").
		   td({-width=>'15%', 
		       -bgcolor=>'#a4abc2',
		       -align=>'center'},
		      "Locus \#2").
		   td({-width=>'15%', 
		       -bgcolor=>'#a4abc2',
		       -align=>'center'},
		      "\# of Experiments").	
		   td({-width=>'15%', 
		       -bgcolor=>'#a4abc2',
		       -align=>'center'},
		      "Average Distance").	
		   td({-width=>'15%', 
		       -bgcolor=>'#a4abc2',
		       -align=>'center'},
		      "Genetic Map Distance")).
		   $rows),p;
		 

    close(XLS);
    &printEndPage;
}

########################################################################
sub displayDetails {
########################################################################
    my ($self) = @_;

    my $twoPointNm;
    if ($self->{'_twoPointNm'}) {
	$twoPointNm = $self->{'_twoPointNm'}.'-%';
    }
    else {
	$twoPointNm = $self->{'_ACEname'};
    }

    open(XLS, ">$downloadfile") 
	    || die "Can't open '$downloadfile' for writing:$!\n";
    my ($rownum, $refNum, %REFnum, $thisRefNum, $notes);
#    my $sth2 = $dbh->prepare("
#        SELECT R.reference_no, R.citation, R.year
#        FROM   CGM_DDB.reference R, CGM_DDB.reflink RL
 #       WHERE  RL.tab_name = 'TWO_POINT'
#        AND    RL.primary_key = ?
#        AND    RL.reference_no = R.reference_no
#        ORDER BY R.year
#    ");
    my $bgcolor = "white";
    my $rows;
    my $type;
    my $twoPointNo;

    my $arrayRef = Two_point->GetTwoPointInfoArrayRefBYname(dbh=>$dbh,
					     twoPointNm=>$twoPointNm);
    foreach my $rowRef (@$arrayRef) {

	my ($two_point_no, $two_point_name, $parental_ditype, 
	    $nonparental_ditype, $tetratype, $first_division, 
	    $second_division, $distance, $std_err, $interference, 
	    $interference_std_err, $remark) = @$rowRef;

	$rownum++;
	$twoPointNo = $two_point_no;
	if (!$distance) { $distance = br;}
	if (!$std_err) { $std_err = br;} 
	if (!$interference) { $interference = br;}
	if (!$interference_std_err) { $interference_std_err = br;}
	# $sth2->execute($two_point_no);
	my $noteNums;
	# while(my ($refNo, $citation, $year) = $sth2->fetchrow()) {

	my $twoPtObj = Two_point->new(dbh=>$dbh,
				      two_point_no=>$two_point_no);
	foreach my $paperRowRef (@{$twoPtObj->getReferenceInfo4twoPoint}) {
	    my ($refNo, $citation, $year) = @$paperRowRef;
	    my $refObj = Reference->new(dbh=>$dbh,
					reference_no=>$refNo);
	    $citation = $refObj->formatedCitation;
	    if (!$REFnum{$citation}) {
		$refNum++;
		$REFnum{$citation} = $refNum;
		$notes = p."<a name=\"ref${refNum}\">\(${refNum}\) ".$citation;
	    }
	    $thisRefNum = $REFnum{$citation};
	    $noteNums .= ", ".a({-href=>"#ref${thisRefNum}"}, $thisRefNum);
        }
        if ($remark) {
	    if (!$REFnum{$remark}) {
		$refNum++;
		$REFnum{$remark} = $refNum;
		$notes = p."<a name=\"ref${refNum}\">\(${refNum}\) $remark";
	    }
	    $thisRefNum = $REFnum{$remark};
            $noteNums .= ", ".a({-href=>"#ref${thisRefNum}"}, $thisRefNum);
	}
        $noteNums =~ s/^\, //;
        if (!$noteNums) { $noteNums = br; }
        if ($rownum == 1) {
	    if ($parental_ditype || $nonparental_ditype) {
		$type = "Tetrad";
		$rows = Tr($self->headerCell("Cross").
			   $self->headerCell("Parental Ditype").
			   $self->headerCell("Nonparental Ditype").
			   $self->headerCell("Tetratype").
			   $self->headerCell("Distance").
			   $self->headerCell("Distance Standard Error").
			   $self->headerCell("Interference").
			   $self->headerCell("Interference Standard Error").
			   $self->headerCell("Notes/References"));
		print XLS "Cross\tParental Ditype\tNonparental Ditype\tTetratype\tDistance\tDistance Standard Error\tInterference\tInterference Standard Error\tNotes/References\n";
	    }
	    else {
		$type = "Centromere Segregation";
		$rows = Tr($self->headerCell("Cross").
			   $self->headerCell("First Division").
			   $self->headerCell("Second Division").
			   $self->headerCell("Distance").
			   $self->headerCell("Distance Standard Error").
			   $self->headerCell("Interference").
			   $self->headerCell("Interference Standard Error").
			   $self->headerCell("Notes/References"));    
		print XLS "Cross\tFirst Division\tSecond Division\tDistance\tDistance Standard Error\tInterference\tInterference Standard Error\tNotes/References\n";
	    }
        }
        $two_point_name =~ s/^(.+)-[0-9]+$/$1/;
        my $row = $self->contentCell($two_point_name);
        print XLS "$two_point_name\t";
        if ($type eq "Tetrad") {
	    $row .= $self->contentCell($parental_ditype).
		    $self->contentCell($nonparental_ditype).
		    $self->contentCell($tetratype);
	    print XLS "${parental_ditype}\t${nonparental_ditype}\t${tetratype}\t";   	       
        }
        else {
	    $row .= $self->contentCell($first_division).
		    $self->contentCell($second_division);
	    print XLS "${first_division}\t${second_division}\t";
        }
        $row .= $self->contentCell($distance).
	        $self->contentCell($std_err).
		$self->contentCell($interference).
		$self->contentCell($interference_std_err).
		$self->contentCell($noteNums);
        print XLS "${distance}\t${std_err}\t${interference}\t${interference_std_err}\t${noteNums}\n";
        $rows .= Tr({-bgcolor=>"$bgcolor"}, $row);
        if ($bgcolor eq "white") { $bgcolor = "#d8d8d8"; }
    }
    close(XLS);
    if ($type eq "Tetrad") {
	$self->{'_help'} = "tetradhelp.html";
    }
    else {
	$self->{'_help'} = "segregationhelp.html";
    }
    $twoPointNm =~ s/\-\%$//;
    $self->{'_title'} = $type ." Data for " . $twoPointNm;
    &printStartPage($self->database, $self->title, $self->help);
    my ($locus1, $locus2) = split(/-/, $twoPointNm);
    my ($THISlocus1, $THISlocus2) = $self->getLociBYtwoPointNo($twoPointNo);
    uc $locus1;
    uc $locus2;
    if ($locus1 eq $THISlocus1) {
	$locus2 = $THISlocus2;
    }
    elsif ($locus1 eq $THISlocus2) {
	$locus2 = $THISlocus1;
    }
    elsif ($locus2 eq $THISlocus1) {
	$locus1 = $THISlocus2;
    }
    elsif ($locus2 eq $THISlocus2) {
	$locus1 = $THISlocus1;
    }
    else {
	($locus1, $locus2) = ($THISlocus1, $THISlocus2);
    }
    my $stdNm1 = $locus1;
    my $stdNm2 = $locus2;
    $self->printDetailTop($locus1, $locus2);
    print table({-align=>'center',
		 -border=>'0',
		 -cellpadding=>'2',
		 -cellspacing=>'3',
		 -width=>'100%'},
		Tr(td({-align=>'center'},
		      font({-size=>'+1'},b($type)))));
    
    print table({-align=>'center',
		 -border=>'0',
		 -cellpadding=>'2',
		 -cellspacing=>'3',
		 -width=>'100%'},
		$rows),p;
    my $note = $self->getNotes($locus1, $locus2);
    if ($note) {
	$self->printSubtitle("Locus Notes");
	print $note;
    }
    if ($notes) {
	$self->printSubtitle("Notes/References");
	print "$notes<p>";
    }
    
    &printEndPage;
}

########################################################################
sub printSubtitle {
########################################################################
    my ($self, $subtitle) = @_;
    print table({-align=>'center',
		 -border=>'0',
		 -cellpadding=>'2',
		 -cellspacing=>'3',
		 -width=>'100%'},
		Tr(td({-width=>'100%',
		       -bgcolor=>'#b7d8e4'},
		      font({-size=>'-1'}, $subtitle)))),p;
}


########################################################################
sub printDetailTop {
########################################################################
    my ($self, $locus1, $locus2) = @_;
    print table({-align=>'center',
	         -border=>'0',
		 -cellpadding=>'2',
		 -cellspacing=>'3',
		 -width=>'650'},
		Tr(td({-width=>'40%',
		       -bgcolor=>'#b7d8e4',
		       -align=>'center'},
		      $self->locusLinkCell($locus1)).
		   td({-width=>'40%',
		       -bgcolor=>'#b7d8e4',
		       -align=>'center'},
		      $self->locusLinkCell($locus2)).
		   td({-width=>'20%',
		       -bgcolor=>'#b7d8e4',
		       -align=>'center'},
		      a({-href=>"$downloadUrl"},
			"Download Data"))));
}

########################################################################
sub locusLinkCell {
########################################################################
    my ($self, $locus) = @_;
    $locus = "\L$locus";
    return table({-border=>'0',
		  -cellpadding=>'0',
		  -cellspacing=>'9'},
		 Tr(td(b($locus)).
		    td(a({-href=>$configUrl->dictyBaseCGIRoot."gene_page.pl?gene_name=$locus"},
			 font({-size=>'-1'},
			      "Locus Info"))).
		    td(a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/PGMAP/PGmap?seq=$locus"},
			 font({-size=>'-1'},
			      "Map"))).
		    td(a({-href=>url."?gene=$locus"},
			 font({-size=>'-1'},
			 "Mapping Data")))		
		    ));

}

########################################################################
sub topLink4allExpt {
########################################################################
    my ($self) = @_;
    print table({-align=>'center',
		 -border=>'0',
		 -cellpadding=>'2',
		 -cellspacing=>'3' 
		 -width=>'500'},
		Tr(td({-width=>'15%', 
		       -bgcolor=>'#b7d8e4',
		       -align=>'center'},
		      a({-href=>$configUrl->DictyosteliumServerRoot.'cgi-bin/blast.pl/dictyBase/seqTools?seqname='.$self->gene},
			font({-size=>'-1'}, 
			     $self->gene." Gene/Seq Resources"))).
		   td({-width=>'15%', 
		       -bgcolor=>'#b7d8e4',
		       -align=>'center'},
		      a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/PGMAP/PGmap?seq=".$self->gene},
			font({-size=>'-1'}, 
			     $self->gene." Physical/Genetic Map"))).
		   td({-width=>'15%', 
		       -bgcolor=>'#b7d8e4',
		       -align=>'center'},
		      a({-href=>"$downloadUrl"},
			font({-size=>'-1'}, 
			     "Download Data"))) 		   
		   ));

}

#######################################################################
sub headerCell {
#######################################################################
    my ($self, $text) = @_;
    return td({-width=>'10%',
	       -bgcolor=>'#a4abc2',
	       -align=>'center'},
	       font({-size=>'-1'},
		    $text));

}

#######################################################################
sub contentCell {
#######################################################################
    my ($self, $text) = @_;
    return td({-width=>'10%',
	       -align=>'center'},
	       font({-size=>'-1'},
		    $text));

}


#######################################################################
sub getLociBYtwoPointNo {
#######################################################################
    my ($self, $twoPointNo) = @_;
    my $twoPtObj = Two_point->new(dbh=>$dbh,
				  two_point_no=>$twoPointNo);
    my $lociRef = $twoPtObj->getLoci;
    return @$lociRef;
}

#######################################################################
sub getNotes {
#######################################################################
    my ($self, $locus1, $locus2) = @_;
    my $notes = Two_point->GetNotesBYloci(dbh=>$dbh,
					  locus1=>$locus1,
					  locus2=>$locus2);
    return $notes;
}

#######################################################################
sub getCmBYlocus {
#######################################################################
    my ($self, $locus) = @_;
    if (!$locus) { return "not found"; }
    my $locusObj = Locus->new(dbh=>$dbh,
			      locus_name=>$locus);
    if ($locusObj) {
	return $locusObj->genetic_position;
    }
    else {
	return "not found";
    }
}

########################################################################
sub setDownloadfile {
########################################################################
    my ($self) = @_;
    
    my $configPath = ConfigPathdictyBase->new;
    
    $downloadfile = $configPath->tmpDir."twopoint.$$.xls";
    $downloadUrl = $configUrl->dictyBaseHtmlTmp."twopoint.$$.xls";
}

########################################################################
sub err_report {
########################################################################
    my ($self, $err) = @_;

    &printStartPage($self->database, $self->title, $self->help);
   
    print b($err);
    
    &printEndPage;

    $dbh->disconnect;
    exit;
}


########################################################################
1; #####################################################################
########################################################################



















