#!/usr/bin/perl
package sdevDomain;

#######################################################################
##### Author :	Shuai Weng
##### Date   :  Nov. 2001
##### Description : This package contains all necessary methods for 
#####               displaying protein motifs and functional information 
#####               for a given Dictyostelium protein. 
#####              
#######################################################################
use strict;
use DBI;
use GD;
use CGI qw/:all/;
use CGI::Carp qw(fatalsToBrowser);
use LWP::UserAgent;

use lib "/usr/local/dicty/www_dictybase/db/lib/dictyBase/Objects";
use Locus;
use Feature;
use dictyBaseid;
use Pdb_sequence;
use ConfigURLdictyBase;
use ConfigPathdictyBase;
use CreateGD;
use Motif;

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 $configUrl;
my $configPath;
my %gene4orf;
my %commonMotif;
my $defaultRulerWidth = 700;
my $defaultBarHeight = 15;
my $lastUpdate;

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

	$self = {};
	bless $self;

      	$self->{'_database'} = $args{'database'};
	$self->{'_help'}     = $args{'help'};

	$dbh = &ConnectToDatabase($self->database);

    	return $self;
}

sub help { $_[0]->{_help} }
sub database { $_[0]->{_database} }
sub title { $_[0]->{_title} }
sub featNm { $_[0]->{_featNm} }
sub locusNm { $_[0]->{_locusNm} }
sub showNm { $_[0]->{_showNm} }
sub proteinNm { $_[0]->{_proteinNm} }

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

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

    my ($self) = @_;

    $self->{'_title'} = "Dictyostelium Protein Motif Query";
    
    $self->initGlobalVars;
    
    if (!param) {
	$self->printEntryForm;
    }
    elsif (param('externalDb')) {
        $self->setIdentifier;
	$self->redirectPage;
    }
    else {
	$self->setIdentifier;
	$self->displayInfo;
    }
}

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

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

    print blockquote(table(Tr(td({-width=>'80%'},
				 font({-size=>'+2'},
				      b("Protein Motif Query"))).
			      td({-bgcolor=>"#b7d8e4"},
				 "&nbsp;&nbsp;".
				 a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/protein/get3d"}, b("PDB Homolog Query")).
				 "&nbsp;&nbsp;"))).
		     "This query page allows you to retrieve motif information for ".i("Dictyostelium discoideum")." proteins. The search will identify motifs contained in the query protein and will list other Dictyostelium proteins that also contain those motifs. The analysis was performed by comparing Dictyostelium protein sequences against motifs in ".a({-href=>'http://motif.stanford.edu/emotif/'}, "eMOTIFS database")." using eMOTIF-SEARCH regular expression matching program."),p;
   
    print center(table(Tr(td({-colspan=>'3'}, hr)).
		       Tr(td(start_form).
		          td({-bgcolor=>'#a4abc2'}, 
			     b(font({-size=>'+1'}, 
				    "Gene/ORF Name: "))).
			  td(textfield(-name=>'locus',
				       -size=>'20')).
			  td(submit(-name=>'Submit',
				    -value=>'Search')." ".
			      reset(-name=>'Clear'))).
	      	       Tr(td(end_form))
		));

    &printEndPage;
}

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

    print table({-width=>'100%'},
		Tr(th({-align=>'left',
		       width=>'80%'},
		      br.font({-size=>'+1'},
			      font({-color=>'red'},
				   $self->showNm)." Protein Motifs")).
		   $self->printGeneLink($self->showNm))),p;

    print blockquote("Motifs determined by comparing ".i("Dictyostelium discoideum")." protein sequence against motif sequences in ".a({-href=>'http://motif.stanford.edu/emotif/'}, "eMOTIFS database").", using eMOTIF-SEARCH regular expression matching program."),p;
    print blockquote("Last updated on $lastUpdate"),p;

    my $motifObj = Motif->new(seqname=>$self->featNm);

    $self->{'_sequence'} = $motifObj->getSequence;

    my ($domainRef, $relatedProteinDomainRef) 
	= $motifObj->getMotifInfo;

    if (!$domainRef || !@$domainRef) {
	print p, center(b("We currently have no motif information for ".
	      font({-color=>'red'}, $self->showNm).". You may find the following domain databases useful.")),p;	
	$self->printDomainLink;
    }
    else {
	$self->printBarGraph($domainRef);
   
        $self->printDomainLink;
    	
	$self->printSimilarProteinDomain($relatedProteinDomainRef);
    }

    print table({-width=>'100%'}, 
		Tr(td({-align=>'center'}, 
		      "Last updated on $lastUpdate"))),p;

    &printEndPage;
    
}

