#!/usr/local/bin/perl 

###############################################################################
#
#   Name:           seqentryview
#
#   Description:    mod_perl script to display all the contigs in a clone, or
#                   just a single contig if required.
#
#   History:        *cough*     as2/avc -   original versions
#                   2000-11-08  jws -   changes to work with static_golden_path
#                                       virtual contigs, dumpview, and SiteDefs
#		    2000-11-28	jws -	Added FPC id
#		    2001-02-15	jws -	reworked to match contigview wvc
#
###############################################################################

package seqentryview;

use EnsWeb;
use ExtURL;
use SiteDefs;
use CGI qw(:standard :html3);
use GD;
use WebUserConfig;
use CGI qw(:standard :html3 :cookie);
use Bio::EnsEMBL::DrawableContainer;
use Bio::EnsEMBL::Map::DBSQL::Map;
use Bio::EnsEMBL::ExternalData::GMAPAdaptor;
use Bio::EnsEMBL::ExternalData::SNPSQL::WebSNPAdaptor;
use Bio::EnsEMBL::ExternalData::TCORESQL::DBAdaptor;
use Bio::EnsEMBL::ExternalData::EXONERATESQL::DBAdaptor;
use Bio::EnsemblViewer::Sequence::Contig;
use Bio::EnsEMBL::DBSQL::ExternalWrapper;
use GramenePage;
use strict;

my $grpg=undef;
if( defined( $ENV{'MOD_PERL'} ) )
{
  my $r;
  $r = Apache->request();
  $r->err_header_out('ensembl_headers_out'=>1);
  print header();
  my ($head,$onload,$js_divs)=&EnsWeb::cgi_header_info(('initfocus'=>1,'menus'=>1));
  $grpg=GramenePage->new($r);
  print $head,$grpg->start_body(  -ensembl=>1, -bodyattr=>$onload, -bodyfirst=>$js_divs  );
  print "<br><br><center>\n";
} else {
  print header();
  print EnsWeb::make_cgi_header(('initfocus'=>1, 'menus'=>1));
}
my $cloneid = param('seqentry');

my $contigid;	    # = param('contigid');

###################################
# Do some rough cleanup on cloneid
###################################
$cloneid =~ s/\s//g;

if ($cloneid =~ /\|/){
    $cloneid =~ s/(.*)\|/$1/;
}

if ($cloneid =~ /\./){
    $cloneid =~  s/((.*)\..*)/$2/;
    $contigid=$1;
}

$contigid ||= param('contigid');
$cloneid = $contigid and $cloneid=~ s/\..*// unless $cloneid;

###########################
# Are we using gif or png?
###########################
my $img_type;

if (GD::Image->can("gif")){
    $img_type="gif";
}
else {
    $img_type="png";
}

print EnsWeb::print_form($cloneid, "seqentry");

unless($cloneid || $contigid) {
    print "<br>No clone or contig specified.";
    if($grpg) {
      print $grpg->end_body;
    } else {
      print EnsWeb::make_cgi_footer();
    }
    &EnsWeb::ensembl_exit();
}

my @contigs;
my @genes;
my $db;
my $snpdb;
my $name;
my $clone;
my $mapdb;
my $fpc_map;
my $sa;


