#!/usr/bin/perl
package FeatureTable_base;

##### Author :	Shuai Weng
##### Date   :  August 2000
##### Description : This is the initial 'try' to create a class to 
#####               display the feature table 
#####               Let's see ...    

#######################################################################
use strict;
use DBI;
use CGI qw/:all/;
use CGI::Carp qw(fatalsToBrowser);
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;
use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase/Objects";
use ConfigURLdictyBase;
use Feature;
use Clone;

#######################################################################
#################### global variables #################################
#######################################################################
our %rom2num = (
		"I"	=>"1",
		"II"	=>"2",
		"III"	=>"3",
		"IV"	=>"4",
		"V"	=>"5",
		"VI"	=>"6",
		"VII"	=>"7",
		"VIII"	=>"8",
		"IX"	=>"9",
		"X"	=>"10",
		"XI"	=>"11",
		"XII"	=>"12",
		"XIII"	=>"13",
		"XIV"	=>"14",
		"XV"	=>"15",
		"XVI"	=>"16",
		"MITO"	=>"17"

);

our %num2rom = (
		"1"=>"I",
		"2"=>"II",
		"3"=>"III",
		"4"=>"IV",
		"5"=>"V",
		"6"=>"VI",
		"7"=>"VII",
		"8"=>"VIII",
		"9"=>"IX",
		"10"=>"X",
		"11"=>"XI",
		"12"=>"XII",
		"13"=>"XIII",
		"14"=>"XIV",
		"15"=>"XV",
		"16"=>"XVI",
		"17"=>"Mito"
);

our $dbh;
our $chrsize;
our $configUrl;
our $dblink;

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

	my $self = {};
	bless $self, $type;

	$self->{'_seq'}    	= $args{'seq'};
    	$self->{'_chr'}     	= $args{'chr'};
	$self->{'_beg'}     	= $args{'beg'};
	$self->{'_end'}     	= $args{'end'};
	$self->{'_help'}     	= $args{'help'};
    	$self->{'_database'} 	= $args{'database'};
	$self->{'_title'} = $args{'title'};
 
	$self->processInfo;
	$dbh = &ConnectToDatabase($self->{'_database'});
	$configUrl = ConfigURLdictyBase->new;
	$dblink = ConfigURLdictyBase->dblink($self->{'_database'});
    	return $self;
}

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

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

#############################################################################
sub print{
#############################################################################
####### print search form, colleague list or colleague page

    	my ($self) = @_;
	if ($self->{'_chr'}) {
		if ($self->{'_chr'} < 1 ||  $self->{'_chr'} > 17 || 
		    $self->{'_chr'} !~ /^[0-9]+$/) {
			my $err = $self->notFoundMsg($self->{'_chr'}, "chromosome");
			$self->err_report($err);
		}
		$self->setBegEnd;
		if ($self->{'_chr'} == 17) {
			$self->{'_subtitle'} = "Mitochondrial features between coordinates $self->{'_beg'} to $self->{'_end'}";
		}
		else {
			$self->{'_subtitle'}= "Chromosome $num2rom{$self->{'_chr'}} features between coordinates $self->{'_beg'} to $self->{'_end'}";
		}
		$self->printFeatureTable;
	}			
	elsif ($self->{'_seq'}) {
		if ($self->{'_seq'} =~ /^[0-9]+$/) {  ### it is a clone
			$self->getChrBegEnd4clone;
			$self->{'_subtitle'}= "Clone $self->{'_seq'} features from coordinates $self->{'_beg'} to $self->{'_end'}";
		}
		else { ### it is an orf or gene or dictyBaseid
			$self->getChrBegEnd4feat;
			$self->{'_subtitle'}= "Features around $self->{'_seq'} on chromosome $num2rom{$self->{'_chr'}}";
		}
		$self->printFeatureTable;
	}
	else {
		$self->err_report("You have to provide chromosome number or sequence name to this program. Please go back and try again."); 
	}
	
}

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

	if ($self->{'_subtitle'} =~ /^Feature/i) {
	    print $self->printSubTitle;
	}
	else {
	    print center(h2($self->{'_subtitle'})), p;
	}
	if (!$self->featureTable) {
	    print $self->noFeaturesMsg;
	}
	else {
	    print $self->featureTable;
	    print $self->bottomLink; 
	}
	####################
	&printEndPage;
}

#######################################################################
sub printSubTitle {
#######################################################################
    my ($self) = shift;
    
    my $miniORFmapUrl = $configUrl->dictyBaseCGIRoot."$dblink/ORFMAP/miniORFmap?seq=$self->{'_seq'}";
    my $ORFmapUrl = $configUrl->dictyBaseCGIRoot."$dblink/ORFMAP/ORFmap?seq=$self->{'_seq'}";
    return 
      	table({-width=>'95%',
	       -border=>0,
	       -cellspacing=>0,
	       -cellpadding=>0},
	      th(h2($self->{'_subtitle'}).br.strong("Spanning a region 5 kb left and 5 kb right".br."\(coordinates $self->{'_beg'} to $self->{'_end'} bp\)")
		    
	         ).
	      th(a({-href=>$ORFmapUrl},
		    img({-src=>$miniORFmapUrl,
			 -border=>0,
			 -alt=>'ORFmap'}))
	      )
	);
}