########################################################################
sub printGeneLink {
########################################################################

    my ($self, $showNm) = @_;
    
    my $geneLinks = b($self->showNm." links").br.li(a({-href=>$configUrl->dictyBaseCGIRoot."gene_page.pl?gene_name=".$self->featNm, -target=>'infowin'}, 
						      "Locus Info"));

    my $seqObj = Pdb_sequence->new(dbh=>$dbh,
				   sequence_name=>$self->featNm);
    if ($seqObj) {
	$geneLinks .= li(a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/protein/get3d?locus=".$self->featNm, -target=>'infowin'},
	               "PDB Homologs"));
    }
    return td({-bgcolor=>'#b7d8e4',
	       -align=>'left',
	       -width=>'20%'},
	      $geneLinks);
	
}

########################################################################
sub printBarGraph {
########################################################################
    my ($self, $domainRef) = @_;

    my $yStart = 20;
    my $rulerHeight = 3;
    my $barGap = 16;
    my $xGap = 80;

    my ($newDomainRef, $rowNum) = $self->processImageCoords($yStart, 
				       $xGap, $barGap, $rulerHeight,
				       $domainRef);

    my $height = $yStart + $rulerHeight + ($rowNum+1)*$barGap + 
	         ($rowNum+1)*$defaultBarHeight + 40;

    my $width = $defaultRulerWidth+$xGap+40;

    my $gd = CreateGD->new(width=>$width,
			   height=>$height);
    
    print "<map name='domainGif'>";

    $gd->im->rectangle(0, 0, $width-1, $height-1,
		       $gd->blue);

    ### draw ruler
    
    $gd->im->filledRectangle($xGap, $yStart, $width-40, 
			     $yStart+$rulerHeight, 
			     $gd->black);    
    
    $gd->im->string(gdSmallFont, 10, $height-15, 
		    "eMOTIF motifs via dictyBase", $gd->red);	
    
    my $date = `date`;
    chomp $date;
    $date =~ s/^[^ ]+ ([^ ]+) ([0-9]+) .+ ([0-9]+)$/$1 $2\, $3/;

    $gd->im->string(gdSmallFont, $width-82, $height-15, 
		    $date, $gd->red);	

    my ($orf, $Qlen, $others) = split(/\t/, $$domainRef[0]);   
    my $tickNum = $Qlen/100;
    my $pixelNum = $defaultRulerWidth*100/$Qlen; 
    my $i;
    for ($i = 0; $i <= $tickNum; $i++) {
	$gd->im->line($xGap+$i*$pixelNum+1, $yStart-4, 
		      $xGap+$i*$pixelNum+1, $yStart,
		      $gd->black);
	$gd->im->string(gdSmallFont, $xGap+$i*$pixelNum, 
			$yStart-17, $i*100, $gd->black);	
    }
    if ($Qlen - ($i-1)*100 > 30) {
	$gd->im->line($xGap+$defaultRulerWidth, $yStart-4, 
		      $xGap+$defaultRulerWidth, $yStart,
		      $gd->black);
	$gd->im->string(gdSmallFont, $xGap+$defaultRulerWidth-1, 
			$yStart-17, $Qlen,
			$gd->black);	
    }

    ### draw query bar

    $yStart += $rulerHeight + $barGap;

    my $Qx1 = $xGap;
    my $Qx2 = $xGap+$defaultRulerWidth;
    my $Qy1 = $yStart;
    my $Qy2 = $yStart+$defaultBarHeight;

    $gd->im->filledRectangle($Qx1, $Qy1, $Qx2, $Qy2, $gd->blue);    
    $gd->im->string(gdMediumBoldFont, $defaultRulerWidth/2-40, 
		$Qy1+($defaultBarHeight-10)/2, 
		$self->proteinNm, $gd->white);

    my $locusUrl = $configUrl->dictyBaseCGIRoot."gene_page.pl?gene_name=".$self->featNm;
    print "<area shape=\"rect\" coords=\"$Qx1,$Qy1,$Qx2,$Qy2\" href=\"$locusUrl\" target='infowin'>";

    ### draw target bar

    my @keyText;
    my $tblRows;
    foreach my $row (@$newDomainRef) {

	my ($orfNm, $orfLen, $domainNm, $domainDesc, $pvalue,
	    $Tx1, $Ty1, $Tx2, $Ty2, $url) = split(/\:/, $row);

	$commonMotif{$domainNm}++;

	my ($domainNmRoot, $domainSuffix);
	if ($domainNm =~ /^(.+)([A-Z])$/i) {
	    $domainNmRoot = $1;
	    $domainSuffix = $2;
	}
	else { $domainNmRoot = $domainNm; }

	my $linkUrl = $self->getEntryLinkUrl($domainNmRoot);

	my $barColor = $self->getBarColor($gd, $pvalue);

	if ($domainDesc ne "Unknown") {

	    $gd->im->filledRectangle(5, $Ty1-8, $defaultRulerWidth+$xGap, 
				     $Ty2+14, $gd->lightGrey);
	    my $NmTx1 = 10;
	    my $NmTx2 = $NmTx1 + length($domainNmRoot)*6;
	    my $NmTy1 = $Ty1-5;
	    my $NmTy2 = $NmTy1 + 8; 
	    $gd->im->string(gdMediumBoldFont, $NmTx1, 
			    $NmTy1, $domainNmRoot, $gd->blue);
	    push(@keyText, $domainNmRoot."||".$domainDesc); 
	    print "<area shape=\"rect\" coords=\"$NmTx1,$NmTy1,$NmTx2,$NmTy2\" href=\"$linkUrl\" target='infowin'>";

	}    

	$gd->im->filledRectangle($Tx1, $Ty1, $Tx2, $Ty2, $barColor); 

	print "<area shape=\"rect\" coords=\"$Tx1,$Ty1,$Tx2,$Ty2\" href=\"$linkUrl\" target='infowin'>";

	if ($domainSuffix) {
	    $gd->im->string(gdMediumBoldFont, $Tx1-7, 
			    $Ty1-4, $domainSuffix, $gd->red);
	}    
	$tblRows .= Tr(td(a({-href=>$linkUrl,
			     -target=>'infowin'},
			    b($domainNm)).": ").
		       td(br).
		       td($domainDesc));
    }

    print "</map>";

    my $gifDir = $configPath->tmpDir;
    my $gifHttp = $configUrl->dictyBaseHtmlTmp;
    my $gifname = $self->featNm.".domain.gif";

    open (OUT, ">".$gifDir.$gifname)||die "Can't create ".$gifDir.$gifname.":$!";
    binmode OUT;
    print OUT $gd->im->gif;
    close OUT;
    print center(img({-src=>$gifHttp.$gifname, 
		      -usemap=>'#domainGif'})),p;

    $self->printKeyGif(\@keyText);
    
}

