#!/usr/local/bin/perl

# $Id: marker_view,v 1.86 2007/06/05 19:27:59 kclark Exp $

use strict;
use Cache::FileCache;
use CGI;
use CGI::Ajax;
use Data::Dumper;
use MLDBM qw(DB_File Storable);
use Fcntl;
use Gramene::Config;
use Gramene::CDBI::Markers;
use Gramene::Marker::DB;
use Gramene::Page;
use Gramene::Utils qw[ pager iterative_search_values ];
use List::MoreUtils qw( uniq );
use Template;
use Readonly;

Readonly my $COMMA      => q{,};
Readonly my $DASH       => q{-};
Readonly my $TEXT_HTML  => 'text/html';
Readonly my $TEXT_PLAIN => 'text/plain';
Readonly my $PAGE_SIZE  => 25;
Readonly my $VERSION    => sprintf '%d.%02d', 
                           qq$Revision: 1.86 $ =~ /(\d+)\.(\d+)/;
Readonly my %DEFAULT    => (
    search_cache        => '/tmp/marker-search-cache',
    output_type         => $TEXT_HTML,
);

delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';

my %CACHE;

my $q   = CGI->new;
my $pjx = CGI::Ajax->new( 
    species_list   => \&set_species_list,
    germplasm_list => \&set_germplasm_list,
    library_list   => \&set_library_list,
    map_set_list   => \&set_map_set_list,
);

$pjx->js_encode_function('encodeURIComponent');

my ( $t, $page, $html, $output_type, $marker_types, $all_species, 
    @genera, $map_set_species, $analyses );
