#!/usr/local/bin/perl

use strict;
use warnings;
use CGI qw(:standard *table *TR *th *td *ul *ol);
use File::Temp qw/ tempfile /;
use Gramene::Ontology::OntologyDB;
use Gramene::Page;
use Gramene::Utils 'pager'; 

#####################################################################

use constant EXE_NAME => '/db/ontology/search_term';
local $SIG{CHLD} = 'DEFAULT';    # for debug the system failed

my $entries_per_page = 25;

my $dbxref_urls = {
    'QTL'                => '/db/qtl/qtl_display?qtl_accession_id=[%?%]',
    'Gene'               => '/db/genes/search_gene?acc=[%?%]',
    'Ensembl rice gene'       => '/Oryza_sativa/geneview?gene=[%?%]',
    'Ensembl maize gene' => '/Zea_mays2/geneview?gene=[%?%]',
    'Ensembl arabidopsis gene' => '/Arabidopsis_thaliana/geneview?gene=[%?%]',
    'Protein'            => '/db/protein/protein_search?acc=[%?%]',
    'Map set' =>
        '/db/markers/marker_view?action=view_map_set&map_set_acc=[%?%]',
    'Marker library' =>
        '/db/markers/marker_view?action=view_library&library_id=[%?%]',
    'Marker species' =>
        '/db/markers/marker_view?action=view_species&species_id=[%?%]',
    'evidence_codes' => '/plant_ontology/evidence_codes.html#[%?%]',
    'GR_Ref'         => '/db/literature/pub_search?ref_id=[%?%]',
    'InterPro'       => 'http://www.ebi.ac.uk/interpro/IEntry?ac=[%?%]',
    'PMID' =>
        'http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=[%?%]&dopt=Abstract'

};
####################################################################
my $cgi  = CGI->new;
my $page = Gramene::Page->new( Apache->request );

my $doc_root     = Apache->request->document_root;
my $download_dir = '/tmp/ontology/download';

# Connect to the database
my $db = Gramene::Ontology::OntologyDB->new();

my $page_no = $cgi->param( 'page_no' ) || 1;
my $input = $cgi->param( 'id' );

$input =~ s/^\s+|\s+$//g;
my $id = $input ? $db->get_termID( $input ) : undef;
my ( $name, $term_type_id, $term_type, $accession, $is_obsolete )
    = $db->get_term( $id )
    if $id;

my @term_associations;
if ( $id ) {
    my $obj_type    = $cgi->param( 'object_type' )    || '';
    my $obj_species = $cgi->param( 'object_species' ) || '';
    my $order_by    = $cgi->param( 'order_by' )       || '';
    @term_associations
        = $db->get_term_associations( $id, $obj_type, $obj_species,
        $order_by );
}

print $cgi->header;
#########################################################
if ( @term_associations && scalar( @term_associations ) > 0 ) {
    print $page->start_html( -title => "Ontology $input Association" );
    print $page->start_body;
    print_search_area();
    print h1(
        "Term <i>$name</i> (",
        a( { href => EXE_NAME . "?id=$accession" }, $accession ),
        ") Associations"
    );
    my $download_filename
        = make_download_file( $accession, \@term_associations, $doc_root,
        $download_dir );
    print_associations( \@term_associations, $page_no, $cgi,
        $entries_per_page, $dbxref_urls, $download_filename );

    print $page->end_body;

}
else {
    print $page->start_html( -title => "No association for $input" );
    print $page->start_body;
    print_search_area();
    print h1( "Sorry! Cannot find any association for <i>$input</i>" );
    print $page->end_body;
}