########################################################################
sub printKeyGif {
########################################################################

    my ($self, $keyTextRef) = @_;
    
 
    my $height = 40 + 15*@$keyTextRef;
    my $xGap = 20;

    my $gd = CreateGD->new(width=>$defaultRulerWidth+3*$xGap,
			   height=>$height);

    print "<map name='domainKeyGif'>";

    $gd->im->rectangle(0, 0, $defaultRulerWidth+3*$xGap-1, $height-1,
		       $gd->blue);

    $gd->im->line(1, 30, $defaultRulerWidth+3*$xGap-1, 30,
		       $gd->black);

    $gd->im->string(gdMediumBoldFont, $xGap, 8,
		    "Key: ", $gd->red);

    $gd->im->filledRectangle($xGap+50, 13, $xGap+75, 17,
			     $gd->red);
    $gd->im->string(gdMediumBoldFont, $xGap+80, 8, 
		    " pvalue <= 1.0e-20", $gd->black);

    $gd->im->filledRectangle($xGap+250, 13, $xGap+275, 17,
			     $gd->magenta);
    $gd->im->string(gdMediumBoldFont, $xGap+280, 8, 
		    " pvalue <= 1.0e-10", $gd->black);

    $gd->im->filledRectangle($xGap+450, 13, $xGap+475, 17,
			     $gd->maroon);
    $gd->im->string(gdMediumBoldFont, $xGap+480, 8, 
		    " pvalue <= 1.0e-2", $gd->black);

    my $i = 0;
    foreach my $keyText (@$keyTextRef) {

	my ($motif, $desc) = split(/\|\|/, $keyText);

	my $linkUrl = $self->getEntryLinkUrl($motif);

	my $NmTx1 = $xGap;
	my $NmTy1 = 35+$i*15;
	my $NmTx2 = $xGap + length($motif)*6;
	my $NmTy2 = 35+$i*15 + 8;

	$gd->im->string(gdMediumBoldFont, $NmTx1, $NmTy1, 
		    $motif, $gd->blue);
	
	print "<area shape=\"rect\" coords=\"$NmTx1,$NmTy1,$NmTx2,$NmTy2\" href=\"$linkUrl\" target='infowin'>";

	$gd->im->string(gdMediumBoldFont, $NmTx1+80, $NmTy1, 
		    $desc, $gd->black);

      	$i++;
    }

    print "</map>";

    my $gifDir = $configPath->tmpDir;
    my $gifHttp = $configUrl->dictyBaseHtmlTmp;
    my $gifname = "domain.$$.key.gif";

    open (OUT, ">".$gifDir.$gifname)||die "Can't create ".$gifDir.$gifname.":$!";
    binmode OUT;
    print OUT $gd->im->gif;
    close OUT;
    print center(img({-src=>$gifHttp.$gifname,
		      -usemap=>'#domainKeyGif'})),p;    
}