eval { 
    #
    # Get config info, template object, db handle, Gramene::Page, etc.
    #
    my $cfile  = Gramene::Config->new;
    my $config = $cfile->get('markers');
    my $mdb    = Gramene::Marker::DB->new;
    my $db     = $mdb->db;
    $page      = Gramene::Page->new( Apache->request );

    my $search_cache = $config->{'search_cache'} || $DEFAULT{'search_cache'};
    tie %CACHE, 'MLDBM', $search_cache, O_RDWR | O_CREAT, 0666 
        or die "Unable to tie cache to '$search_cache': $!\n";

    #
    # Search
    #
    my @marker_type_ids     = ( $q->param('marker_type_id')     );
    my @species_ids         = ( $q->param('species_id')         );
    my @library_ids         = ( $q->param('library_id')         );
    my @germplasm_ids       = ( $q->param('germplasm_id')       );
    my @analysis_ids        = ( $q->param('analysis_id')        );
    my @map_set_species_ids = ( $q->param('map_set_species_id') );
    my @map_set_ids         = ( $q->param('map_set_id')         );
    my @selected_genera     = ( $q->param('genus')              );
    my $marker_id           = $q->param('marker_id');
    my $xref_type           = $q->param('xref_type');
    my $xref_value          = $q->param('xref_value');
    my $cmap_feature_aid    = $q->param('cmap_feature_aid');
    my $query               = $q->param('marker_name') || '';
    my $action              = $q->param('action')      || '';
    my $order_by            = $q->param('order_by')    || '';
    my $url                 = $q->url( -full => 1, -query => 1 );
    $url                    =~ s/[;&]?table_only=1//;

    if ( $q->param('fname') ) { # Ajax request?
        exit(0);
    }

    unless ( $action ) {
        my %args = $q->Vars;
        if ( %args ) {
            $action = scalar keys %args == 1 && $args{'power_search'}
                      ? 'search_form' : 'marker_search';
        }
        else {
            $action = 'search_form';
        }
    }

    my $summary   = get_data_summary( $db, $config );
    $marker_types = $summary;

    $all_species  = $db->selectall_arrayref(
        q[
            select   s.species_id, s.species, s.common_name
            from     species s
            order by species
        ],
        { Columns => {} }
    );

    my %genera;
    for my $s ( @$all_species ) {
        if ( $s->{'species'} =~ /^(\S+)/ ) {
            $genera{ $1 }++;
        }
    }
    @genera = sort keys %genera;

    $map_set_species  = $db->selectall_arrayref(
        q[
            select   distinct s.species_id, s.species, s.common_name
            from     species s, map_set ms
            where    s.species_id=ms.species_id 
            order by species
        ],
        { Columns => {} }
    );

#    $analyses  = $db->selectall_arrayref(
#        q[
#            select   distinct a.analysis_id, a.analysis_name
#            from     analysis a, marker m
#            where    a.analysis_id=m.analysis_id
#            order by analysis_name
#        ],
#        { Columns => {} }
#    );

    $t         = Template->new( 
        INCLUDE_PATH => [
            $config->{'template_dir'},
            "$config->{'template_dir'}/../common",
        ],
        WRAPPER      => 'wrapper.tmpl',
        VARIABLES    => {
            cgi             => $q,
            gramene_page    => $page,
            marker_types    => $marker_types,
            all_species     => $all_species,
            genera          => \@genera,
            analyses        => $analyses,
            map_set_species => $map_set_species,
            page_size       => $PAGE_SIZE,
            ajax_javascript => $pjx->show_javascript,
        },
    );

    $query =~ s/%/*/g;
    if ( $action eq 'marker_search' && !$query && !$marker_id ) {
        $query = '*';
        $q->param( 'marker_name', $query ); 
    }

    my ( $markers, $count );
    if ( $action eq 'search_form' ) {
        $t->process( 'search.tmpl', { data_summary  => $summary, }, \$html ) 
            or die $t->error;
    }
    elsif ( $action eq 'marker_search' ) {
        if ( $q->param('marker_type') ) {
            push @marker_type_ids,
                $mdb->get_marker_type_id( $q->param('marker_type') );
        }

        if ( $q->param('species') ) {
            push @species_ids, $mdb->get_species_id( $q->param('species') );
        }

        @marker_type_ids = map { $_ || () } @marker_type_ids;
        @species_ids     = map { $_ || () } @species_ids;

        if ( @marker_type_ids ) {
            $q->param( 'marker_type_id', join($COMMA, @marker_type_ids) );
        }

        if ( @species_ids ) {
            $q->param( 'species_id', join($COMMA, @species_ids) );
        }

        my %args = (
            marker_id        => $marker_id               ||  0,
            marker_name      => $query,
            marker_type_id   => \@marker_type_ids,
            genus            => \@selected_genera,
            species_id       => \@species_ids,
            library_id       => \@library_ids,
            germplasm_id     => \@germplasm_ids,
            analysis_id      => \@analysis_ids,
            map_set_id       => \@map_set_ids,
            xref_type        => $xref_type               || '',
            xref_value       => $xref_value              || '',
            cmap_feature_aid => $cmap_feature_aid        || '',
            is_sequence      => $q->param('is_sequence') || 0,
            order_by         => $q->param('order_by')    || '',
            timeout          => $config->{'timeout'}     || 30,
            current_page     => $q->param('page_no')     || 1,
            limit_no         => $q->param('download') ? -1 : $PAGE_SIZE,
        );

        if ( !@map_set_ids && @map_set_species_ids ) {
            $args{'map_set_species_id'} = \@map_set_species_ids;
        }

        for my $v ( 
            iterative_search_values( $query, { no_leading_wildcard => 1 } ) 
        ) {
            $args{'marker_name'} = $v;
            ( $count, $markers ) = $mdb->marker_search( %args );

            if ( $count > 0 ) {
                $q->param( 'marker_name', $v );
                last;
            }
        }

        if ( $count == 1 ) {
            $marker_id = $markers->[0]{'marker_id'};
            $markers   = [];
        }

        if ( $marker_id ) {
            my $marker = Gramene::CDBI::Markers::Marker->retrieve( $marker_id )
                or die "Bad marker id ($marker_id)\n";

            $marker->{'details'} = $mdb->get_marker_details(
                marker_id => $marker_id
            );

            $marker->{'images'} = $mdb->get_marker_images(
                marker_id => $marker_id
            );

            $marker->{'seq'} = $mdb->get_marker_sequence(
                marker_id => $marker_id
            );

            $marker->{'synonyms'} = $mdb->get_marker_synonyms(
                marker_id   => $marker_id,
                process_url => 1,
            );

            $marker->{'sorted_mappings'} = $mdb->get_marker_mappings(
                marker_id   => $marker_id,
            );

            my %mappings_display;
            for my $m ( @{ $marker->{'sorted_mappings'} } ) { 
                my $inc = 
                    defined $m->{'marker_start'} && 
                    defined $m->{'marker_end'} && 
                    ($marker->{'seq'} 
                        || $marker->{'details'}{'length_basepair'})
                    ? 2 : 1;

                $mappings_display{'species'}{ $m->{'species_id'} } += $inc;
                $mappings_display{'map_type'}{ 
                    $m->{'species_id'} }{ $m->{'map_type_id'} } += $inc;
                $mappings_display{'map_set'}{ $m->{'map_set_id'} } += $inc;
            }

            $marker->{'correspondences'} = $mdb->get_marker_correspondences(
                marker_id   => $marker_id,
            );

            if ( 
                my $url_template 
                = $marker->display_synonym->synonym_type->url_template 
            ) {
                $marker->{'display_synonym_url'} = sprintf(
                    $url_template, $marker->display_synonym->to_string
                );
            }

            $marker->{'xrefs'} = $mdb->get_xrefs(
                table_name  => 'marker',
                record_id   => $marker_id,
                process_url => 1,
            );

            $marker->{'library_xrefs'} = $mdb->get_xrefs(
                table_name  => 'library',
                record_id   => $marker->library->id,
                process_url => 1,
            );

            $q->param('marker_name',    $marker->display_synonym->to_string);
            $q->param('marker_type_id', $marker->marker_type_id->id);
            $q->param('species_id',     $marker->source_species_id->id);

            $t->process(
                'marker-details.tmpl',
                {
                    mdb              => $mdb,
                    marker           => $marker,
                    cmap_datasource  => $config->{'cmap_datasource'},
                    mappings_display => \%mappings_display,
                },
                \$html
            ) or die $t->error;
        }
        elsif ( @$markers && $q->param('download') ) {
            for my $m ( @$markers ) {
                $m->{'marker_synonyms'} = join ',', 
                    map { $_->{'marker_name'} }
                    $mdb->get_marker_synonyms( marker_id => $m->{'marker_id'} )
                ;
            }

            my @fld_names = qw[ 
                marker_id marker_type species marker_name marker_synonyms 
            ];
            $html = join( "\t", @fld_names ) . "\n";
            for my $m ( @$markers ) {
                $html .= join( "\t", map { $m->{ $_ } } @fld_names ) . "\n";
            }
            $output_type = $TEXT_PLAIN;
        }
        else {
            my ( $pager, $summary );
            if ( @$markers ) {
                my $url = $q->url( -full => 1, -query => 1 );
                $url =~ s/[;&]?table_only=1//;
                ( $pager ) = pager(
                    count            => $count,
                    url              => $url,
                    entries_per_page => $PAGE_SIZE,
                    current_page     => $q->param('page_no') || 1,
                    object_name      => 'Markers',
                );

                for my $m ( @$markers ) {
                    $m->{'synonyms'} = uniq( 
                        map { $_->{'marker_name'} }
                        $mdb->get_marker_synonyms(
                            marker_id => $m->{'marker_id'}
                        )
                    );
                }
            }

            $t->process(
                'search.tmpl',
                {
                    markers => $markers,
                    pager   => $pager,
                },
                \$html
            ) or die $t->error;
        }
    }
    elsif ( $action eq 'view_library' ) {
        my $lib_id = $q->param('library_id') 
                     or die "No library id\n";
        my $lib    = Gramene::CDBI::Markers::Library->retrieve(
            $lib_id
        ) or die "Bad marker library id ($lib_id)\n";

        $lib->{'xrefs'} = $mdb->get_xrefs(
            table_name  => 'library',
            record_id   => $lib->id,
            process_url => 1,
        );

        $t->process(
            'view-library.tmpl', { mdb => $mdb, library => $lib }, \$html
        ) or die $t->error;
    }
    elsif ( $action eq 'view_germplasm' ) {
        my $germplasm = $mdb->view_germplasm( $q->Vars );

        $t->process(
            'view-germplasm.tmpl', { germplasm => $germplasm }, \$html
        ) or die $t->error;
    }
    elsif ( $action eq 'view_map_type' ) {
        my $map_type = $mdb->view_map_type( $q->Vars );

        my ( $pager, $data ) = pager(
            data             => $map_type->{'sorted_map_sets'},
            url              => $url,
            entries_per_page => $PAGE_SIZE,
            current_page     => $q->param('page_no') || 1,
            object_name      => 'Map Sets',
        );

        $map_type->{'sorted_map_sets'} = $data;

        $t->process(
            'view-map-type.tmpl', 
            { 
                map_type => $map_type,
                pager    => $pager,
            }, 
            \$html
        ) or die $t->error;
    }
    elsif ( $action eq 'view_species' ) {
        my $species = $mdb->view_species( $q->Vars );

        my ( $pager, $data ) = pager(
            data             => $species->{'sorted_map_sets'},
            url              => $url,
            entries_per_page => $PAGE_SIZE,
            current_page     => $q->param('page_no') || 1,
            object_name      => 'Map Sets',
        );

        $species->{'sorted_map_sets'} = $data;

        $t->process(
            'view-species.tmpl', 
            { 
                species => $species,
                pager   => $pager,
            }, 
            \$html
        ) or die $t->error;
    }
    elsif ( $action eq 'view_map_set' ) {
        my $ms    = $mdb->view_map_set( 
            $q->Vars, 
            include_mapping_details => 1 
        ) or die 'Bad map set identifier';
        my $cache = Cache::FileCache->new;

        my $map_set;
        eval {
            $map_set = $cache->get( $ms->id );
        };

        if ( !$map_set || $q->param('recache') ) {
            $map_set = cache_map_set( $mdb, $ms->id, $cache );
        }

        my ( $pager, $data ) = pager(
            data             => $map_set->{'sorted_maps'},
            url              => $url,
            entries_per_page => $PAGE_SIZE,
            current_page     => $q->param('page_no') || 1,
            object_name      => 'Maps',
        );

        $map_set->{'sorted_maps'} = $data;

        $t->process(
            'view-map-set.tmpl', 
            { 
                map_set => $map_set,
                pager   => $pager,
            }, 
            \$html
        ) or die $t->error;
    }
    elsif ( $action eq 'view_map_sets' ) {
        my $species_id   = $q->param('species_id')  || 0;
        my $map_type_id  = $q->param('map_type_id') || 0;
        my @map_set_accs = map { split /,/, $_ } $q->param('map_set_acc');
        my $order_by     = $q->param('order_by')    
                        || 'map_type,species,map_set_name';

        if ( $order_by eq 'num_maps' ) {
            $order_by .= ' desc';
        }

        my $sql = q[
            select    s.species_id,
                      s.species,
                      mt.map_type_id,
                      mt.map_type,
                      ms.map_set_id,
                      ms.map_set_name,
                      ms.cmap_map_set_accession,
                      count(map.map_id) as num_maps
            from      species s, map_type mt, map_set ms
            left join map
            on        ms.map_set_id=map.map_set_id
            where     ms.species_id=s.species_id
            and       ms.map_type_id=mt.map_type_id
        ];

        if ( $species_id ) {
            $sql .= " and ms.species_id=$species_id ";
        }

        if ( $map_type_id ) {
            $sql .= " and ms.map_type_id=$map_type_id ";
        }

        if ( @map_set_accs ) {
            $sql .= ' and ms.cmap_map_set_accession in ( ' .
                join(', ', map { qq['$_'] } @map_set_accs ) .
            ') ';
        }

        $sql .= qq[
            group by  s.species_id,
                      s.species,
                      mt.map_type_id,
                      mt.map_type,
                      ms.map_set_id,
                      ms.map_set_name,
                      ms.cmap_map_set_accession
            order by $order_by
        ];

        my $map_sets = $db->selectall_arrayref( $sql, { Columns => {} } );

        my ( $pager, $data ) = pager(
            data             => $map_sets,
            url              => $url,
            entries_per_page => $PAGE_SIZE,
            current_page     => $q->param('page_no') || 1,
            object_name      => 'Map Sets',
        );

        my $form_species = $db->selectall_arrayref(
            q[
                select   distinct s.species_id, s.species, s.common_name
                from     species s, map_set ms
                where    s.species_id=ms.species_id
                order by species
            ],
            { Columns => {} }
        );

        my $form_map_types = $db->selectall_arrayref(
            q[
                select   distinct mt.map_type_id, mt.map_type
                from     map_type mt, map_set ms
                where    mt.map_type_id=ms.map_type_id
                order by map_type
            ],
            { Columns => {} }
        );

        $t->process(
            'view-map-sets.tmpl', 
            { 
                map_sets  => $data,
                pager     => $pager,
                species   => $form_species,
                map_types => $form_map_types,
            }, 
            \$html
        ) or die $t->error;
    }
    elsif ( $action eq 'view_map' ) {
        my $map = $mdb->view_map( $q->Vars );

        my ( $pager, $data ) = pager(
            data             => $map->{'sorted_mappings'},
            url              => $url,
            entries_per_page => $PAGE_SIZE,
            current_page     => $q->param('page_no') || 1,
            object_name      => 'Mappings',
        );

        $map->{'sorted_mappings'} = $data;

        $t->process(
            'view-map.tmpl', 
            { 
                map   => $map,
                pager => $pager,
            }, 
            \$html
        ) or die $t->error;
    }
    elsif ( $action eq 'view_marker_type' ) {
        my $marker_type = $mdb->view_marker_type(
            marker_type    => $q->param('marker_type')    || '',
            marker_type_id => $q->param('marker_type_id') || 0,
            order_by       => $q->param('order_by')       || '',
            no_markers     => 1,
        );

        $t->process(
            'view-marker-type.tmpl', { marker_type => $marker_type }, \$html
        ) or die $t->error;
    }
    elsif ( $action eq 'view_analysis' ) {
        my $analysis = $mdb->view_analysis( 
            analysis_id => $q->param('analysis_id')
        );

        $t->process(
            'view-analysis.tmpl',
            {
                analysis => $analysis,
                title    => 'View Analysis &quot;'.
                            $analysis->{'analysis_name'}.'&quot;',
            },
            \$html
        ) or die $t->error;
    }
    elsif ( $action eq 'init_cache' ) {
        my $map_set_ids = $mdb->db->selectcol_arrayref(
            'select map_set_id from map_set'
        );

        my $cache = Cache::FileCache->new;

        for my $map_set_id ( @$map_set_ids ) {
            cache_map_set( $mdb, $map_set_id, $cache );
        }
    }
    else {
        $html = "Unknown action: $action\n";
    }
};

#
# Error handler
#
if ( $@ ) {
    if ( $t ) {
        $t->process(
            'error.tmpl',
            {
                title   => 'Error',
                err_msg => $@,
            },
            \$html
        ) or $html = $t->error;
    }
    else {
        $output_type = $TEXT_PLAIN;
        $html        = $@;
    }
}

if ( $output_type eq $TEXT_PLAIN || $q->param('table_only') ) {
    print $q->header( $output_type ), $html;
}
else {
    print $pjx->build_html( $q, $html );
}

exit 0;

# ----------------------------------------------------
sub cache_map_set {
    my ( $mdb, $map_set_id, $cache ) = @_;

    my $map_set = $mdb->view_map_set( 
        map_set_id              => $map_set_id,
        include_mapping_details => 1,
    );

    $map_set->{'xrefs'} = $mdb->get_xrefs(
        table_name  => 'map_set',
        record_id   => $map_set->id,
        process_url => 1,
    );

    eval {
        $cache->set( $map_set->id, $map_set );
    };

    if ( my $err = $@ ) {
        print STDERR "Error caching map set: $err\n";
    }

    return $map_set;
}

# ----------------------------------------------------
sub set_species_list {
    my @genera = @_ or return '';

    my $txt = q!
        <select multiple id="species_list" name="species_id" size="5"
        onclick="resetdiv('library_div', 'Loading...');
        resetdiv('germplasm_div', 'Loading...'); 
        library_list( ['species_list'], ['library_div'] ); 
        germplasm_list( ['species_list'], ['germplasm_div'] ); return true;"
    !;

    for my $genus ( @genera ) {
        $genus =~ s/\s\[.*\]$//g;
        $genus =~ s/\**//g;
        for my $species ( 
            Gramene::CDBI::Markers::Species->search_like(
                { species => "$genus%" }
            )
        ) {
            $txt .= sprintf(
                '<option value=%s>%s</option>', 
                $species->id, 
                $species->species,
            );
        }
    }

    $txt .= '</select>';

    return $txt;
}