########################################################################
sub getChromSize {
########################################################################
	my ($self) = @_;
	return Feature->GetChrLength(dbh=>$dbh,
				     chr=>$self->{'_chr'});
}

########################################################################
sub getChrBegEnd4clone {
########################################################################
	my ($self) = shift;
	my ($chr, $beg, $end) = Clone->getChrBegEnd4clone(dbh=>$dbh,
					   clone=>$self->{'_seq'});
	if ($chr && $beg && $end) {
	    ($beg, $end) = ($end, $beg) if ($beg > $end);
	    $self->{'_chr'} = $chr;
	    $self->{'_beg'} = $beg;
	    $self->{'_end'} = $end;
	}
	else {
	    my $err = $self->notFoundMsg($self->{'_seq'}, "sequence");
	    $self->err_report($err);
	}
}

########################################################################
sub getChrBegEnd4feat {
########################################################################
	my ($self) = shift;
	
	my $dictyBase = new dictyBaseObject(database=>$self->database,
			        query=>$self->{'_seq'});
	if ($dictyBase->orf) {
	    if ($self->{'_seq'} ne $dictyBase->orf && 
		$self->{'_seq'} ne $dictyBase->gene) {
		if ($dictyBase->alias =~ /$self->{'_seq'}/i) {
		    $self->{'_seq'} = $dictyBase->gene;
		}
		else {
		    $self->{'_seq'} = $dictyBase->orf;
		}
	    }
	    $self->{'_chr'} = $dictyBase->chr;
	    $self->{'_beg'} = $dictyBase->begCoord - 5000;
	    if ($self->{'_beg'} < 1) {
		 $self->{'_beg'} = 1;
	    }
	    $self->{'_end'} = $dictyBase->endCoord + 5000;
	    if (!$chrsize) { 
		 $chrsize = $self->getChromSize;
	    }
	    if ($self->{'_end'} > $chrsize) {
		 $self->{'_end'} = $chrsize;
	    }
	}
	else {
	    my $err = $self->notFoundMsg($self->{'_seq'}, "sequence");
	    $self->err_report($err);
	}	
	return;
}

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

	my @rows;
	my $geneSeqResourceUrl = $configUrl->DictyosteliumServerRoot.
	                "cgi-bin/dictyBase/seqTools?seqname=";
	my $infoUrl = $configUrl->dictyBaseCGIRoot.
	                "gene_page.pl?dictyBaseid=";
	my $physmapUrl = $configUrl->dictyBaseCGIRoot.
	                "$dblink/PHYSMAP/PHYSmap?dictyBaseid=";

	my $arrayRef = Feature->GetFeatureTableArrayRefByChrBegEnd(
					 dbh=>$dbh,
					 chromosome=>$self->{'_chr'},
                                         start_coord=>$self->{'_beg'},
                                         stop_coord=>$self->{'_end'});
	my %foundOrf;
	foreach my $rowRef (@$arrayRef) {
	    my ($orf, $start, $stop, $strand, $gene, $desc, $dictyBaseid, $type)
		= @$rowRef;
	    if ($foundOrf{$orf}) { next; }
	    ($start, $stop) = ($stop, $start) if ($start > $stop);
	    if (!$gene) { $gene = "-"; }
	    else { 
		$gene = a({-href=>"$infoUrl$dictyBaseid", -target=>'infowin'}, $gene); 
	    }
	    my $geneSeqResource = a({-href=>"$geneSeqResourceUrl$orf", 
				     -target=>'infowin'}, 
				    "Gene/Seq Resources");
	    my $info = a({-href=>"$infoUrl$dictyBaseid", 
			  -target=>'infowin'}, 
			 "Info");
	    my $physmap = a({-href=>"$physmapUrl$dictyBaseid",
			     -target=>'infowin'}, 
			    "PhysicalMap");
	    if (!$desc) { $desc = "-"; }
	    push(@rows, td($orf).td($start).td($stop).td($strand).td($geneSeqResource.br."|".$info."|".$physmap).td($gene).td($desc));
		
	    $foundOrf{$orf}++;
	}
        if (@rows > 0) {
	    return center(table({-border=>3,
				 -cellspacing=>3,
				 -cellpadding=>3},
				Tr({-align=>'center'},
				   th({-rowspan=>2}, "Feature").
				   th({-colspan=>2}, "Chromosomal Coordinates").
				   th({-rowspan=>2}, "Strand").
				   th({-rowspan=>2}, "Retrieve").
				   th({-rowspan=>2}, "Locus").
				   th({-rowspan=>2}, "Locus Description")).
			        Tr({-align=>'center'},
				   th("Begin").
				   th("End")).
		                Tr({-align=>'center'},
				   [@rows])
		       ));
	}
	else {
	    return 0;
	}
}


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

	print p, $err,

	&printEndPage;
    	
	$dbh->disconnect;
	exit;
}