########################################################################
sub processImageCoords {
########################################################################
    my ($self, $yStart, $xGap, $barGap, $rulerHeight, $domainRef) = @_;

    $yStart += $rulerHeight + $barGap - 15;
    
    my %data4domainNmRoot;
    
    foreach my $row (@$domainRef) {
	my ($orfNm, $orfLen, $domainNm, $pvalue, $orfBeg, 
	    $orfEnd, $linkUrl, $domainDesc) = split(/\t/, $row);
	my $domainNmRoot = $domainNm;
	$domainNmRoot =~ s/^(IPB[0-9]{6}).*$/$1/;
	$domainNmRoot =~ s/^(PF[0-9]{5}).*$/$1/;
	$domainNmRoot =~ s/^(BP[0-9]{5}).*$/$1/;
	$domainNmRoot =~ s/^(DM[0-9]{5}).*$/$1/;
	$domainNmRoot =~ s/^(PR[0-9]{5}).*$/$1/;
	$data4domainNmRoot{$domainNmRoot} .= "::".$row;
    }
    my @domain;
    my $i;
    foreach my $key (sort keys (%data4domainNmRoot)) {

	$i++;

	my @row = split(/::/, $data4domainNmRoot{$key});
	shift @row;

	my %domain;
	foreach my $row (@row) {
	    my ($orfNm, $orfLen, $domainNm, $pvalue, $orfBeg, 
	    $orfEnd, $linkUrl, $domainDesc) = split(/\t/, $row);
	    if ($domain{$orfBeg}) { $domain{$orfBeg} .= "\t"; }
	    $domain{$orfBeg} .= $orfNm.":".$orfLen.":".$domainNm.":".
	                    $domainDesc.":".$pvalue.":".$orfBeg.":".
			    $orfEnd.":".$linkUrl;
	}

	my $preTx2;    
	my $j;
	foreach my $key (sort {$a<=>$b} keys (%domain)) {

	    $j++;

	    my @entry = split(/\t/, $domain{$key});

	    foreach my $entry (@entry) {
		my $linkUrl;
		if ($entry =~ /^(.+):(http:.+)$/) {
		    $entry = $1;
		    $linkUrl = $2;
		}
		my ($orfNm, $orfLen, $domainNm, $domainDesc, $pvalue, 
		    $orfBeg, $orfEnd) = split(/\:/, $entry);
	    
		my $Tx1 = $xGap+$defaultRulerWidth*$orfBeg/$orfLen;
		my $Tx2 = $xGap+$defaultRulerWidth*$orfEnd/$orfLen;
	
		my $Ty1 = $yStart+($i+1)*($barGap+$defaultBarHeight)-10;
		if ($Tx1 < $preTx2 + 9) {
		    $Ty1 += 10;
		}
		else {
		    $preTx2 = $Tx2;
		}
		my $Ty2 = $Ty1 + $defaultBarHeight-10;
		if ($j != 1) {
		    $domainDesc = "Unknown";
		}
		elsif ($domainNm =~ /^PR/i) {
		    $domainDesc =~ s/^(.+) [IXV]+$/$1/;
		}
		push(@domain, $orfNm.":".$orfLen.":".$domainNm.":".
		              $domainDesc.":".$pvalue.":".$Tx1.":".
			      $Ty1.":".$Tx2.":".$Ty2.":".$linkUrl);
	    } 
	}
    }
    return (\@domain, $i);

}