# ----------------------------------------------------
sub set_map_set_list {
    my @species_ids = @_ or return '';
    
    my @map_sets;
    for my $species_id ( @species_ids ) {
        push @map_sets, Gramene::CDBI::Markers::MapSet->search( 
            { species_id => $species_id } 
        );
    }

    my $txt = '';
    if ( @map_sets ) {
        my $num_sets = scalar @map_sets;
        my $size     = $num_sets < 6 ? 5 : 10;
        $txt = qq!
            <em>Select map set:</em><br>
            <select multiple id="map_set_list" name="map_set_id" size="$size">
        !;

        @map_sets = 
            map  { $_->[0] }
            sort { $a->[1] cmp $b->[1] }
            map  { [
                $_,
                join($DASH, 
                    $_->species->species,
                    $_->map_type->map_type,
                    $_->map_set_name 
                ),
            ] }
            @map_sets;
            
        for my $ms ( @map_sets ) {
            $txt .= sprintf(
                '<option value=%s>%s-%s-%s</option>', 
                $ms->id, 
                $ms->species->species,
                $ms->map_type->map_type,
                $ms->map_set_name 
            );
        }

        $txt .= '</select>';
    }
    else {
        $txt .= '<em>No map sets</em>';
    }

    return $txt;
}

# ----------------------------------------------------
sub set_library_list {
    my @species_ids = @_ or return '';
    
    my @libraries;
    for my $species_id ( @species_ids ) {
        push @libraries, Gramene::CDBI::Markers::Library->search( 
            { species_id => $species_id } 
        );
    }

    my $txt = '';
    if ( @libraries ) {
        my $num_libs = scalar @libraries;
        my $size     = $num_libs < 6 ? 5 : 10;
        $txt = qq!
            <select multiple id="library_list" name="library_id" size="$size">
        !;

        for my $lib ( @libraries ) {
            $txt .= sprintf(
                '<option value=%s>[%s] %s</option>', 
                $lib->id, 
                $lib->species->species,
                $lib->library_name 
            );
        }

        $txt .= '</select>';
    }
    else {
        $txt .= '<em>No libraries</em>';
    }

    return $txt;
}