sub print_associations {
    my ( $associations_ref, $page_no, $cgi, $entries_per_page, $dbxref_urls,
        $download_filename )
        = @_;

    my $page_url = $cgi->url( -relative => 1, -query => 1 );
    my $this_url = $page_url;    # script url
    $this_url =~ s/[;&]?page_no=\d+//;     # remove page_no for resetting
    $this_url =~ s/[;&]?order_by=\w+//;    # remove order_by for resetting

    my ( $pager, $data );
    ( $pager, $data ) = pager(
        current_page     => $page_no,
        url              => $page_url,
        entries_per_page => $entries_per_page,
        data             => $associations_ref,
    );

    print start_table(
        {
            -class       => 'data-table',
            -width       => '95%',
            -align       => 'center'
        }
    );
    print TR(
        { -align => "center" },
        td( { -colspan => '7' }, $pager ),
        td(
            { -align => 'left' },
            start_form(
                -method => 'GET',
                -action => "$download_filename"
            ),
            submit( -value => 'Download' ),
            end_form()
        )
    );

    print TR(
        { -align => "left" },
        th(
            a( { -href => $this_url . "&order_by=term_name" }, 'Term Name' )
        ),
        th( 'Object Type' ),
        th(
            a(
                { -href => $this_url . "&order_by=object_accession_id" },
                'Object Accession ID'
            )
        ),
        th(
            a(
                { -href => $this_url . "&order_by=object_symbol" },
                'Object Symbol'
            )
        ),
        th(
            a(
                { -href => $this_url . "&order_by=object_name" },
                'Object Name'
            )
        ),
        th( 'Object Synonyms' ),
        th(
            a(
                { -href => $this_url . "&order_by=object_species" },
                'Object Species'
            )
        ),
        th( 'Evidence' )
    );

    my $count = ( $page_no - 1 ) * $entries_per_page + 1;
    foreach my $assocRef ( @$data ) {
        my $obj_link = $dbxref_urls->{ $assocRef->{'object_type'} };

        # replace template to real value
        $obj_link =~ s/\Q[%?%]/$assocRef->{'object_accession_id'}/;

        my $evidences = $assocRef->{'evidences'};
        my @evidences_links;
        my @evn_codes = split( /;/, $evidences );
        foreach my $evn_code ( @evn_codes ) {
            my $evn_code_link;
            if ( $evn_code =~ /(.+)\((.+)\)/ ) {
                my ( $code, $xref ) = ( $1, $2 );
                my $code_link = $dbxref_urls->{'evidence_codes'};
                $code_link =~ s/\Q[%?%]/$code/;
                $code_link = '<a href="' . $code_link . '">' . $code . '</a>';
                my @xref_links;
                my @xrefs = split( /\|/, $xref );

                foreach my $x ( @xrefs ) {
                    my ( $dbx, $dbxid ) = split( /:/, $x );
                    my $dbx_link = $dbxref_urls->{$dbx};
                    if ( $dbx_link ) {
                        $dbx_link =~ s/\Q[%?%]/$dbxid/;
                        $dbx_link
                            = '<a href="' . $dbx_link . '">' . $x . '</a>';
                    }
                    else {
                        $dbx_link = $x;
                    }
                    push @xref_links, $dbx_link;
                }

                # hide the dbxref links (protein has many dbxrefs)
                #$evn_code_link = "$code_link(".join('|',@xref_links).')';
                $evn_code_link = "$code_link";
            }
            else {
                $evn_code_link = $evn_code;
            }
            push @evidences_links, $evn_code_link;
        }

        my $evidences_link = join( ";", @evidences_links );

        my $class = $count % 2 == 0 ? 'roweven' : 'rowodd';
        print start_TR( { -class => $class } );

        print td(
            a(
                {
                    -href => EXE_NAME . '?id=' . $assocRef->{'term_accession'}
                },
                $assocRef->{'term_name'}
            )
        );
        print td( $assocRef->{'object_type'} );
        print td(
            a( { -href => $obj_link }, $assocRef->{'object_accession_id'} ) );
        print td( $assocRef->{'object_symbol'} );
        print td( $assocRef->{'object_name'}     || '&nbsp;&nbsp;' );
        print td( $assocRef->{'object_synonyms'} || '&nbsp;&nbsp;' );
        print td( $assocRef->{'object_species'} );

        print td( $evidences_link );

        print end_TR;
        $count++;
    }

    print end_table;

}