########################################################################
sub getEntryLinkUrl {
########################################################################
    my ($self, $domainNm) = @_;

    if ($domainNm =~ /^PR[0-9]+/i) {
	return "http://methionine.sbc.man.ac.uk/cgi-bin/dbbrowser/sprint/searchprintss.cgi?prints_accn=$domainNm&display_opts=Prints&category=None&queryform=false";
    }
    elsif ($domainNm =~ /^IPB[0-9]+/) {
	$domainNm =~ s/^IPB/IPR/i;
	return "http://www.ebi.ac.uk/interpro/ISimpleSearch?query=$domainNm";
    }
    else {
	return "http://blocks.fhcrc.org/blocks-bin/getblock.sh?$domainNm";
    }

}

########################################################################
sub getNCBIlinkUrl {
########################################################################
    my ($self, $domainNm) = @_;
    return "http://www.ncbi.nlm.nih.gov/Structure/cdd/cddsrv.cgi?uid=$domainNm";
}

########################################################################
sub getBarColor {
########################################################################
    my ($self, $gd, $pvalue) = @_;
    my $barColor;
    if ($pvalue <= 1.0e-20) {
	$barColor = $gd->red;
    }
    elsif ($pvalue <= 1.0e-10) {
	$barColor = $gd->magenta;
    }
    else {
	$barColor = $gd->maroon;
    }
    return $barColor;
}

########################################################################
sub printSimilarProteinDomain {
########################################################################
    my ($self, $relatedProteinDomainRef) = @_;

    if (!@$relatedProteinDomainRef) { return; }

    my $tblRows;
    my $preOrf;
    my @commonDomain;
    my @otherDomain;
    my $preRow;
    foreach my $row (@$relatedProteinDomainRef) {
	my ($orfNm, $orflen, $domainNm, $others) 
	    = split(/\t/, $row);
	if ($orfNm ne $preOrf && @commonDomain) {
	    my $commonDomainList 
		= $self->domainList(\@commonDomain);
	    my $otherDomainList 
		= $self->domainList(\@otherDomain);
	    $tblRows .= $self->getRow($preOrf, $commonDomainList, 
				      $otherDomainList);
	    undef @commonDomain;
	    undef @otherDomain;
	}
	if ($commonMotif{$domainNm}) {
	    push(@commonDomain, $row);
	}
	else {
	    push(@otherDomain, $row);
	}
	$preOrf = $orfNm;
    }
    my $commonDomainList = $self->domainList(\@commonDomain);
    my $otherDomainList = $self->domainList(\@otherDomain);

    $tblRows .= $self->getRow($preOrf, $commonDomainList, 
			      $otherDomainList);

    print table(Tr(td(b(font({-size=>'+1'},
			      "Other ".i("Dictyostelium discoideum")." proteins that contain motifs found in ".font({-color=>'red'}, $self->proteinNm))))).  
		Tr(td(blockquote(table({-align=>'center',
					-border=>'1',
					-cellpadding=>'3'},
				       Tr({-bgcolor=>'#CCCFFF'},
					  th("Protein").
					  th("Motifs in common with ".$self->proteinNm).
					  th("Other motifs in this protein (but not in ".$self->proteinNm.")")).
				       $tblRows))))),p;
}

########################################################################
sub domainList {
########################################################################
    my ($self, $domainRef) = @_;
    my $domainList;
    my %foundDomainNm;
    foreach my $row (sort(@$domainRef)) {
	my ($orfNm, $orflen, $domainNm, $pvalue, $orfBeg, 
	    $orfEnd, $linkUrl, $domainDesc) = split(/\t/, $row);
	if ($foundDomainNm{$domainNm}) { next; }
	$foundDomainNm{$domainNm}++;
	### since the $linkUrl may be old
	### get current url
	my $domainNmRoot = $domainNm;
	$domainNmRoot =~ s/^(.+[0-9]+)[A-Z]$/$1/;
	$linkUrl = $self->getEntryLinkUrl($domainNmRoot);
	$domainList .= li(a({-href=>$linkUrl,
			     -target=>'infowin'}, 
			    b($domainNm)).
			  ": ".$domainDesc);
    }
    return $domainList;

}