# ----------------------------------------------------
sub set_germplasm_list {
    my @species_ids = @_ or return '';
    
    my @germplasm;
    for my $species_id ( @species_ids ) {
        push @germplasm, Gramene::CDBI::Markers::Germplasm->search( 
            { species_id => $species_id } 
        );
    }
    
    my $txt = '';
    if ( @germplasm ) {
        my $num_germ = scalar @germplasm;
        my $size     = $num_germ < 6 ? 5 : 10;
        $txt = qq!
         <select multiple id="germplasm_list" name="germplasm_id" size="$size">
        !;

        for my $g ( @germplasm ) {
            $txt .= sprintf(
                '<option value=%s>[%s] %s</option>', 
                $g->id, 
                $g->species->species,
                $g->germplasm_name 
            );
        }

        $txt .= '</select>';
    }
    else {
        $txt = '<em>No germplasm</em>';
    }

    return $txt;
}

# ----------------------------------------------------
sub get_data_summary {
    my $db      = shift;
    my $config  = shift;
    my $cache   = $CACHE{'data_summary'} || {};
    my $expires = $cache->{'expires'}    ||  0;
    my $summary = $cache->{'data'};

    if ( 
        ! defined $summary # no data
        || 
        ( ! $config->{'no_expire'} && time() > $expires ) # expired
    ) { 
        $summary = $db->selectall_arrayref(
            q[
                select   count(m.marker_id) as count, 
                         t.marker_type_id,
                         t.marker_type,
                         t.is_sequence
                from     marker m, 
                         marker_type t
                where    m.marker_type_id=t.marker_type_id
                group by marker_type, marker_type_id
                order by marker_type, count
            ],
            { Columns => {} }
        );

        # See "BUGS" section of MLDBM manpage for explanation of $tmp
        my $expire  = $config->{'expire_in_seconds'} || 60 * 60;
        my $tmp     = $CACHE{'data_summary'};
        $tmp        = {
            data    => $summary,
            expires => time() + $expire,
        };

        $CACHE{'data_summary'} = $tmp;
    }

    return $summary;
}