sub print_search_area {
    my $self = url( -relative => 1 );

    print <<SMALLBAR;
<table>
  <tr>
    <td align="LEFT">&nbsp;<img src="/images/icons/grain_icon.jpg" alt="grain_icon" height=16 width=16 align="top">
    </td>
    <td align="LEFT">
        &nbsp;<a href="/plant_ontology/index.html#ontology" class="gopage"><b>Current Ontologies</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#doc" class="gopage"><b>Documentation</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#evi" class="gopage"><b>Evidence code</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#ftp" class="gopage"><b>FTP</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#sub" class="gopage"><b>Ontology suggestion</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#assoc" class="gopage"><b>Associations</b></a>&nbsp; 
        |&nbsp;<a href="/plant_ontology/index.html#pub" class="gopage"><b>Publications</b></a>&nbsp;
        |&nbsp;<a href="/tutorials/ontologies.html" class="gopage"><b>Tutorial</b></a>  &nbsp;
       |</b>&nbsp;<a href="/fom/cache/1.html" class="gopage"><b>FAQ</b></a>  &nbsp;
       |</b>&nbsp;<a href="/documentation/ontology_help.html" class="gopage"><b>HELP</b></a>  &nbsp;
 
    </td>
  </tr>
</table>
<p></p>
        <form action="/db/ontology/search" method=get name=f>
          <table align=center border=0 cellspacing=0 cellpadding=1 width='98%'>
            <tr>
            <th colspan=3 align=center class=searchtitle>Ontology Database</th>
            </tr>
            <tr align=center class=searchbody>
              <td align=center width=30%><span class="alert">Type ID or keyword to search</span></td>
              <td align=left width=40%><input type=text value="" framewidth=4 name=query size=55 maxlength=256></td>
              <td align=center width=30%>&nbsp;<input name=btn type=submit value="Search"> &nbsp;<input name=Clear type=reset value="Clear">
                                                                                                                             
              </td>
                                                                                                                             
                                                                                                                             
            </tr>
            <tr class=searchbody>
                                                                                                                             
              <td align=center nowrap width=30%>
              select ontology (optional) &nbsp;
              </td>
              <td align=left nowrap width=30%>
 
                 <input type=checkbox name=ontology_type value="GO">Gene (GO)&nbsp;
                 <input type=checkbox name=ontology_type value="PO">Plant structure (PO)&nbsp;
                 <input type=checkbox name=ontology_type value="GRO">Growth stage (GRO)<br>
                 <input type=checkbox name=ontology_type value="TO">Trait (TO) &nbsp;&nbsp;
                 <input type=checkbox name=ontology_type value="EO">Environment (EO)&nbsp;&nbsp;

                 <input type=checkbox name=ontology_type value="GR_tax">Taxonomy(GR_tax)
              </td>
              <td align=center width=30%>[e.g. <a href="/db/ontology/search?query=flower&btn=Search">flower</a> or <a href="/db/ontology/search_term?id=TO:0000303&ontology_type=TO&btn=Search">TO:0000303</a>]
                          </td>
            </tr>
<tr><td>&nbsp;</td></tr>
<tr>
<td align="center" valign="CENTER" colspan="3">
<hr width="100%">
</tr>
</td>
          </table>
        </form>


SMALLBAR

}

sub make_download_file {
    my ( $accession, $associationsRef, $doc_root, $download_dir ) = @_;
    my $template_name = "association_" . $accession . "_XXXXX";

    my ( $fh, $filename )
        = tempfile( $template_name, DIR => $doc_root . '' . $download_dir );
    print $fh '!',
        join(
        "\t",
        (
            'Term Name',
            'Term Accession',
            'Object Type',
            'Object Accession ID',
            'Object Symbol',
            'Object Name',
            'Object Synonyms',
            'Object Species',
            'Evidence'
        )
        ),
        "\n";

    foreach my $assocRef ( @$associationsRef ) {
        print $fh join(
            "\t",
            (
                $assocRef->{'term_name'},
                $assocRef->{'term_accession'},
                $assocRef->{'object_type'},
                $assocRef->{'object_accession_id'},
                $assocRef->{'object_symbol'},
                $assocRef->{'object_name'},
                $assocRef->{'object_synonyms'},
                $assocRef->{'object_species'},
                $assocRef->{'evidences'}
            )
            ),
            "\n";

    }
    close $fh;
    my $old_filename = $filename;
    $filename =~ s/_\w+?$//;    # remove the tmp file postfix
    $filename =~ s/:/_/;  # the : inside accession is illegal char for windows
    my $txt_file = $filename . '.txt';
    my $zip_file = $filename . '.zip';

    rename( $old_filename, $txt_file )
        or die "Can't rename $old_filename to $txt_file: $!";
    my @command_args = ( "zip", "-j", $zip_file, $txt_file );
    system( @command_args ) == 0 or die "zip system failed: $?,$!";

    # file name is absolute path,need get relative path for url
    my @fnames = split( "/", $filename );
    my $url_filename
        = $download_dir . '/' . $fnames[ scalar( @fnames ) - 1 ] . '.zip';
    return $url_filename;
}