###############################
# Get hold of database handles
###############################
eval {
    my $locator = &EnsWeb::get_locator();
    $db =  Bio::EnsEMBL::DBLoader->new($locator);

    $db or print STDERR "cannot open $locator\n"
     and die "cannot open $locator\n";

                        
    if ($ENSEMBL_EMBL){
	my $emblext= Bio::EnsEMBL::DBSQL::DBAdaptor->new(       
			    -driver => $ENSEMBL_DRIVER,
			    -user   => $ENSEMBL_DBUSER,
			    -pass   => $ENSEMBL_DBPASS,
			    -dbname => $ENSEMBL_EMBL,
			    -host   => $ENSEMBL_HOST,
			    -port   => $ENSEMBL_HOST_PORT,
			    ); 
                        
	my $embldb= new Bio::EnsEMBL::DBSQL::ExternalWrapper($emblext);
	$db->add_ExternalFeatureFactory($embldb);
    }

    if ($ENSEMBL_GMAP){
	my $gmapdb= Bio::EnsEMBL::ExternalData::GMAPAdaptor->new(       
			    -driver => $ENSEMBL_DRIVER,
			    -user   => $ENSEMBL_DBUSER,
			    -pass   => $ENSEMBL_DBPASS,
			    -dbname => $ENSEMBL_GMAP,
			    -host   => $ENSEMBL_HOST,
			    -port   => $ENSEMBL_HOST_PORT,
			    ); 
                        
	$db->add_ExternalFeatureFactory($gmapdb);
    }

    if ($ENSEMBL_SNP){
    my $snpdb = Bio::EnsEMBL::ExternalData::SNPSQL::WebSNPAdaptor->new(   
			     -dbname => $ENSEMBL_SNP,
			     -user   => $ENSEMBL_DBUSER,
			     -pass   => $ENSEMBL_DBPASS,
			     -host   => $ENSEMBL_HOST,
			     -port   => $ENSEMBL_HOST_PORT,
			     );

    $db->add_ExternalFeatureFactory($snpdb);
    }

    if ($ENSEMBL_MOUSE){
	my $mouse = Bio::EnsEMBL::ExternalData::EXONERATESQL::DBAdaptor->new( 
			    -user   => $ENSEMBL_DBUSER,
			    -pass   => $ENSEMBL_DBPASS,
			    -dbname => $ENSEMBL_MOUSE,
			    -host   => $ENSEMBL_HOST,
			    -port   => $ENSEMBL_HOST_PORT,
			    ); 

	my $mouse_ext_feature_factory = $mouse->get_ExonerateAdaptor();
	$db->add_ExternalFeatureFactory($mouse_ext_feature_factory);
    }

    $db->static_golden_path_type($ENSEMBL_GOLD);


    if($ENSEMBL_MAP) {
	$mapdb   = new Bio::EnsEMBL::Map::DBSQL::Obj(   
                                                -user   => $ENSEMBL_DBUSER, 
						-pass   => $ENSEMBL_DBPASS,
                                                -dbname => $ENSEMBL_MAP,
                                                -host   => $ENSEMBL_HOST,
                                                -port   => $ENSEMBL_HOST_PORT,
                                                -ensdb  => $ENSEMBL_DB,
                                                );
	$fpc_map = $mapdb->get_Map( 'FPC' );
    }
    $sa = $db->get_StaticGoldenPathAdaptor();
};
if ( $@ ){
    print &ensembl_exception("An error occurred while loading the databases",$@);
    &EnsWeb::ensembl_exit();
}

#####################################
# Get all the contigs for this clone
#####################################

eval {
    $clone = $db->get_Clone($cloneid);
    $name = $clone->id;
	    
};

if ($@){
    print &ensembl_exception("No clone named $cloneid or error in database fetch.", $@);
    &EnsWeb::ensembl_exit();
}
    
foreach my $temp($clone->get_all_Contigs){
    push @contigs, $temp if $temp->is_static_golden;
}
@contigs = sort { $a->embl_offset <=> $b->embl_offset } @contigs;


my $c = scalar @contigs;

##################################
# Get FPC id to keep people happy
##################################

my $fpc=$fpc_map?$fpc_map->get_Clone_by_name($clone->embl_id):undef;
my $fpc_id;
if ($fpc){
    $fpc_id=$fpc->name;
}
else {
    $fpc_id="unknown";
}

#######################################################################
# OK, we have 2 possibilities here - 
#   1) We have a contigid and want to display one contig
#   2) We  want to display everything
#
#   So, find out which one we want, print out the appropriate headers,
#   do the display deed, and then print the appropriate footers.
#   Easy job, home in time for Blue Peter.
#######################################################################
my $urls = ExtURL->new;

my $embl_url = $clone->gi ? $urls->get_url('ENTREZPRO',$clone->gi)
			  : $urls->get_url('EMBL', $name);

my $clone_info=
      ( $clone->name ? "BAC/PAC <B>".$clone->name."</B>&nbsp;&nbsp;":'') .
      "Version ".$clone->version."&nbsp;&nbsp;" .
      "Sequencing Phase ".$clone->htg_phase."<BR>\n" .
      ($db->seqsite_html($clone->site)
	  ?"Sequenced by ".$db->seqsite_html($clone->site)
	  :""
      )
      ."<BR>\n";

      