# ----------------------------------------------------

=pod

=head1 NAME

marker_view - CGI interface for querying marker database

=head1 DESCRIPTION

This is a CGI script for querying the marker database.

When called with no arguments, the script will return a summary of the
contents of the marker db, showing a count of markers by marker type.

The script accepts the following arguments (via the query string):

=over 4

=item * action

The action to perform, one of the following:

=over 2

=item * search_form

=item * marker_search

=item * view_germplasm

=item * view_map_type

=item * view_species

=item * view_map_set

=item * view_map

=item * view_marker_type

=item * view_analysis

=back

The actions are pretty self-explanatory.

=item * marker_id

A marker's unique ID (the primary key of the "marker" table,
actually).  Used for "marker details" view.

=item * marker_type_id

Used to view marker type details.

=item * species_id

Used in marker search or to view species details.

=item * germplasm_id

Used in marker search (not yet) or to view germplasm details.

=item * xref_type

Used in marker search to find all markers having a particular xref
(e.g., GenBank xref).

=item * xref_value

Used in marker search in conjunction with "xref_type" to find marker's
with a particular xref value (e.g., "GenBank" accession of
"AB993245").

=item * cmap_feature_aid

CMap feature accession ID.

=item * marker_name

Used in marker search, may be a comma-separated string to denote
multiple markers to search for (e.g., "RZ113,RM990").

=back

=head1 SEE ALSO

Gramene::Marker::DB.

=head1 AUTHOR

Ken Youens-Clark E<lt>kclark@cshl.eduE<gt>.

=head1 COPYRIGHT

Copyright (c) 2006 Cold Spring Harbor Laboratory

This library is free software;  you can redistribute it and/or modify 
it under the same terms as Perl itself.

=cut