########################################################################
sub processInfo {
########################################################################
	my ($self) = shift;
	if ($self->{'_chr'} !~ /^([0-9]+)$/) {
		$self->{'_chr'} = $rom2num{"\U$self->{'_chr'}"};
	}	
	$self->{'_seq'} = "\U$self->{'_seq'}";
}

########################################################################
sub setBegEnd {
########################################################################
	my ($self) = shift;
	if (!$chrsize)  {
	    $chrsize = $self->getChromSize;
	}
	if ($self->{'_end'} > $chrsize) {
		$self->{'_end'} = $chrsize;
	}
	elsif ($self->{'_beg'} > $chrsize) {
		$self->{'_beg'} = $chrsize - 100000;
		$self->{'_end'} = $chrsize;
	}
	if (!$self->{'_beg'}) {
		$self->{'_beg'} = 1;
		$self->{'_end'} = 100000;
	}
	if (!$self->{'_end'}) {
		if ($self->{'_beg'} == 1) {
			$self->{'_end'} = 100000;
		} 
		else {
			$self->{'_end'} = $self->{'_beg'} + 100000;
		}
	}
	if ($self->{'_end'} > $chrsize) {
	    $self->{'_end'} = $chrsize;
	}
}

########################################################################
sub notFoundMsg {
########################################################################
	my ($self, $seqORchr, $type) = @_;
	return font({-color=>'red'}, b("\u$type"." $seqORchr is unknown to dictyBase")).p."If the $type originated from a link within dictyBase, please ".a({-href=>$configUrl->breadServerRoot."forms/dictyBase-suggestion.html"}, "send us a message")." with a description of how you got this error message and the URL of the dictyBase WWW page with the bad link. If the sequence originated on another WWW server, contact the Webmaster for that server with similar information.", p;

}

#######################################################################
sub noFeaturesMsg {
#######################################################################
	my ($self) = @_;
	return font({-color=>'red'}, "This region of chromosome ".$self->{'_chr'}." spanning coordinates ".$self->{'_beg'}." to ".$self->{'_end'}." has no annotations.").p."This ".a({-href=>url."?chr=".$self->{'_chr'}}, "Features Table")." displays the chromosome features from coordinate 1 to 100000.", p;

}

#######################################################################
sub bottomLink {
#######################################################################
    my ($self) = shift;
    if (!$chrsize)  {
	    $chrsize = $self->getChromSize;
    }
    my ($backBeg, $backEnd, $nextBeg, $nextEnd);
    if ($self->{'_beg'} > 1) { 
	$backEnd = $self->{'_beg'} + 20000;
        $backBeg = $backEnd - 100000;
        if ($backBeg < 1) {
	    $backBeg = 1;
	}
        if ($backEnd > $chrsize) {
	    $backEnd = $chrsize;
	}
    }
    if ($self->{'_end'} < $chrsize) {
	$nextBeg = $self->{'_end'} - 20000;
	$nextEnd = $nextBeg + 100000;
	if ($nextBeg < 1) {
	    $nextBeg = 1;
	}
        if ($nextEnd > $chrsize) {
	    $nextEnd = $chrsize;
	}
    }
    my $ORFmapUrl = $configUrl->dictyBaseCGIRoot."$dblink/ORFMAP/ORFmap";
    my $ORFtableUrl = $configUrl->dictyBaseCGIRoot."$dblink/featureform";
    my $GeneSeqResourceUrl = $configUrl->DictyosteliumServerRoot."cgi-bin/dictyBase/seqTools";
    my $LeftRight;
    if ($backBeg) {
	$LeftRight = a({-href=>$ORFtableUrl."?chr=".$self->{'_chr'}."&beg=$backBeg&end=$backEnd"}, "Retrieve Features Left");
    }
    if ($nextBeg) {
	if ($LeftRight) {
	    $LeftRight .= "<----->"; 
	}
	$LeftRight .= a({-href=>${ORFtableUrl}."?chr=".$self->{'_chr'}."&beg=$nextBeg&end=$nextEnd"}, "Retrieve Features Right");
    }
    if ($LeftRight) {	
	return p.center($LeftRight).p.
	    center(a({-href=>${ORFmapUrl}."?chr=".$self->{'_chr'}."&beg=".$self->{'_beg'}."&end=".$self->{'_end'}}, 
		      "Chromosomal Features Map")." | ".
		   a({-href=>${GeneSeqResourceUrl}."?chr=".$self->{'_chr'}."&beg=".$self->{'_beg'}."&end=".$self->{'_end'}}, 
		      "Gene/Sequence Resources"));
    }
    else {
	return p.center(a({-href=>${ORFmapUrl}."?chr=".$self->{'_chr'}."&beg=".$self->{'_beg'}."&end=".$self->{'_end'}}, 
                           "Chromosomal Features Map")." | ".
                        a({-href=>${GeneSeqResourceUrl}."?chr=".$self->{'_chr'}."&beg=".$self->{'_beg'}."&end=".$self->{'_end'}}, 
                           "Gene/Sequence Resources"));
    }
}

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



