if ($contigid){
    my $vc;
    my @vcontigs;
    eval {
	$vc = $sa->fetch_VirtualContig_of_contig($contigid);
    };
    if ($@){
	print &ensembl_exception("Contig $contigid either does not exist, or is not on the golden assembly path.", $@);
	&EnsWeb::ensembl_exit();
    }
    else {	
	push @vcontigs, {'vc' => $vc, 'id' => $contigid};
    }
    
    #########
    # Header
    #########
    print "<H3>Clone $cloneid - contig $contigid</H3>";
    print "<H4>FPC id : $fpc_id</H4>" if $fpc_id ne 'unknown';
    print<<EOL;
    <P>$clone_info
    <P>
    <P><B>This entry has been reannotated from an orginal Genbank <A HREF="$embl_url">source file</a></B><BR>
    Click any graphical contig feature below to access detailed feature information<BR>
    </P>
EOL

    if ($c>1){
	print qq(<P>View <A HREF="/perl/seqentryview?seqentry=$cloneid">all $c "golden" contigs</A> for clone $cloneid or a <A HREF="/perl/contigview?clone=$cloneid">contig map</A>.<BR></P><HR>);
    }
    &display_one_contig(@vcontigs);
}
else {
    my $vc;
    my @vcontigs;
   
    foreach my $temp (@contigs){
	my $id = $temp->id;
	eval {
	    $vc = $sa->fetch_VirtualContig_of_contig($id);
	};
	push @vcontigs, {'vc' => $vc, 'id' => $id} unless ($@);
    }

    #########
    # Header
    #########
    print qq!<H3>Clone $cloneid has $c contig(s)</H3>!; #"golden-path" 
    print "<H4>FPC id : $fpc_id</H4>" if $fpc_id ne 'unknown';
    print<<EOL;
    <P>$clone_info
    <P>
    <P><B>This entry has been reannotated from an orginal Genbank <A HREF="$embl_url">source file</a></B><BR>
    Click any graphical contig feature below to access detailed feature information<BR>
    </P>
    <HR>    
EOL

    &display_all_contigs(@vcontigs);
}


#########################
# Footers, and goodnight
#########################
print<<EOF;
<BR><P><center><a href="/perl/dumpcfgview/?type=clone&id=$cloneid">Dump entire clone $cloneid</a></center><BR></P><HR>
EOF

if($grpg) {
  print $grpg->end_body;
} else {
  print EnsWeb::make_cgi_footer();
}
&EnsWeb::ensembl_exit();

1;

###############################################################################
################################# END OF SCRIPT ###############################
###############################################################################

###############################################################################
#
# display_one_contig
#
#   Displays a single contig.  Quite dull, really...
###############################################################################
sub display_one_contig{
    my $contig = shift;
    my $vc = $contig->{'vc'};
    my $id = $contig->{'id'}; 
    &display_contig_gif($vc,$id);
}


###############################################################################
#
# display_all_contigs
#
#   Displays all contigs.  The epitome of the contig printers art...
###############################################################################
sub display_all_contigs{
    my @contigs = @_;
    foreach my $contig(@contigs){
	my $vc = $contig->{'vc'};
	my $id = $contig->{'id'}; 
	&display_contig_gif($vc,$id);
    }
}



###############################################################################
#
# display_contig_gif
#
#   This sub does all the actual drawing of contigs.  It also generates image
#   maps, and prints the HTML map and img code.
#
###############################################################################

sub display_contig_gif{
    my ($vc,$contig_name)=@_;
    my $cgi = new CGI;
    my %menuopts;
    my @highlight;

    #################################
    # Generate image/imagemap for vc
    #################################
    my $Config = WebUserConfig->new($cgi, 'seqentryview');
    $Config->container_width($vc->length());
    $Config->{'image_frame_colour'} = 'red';

    my $dc = Bio::EnsEMBL::DrawableContainer->new("seqentryview", $vc, $Config,\@highlight);

    my $image    = undef;
    my $imagemap = undef;

    $image = $dc->render($img_type); # always call the image first!

    if($Config->get('seqentryview','_settings','imagemap') == 1) {
	    $imagemap = $dc->render("imagemap");
    }

    my $vc_filename = "$ENSEMBL_SERVERROOT/htdocs/gfx/clone/$contig_name.$img_type";

    open(IMG_OUT, qq(>$vc_filename)) || die qq(cannot open temporary image file $vc_filename: $!\n);

    binmode IMG_OUT;
    print IMG_OUT $image;
    close(IMG_OUT);
    #############################
    # Print vc at bottom of page
    #############################
    print <<EOT;
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><TR><td bgcolor="#eeeeff">
	<dt><B><img src="/gfx/bullet.red.gif">&nbsp;Contig $contig_name:</B></dt>
	</td></tr></table><BR>
	<center><img border="0" src="/gfx/clone/$contig_name.$img_type" usemap="#$contig_name"></center>
	    <BR><BR>
	<map name="$contig_name">\n$imagemap</map>
EOT
	
    my $dump_url="/perl/dumpcfgview?type=contig&id=$contig_name"; 
    print qq(<center><a class="small" href="$dump_url">Dump this region</a></center><br><br>);
}
#####################################################################