########################################################################
sub printDomainLink {
########################################################################
    my ($self, $name) = @_;
    if (!$self->{'_sequence'}) { return; }

    my @urlVals = ('NCBI Dart', 'SMART domain', 'PFAM domain', 'PROSITE pattern', 'SCOP');

    print table({-align=>'center'},
		Tr(td({-align=>'left'},
		      font({-size=>'+1'}, "Search other databases for $name protein motifs:")).
		   td({-align=>'left'},
		      table({-align=>'left',
			     -border=>'0',
			     -cellpadding=>'1',
			     -cellspacing=>'1',
			     -bgcolor=>'#d8d8d8'},
			    Tr(td(start_form.
				  hidden(-name=>'sequence',
					 -value=>$self->{'_sequence'}).
				  hidden(-name=>'showNm',
					 -value=>$self->showNm).
				  hidden(-name=>'featNm',
					 -value=>$self->featNm).
				  popup_menu(-name=>'externalDb',
					     -"values"=>\@urlVals).
				  submit(-name=>'submit',
					 -value=>'Go!').
				  end_form))))));

}

########################################################################
sub redirectPage {
########################################################################
    my ($self) = @_;
    
    if (param('externalDb') =~ /^SCOP/i) {

	my $dictyBase = dictyBaseObject->new(database=>$self->database, 
				 featureName=>param('featNm'));
	$dictyBase->_initURLs;
       
	if ($dictyBase->scop) {
	    
	     print "location: ", $dictyBase->scop, "\n";
	     print "Content-type: text/html\n\n";
	}
	else {

	    $self->err_report("No SCOP information found for ".param('featNm').".");

	}

	exit;
    }


    $self->{'_title'} = "Protein Domains : ".param('showNm');

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

    
    my $AAseq = param('sequence');
    $AAseq =~ s/\*$//;

    my $dartRootUrl = "http://www.ncbi.nlm.nih.gov/";
    my $prositeRootUrl = "http://hits.isb-sib.ch/";
    my $smartRootUrl = "http://smart.embl-heidelberg.de/";
    my $pfamRootUrl = "http://www.sanger.ac.uk/";

    my $externalUrl;
    if (param('externalDb') =~ /NCBI/i) {
	$externalUrl = $dartRootUrl."Structure/lexington/lexington.cgi?cmd=seq&fasta=$AAseq&FILTER=on&EXPECT=0.01";
    }
    elsif (param('externalDb') =~ /PROSITE/i) {
	$externalUrl = $prositeRootUrl."cgi-bin/PFSCAN_parser?text=$AAseq&profile=profile&pattern=pattern&flavour=last&SEView=0";
    }
    elsif (param('externalDb') =~ /^SMART/i) {
	$externalUrl = $smartRootUrl."smart/show_motifs.pl?SEQUENCE=$AAseq";
    }
    elsif (param('externalDb') =~ /^PFAM/i) {
        $externalUrl = $pfamRootUrl."cgi-bin/Pfam/nph-search.cgi?protseq=$AAseq&type=normal&out_format=html&select0=pfamA&select1=smart&select2=tigr&select3=pfamB&evalue=0.01";
    }
    else {
	print p, "Unknown external database: ".param('externalDb'),p;
	&printEndPage;
	exit;
    }
    
    my $ua = new LWP::UserAgent;
    my $reqUrl = new HTTP::Request GET => $externalUrl;
    $reqUrl->content_type('application/x-www-form-urlencoded');
    my $resUrl = $ua->request($reqUrl);
    if (!$resUrl->is_success) { 
	print p, "Search ".param('externalDb')." failed. Please try again later.",p;
	&printEndPage;
	exit;
    }

    my $content = $resUrl->content;

    ####### process output
    if (param('externalDb') =~ /NCBI/i) {
	$content =~ s/href ?= ?\"\//href=\"$dartRootUrl/ig;
	$content =~ s/(src|action) ?= ?\"lexington.cgi/$1=\"${dartRootUrl}Structure\/lexington\/lexington.cgi/ig;
	$content =~ s/(src|href) ?= ?\"html/$1=\"${dartRootUrl}Structure\/lexington\/html/ig;
        $content =~ s/action ?= ?\"\//action=\"${dartRootUrl}\//ig;
        
    }
    elsif (param('externalDb') =~ /PROSITE/i) {
        $content =~ s/(src|href) ?= ?\"\//$1=\"${prositeRootUrl}/ig;
        $content =~ s/(src|href) ?= ?\'\//$1=\"${prositeRootUrl}/ig;        
    }
    elsif (param('externalDb') =~ /^SMART/i) {
        $content =~ s/(src ?= ?\"?)\//$1${smartRootUrl}/ig;
        $content =~ s/HREF ?= ?\"\//href=\"${smartRootUrl}/ig;
    }
    elsif (param('externalDb') =~ /^PFAM/i) {
        $content =~ s/((src|href) ?= ?\"?)\//$1$pfamRootUrl/ig;
    }


    print $content;

    &printEndPage;

}

########################################################################
sub getRow {
########################################################################
    my ($self, $featNm, $commonDomainList, $otherDomainList) = @_;

    if (!$otherDomainList) { $otherDomainList = li("none"); }

    my $featObj = Feature->new(dbh=>$dbh,
			       feature_name=>$featNm);
    my $showNm;
    if ($featObj && $featObj->locus_name) { 
	$showNm = $featObj->locus_name."/"; 
    }
    $showNm .= $featNm;

    my $proteinNm;
    if ($featObj->locus_name) {
	$proteinNm = $featObj->locus_name;
	$proteinNm = "\L$proteinNm";
	$proteinNm = "\u$proteinNm";
    }
    else { $proteinNm = $featNm; }
    $proteinNm .= "p";
	
    return Tr(td({-align=>'left',
		  -valign=>'top'},
		 b($proteinNm).br.
		 li(a({-href=>$configUrl->dictyBaseCGIRoot."gene_page.pl?gene_name=$featNm", -target=>'infowin'}, 
		   "Locus Info")).
		 li(a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/protein/getDomain?locus=$featNm", -target=>'infowin'}, 
		   "Motifs")).
		 li(a({-href=>$configUrl->dictyBaseCGIRoot."$dblink/protein/get3d?locus=$featNm", -target=>'infowin'}, 
		   "PDB Homologs"))).
	      td({-valign=>'top',
	          -align=>'left'},
		 $commonDomainList).
	      td({-valign=>'top',
	          -align=>'left'},
		 $otherDomainList));
}

########################################################################
sub smartLink {
########################################################################
    my ($self) = @_;
    return start_form(-action=>'http://smart.embl-heidelberg.de/smart/show_motifs.pl',
		      -method=>'post',
		      -target=>'infowin').
	   hidden(-name=>'SEQUENCE',
		  -value=>$self->{'_sequence'}).
	   submit(-name=>'DO_SMART',
		  -value=>'SMART domain').
	   end_form;

}

########################################################################
sub pfamLink {
########################################################################
    my ($self) = @_;
    $self->{'_sequence'} =~ s/[^A-Za-z]//g;
    return start_form(-action=>'http://www.sanger.ac.uk/cgi-bin/Pfam/nph-search.cgi',
		      -method=>'post',
		      -target=>'infowin').
	   hidden(-name=>'protseq',
		  -value=>$self->{'_sequence'}).
	   hidden(-name=>'type',
		  -value=>'normal').
	   hidden(-name=>'out_format',
		  -value=>'html').
	   hidden(-name=>'select0',
		  -value=>'pfamA').
	   hidden(-name=>'select1',
		  -value=>'smart').
           hidden(-name=>'select2',
		  -value=>'tigr').
           hidden(-name=>'select3',
		  -value=>'pfamB').
           hidden(-name=>'evalue',
		  -value=>'0.01').
	   submit(-name=>'submit',
		  -value=>'PFAM domain').
	   end_form;
}

########################################################################
sub interPro {
########################################################################
    my ($self) = @_;
    return start_form({-action=>"http://oban.ebi.ac.uk:6600/srs6bin/cgi-bin/pub/launcher.pl", -method=>"POST", -target=>'infowin'}). 
		hidden(-name=>'sequence',
		       -value=>$self->{'_sequence'}).
		hidden(-name=>'runtype',
		       -value=>'interactive').
		hidden(-name=>'sndmail',
		       -value=>'1').
		submit(-name=>'interPro').end_form;
}

########################################################################
sub NCBIdart {
########################################################################
    my ($self) = @_;
    return start_form({-action=>"http://www.ncbi.nlm.nih.gov/Structure/lexington/lexington.cgi", -method=>"POST", -target=>'infowin'}). 
		hidden(-name=>'cmd',
		       -value=>'seq').
		hidden(-name=>'fasta',
		       -value=>$self->{'_sequence'}).
		hidden(-name=>'FILTER',
		       -value=>'on').
		hidden(-name=>'EXPECT',
		       -value=>'0.01').
		submit(-name=>'NCBI Dart').end_form;

}


########################################################################
sub initGlobalVars {
########################################################################
    my ($self) = @_;
    $configUrl = ConfigURLdictyBase->new;
    $dblink = $configUrl->dblink($self->database);
    $configPath = ConfigPathdictyBase->new;
}

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

    $lastUpdate = Motif->LastUpdate;

    if (param('dictyBaseid')) {
	my $dictyBaseid = param('dictyBaseid');
	&DeleteUnwantedChar(\$dictyBaseid);
	my $dictyBaseidObj = dictyBaseid->new(dbh=>$dbh,
				  dictyBaseid=>$dictyBaseid);
	if (!$dictyBaseidObj) {
	    $self->err_report("The dictyBaseid = $dictyBaseid is not found in our database.");
	    exit;
	}

	$self->{'_featNm'} = $dictyBaseidObj->feature_name;

	if (!$self->{'_featNm'}) {
	    $self->err_report("The dictyBaseid = $dictyBaseid is not associated with any feature_name in our database.");
	    exit;
	}
	$self->{'_locusNm'} = $dictyBaseidObj->locus_name;
    }
    elsif (param('gi')) {
	my $gi = param('gi');
	&DeleteUnwantedChar(\$gi);
	my ($featNm, $locusNm) = Feature->GetFeatNmLocusNmBYgiNo(dbh=>$dbh,
					      gi=>$gi);		
	if (!$featNm) {
	   $self->err_report("The NCBI gi number = $gi is not associated with any feature/gene in database.");
	    exit; 
	}
	$self->{'_featNm'} = $featNm;
	$self->{'_locusNm'} = $locusNm;
    }
    elsif (param('locus')) {
	my $locus = param('locus');
	&DeleteUnwantedChar(\$locus);
	my $featObj = Feature->new(dbh=>$dbh,
				   feature_name=>$locus);
	if ($featObj) {
	    $self->{'_featNm'} = $featObj->feature_name;
	    $self->{'_locusNm'} = $featObj->locus_name;
	}
	else {
	    my $locusObj = Locus->new(dbh=>$dbh,
				      locus_name=>$locus);
	    if ($locusObj) {
		$self->{'_locusNm'} = $locusObj->locus_name;
		$self->{'_featNm'} = $locusObj->featureNameList;
	    }
	    elsif (param('class')) {
		$self->{'_pdbid'} = $locus;
	    }
	    else {
		$self->err_report("The feature/locus = ".font({-color=>'red'}, $locus)." is not found in database.");
		exit;
	    }
	}
    }
    if ($self->locusNm) { 
	$self->{'_showNm'} = $self->locusNm."/";
    }
    $self->{'_showNm'} .= $self->featNm;
    $self->{'_title'} = "Protein Motifs : ".$self->showNm;

    if ($self->locusNm) {
	my $proteinNm = $self->locusNm;
	$proteinNm = "\L$proteinNm";
	$proteinNm = "\u$proteinNm"."p";
	$self->{'_proteinNm'} = $proteinNm;
    }
    else { $self->{'_proteinNm'} =$self->featNm."p"; }


}


########################################################################
sub err_report {
########################################################################
    my ($self, $err) = @_;
    
    $self->{'_title'} = "Protein Information: Error Report";
    &printStartPage($self->database, $self->title, $self->help);
   
    print b($err);
    
    &printEndPage;

    exit;
}

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






























