#!/usr/local/bin/perl 


#  SNP_util module - general tasks concerning the SNP database
#  for sql see SNP_util.sql_lib


#######################################################################
# This software has been created by Genome Research Limited (GRL).    # 
# GRL hereby grants permission to use, copy, modify and distribute    # 
# this software and its documentation for non-commercial purposes     # 
# without fee at the user's own risk on the basis set out below.      #
# GRL neither undertakes nor accepts any duty whether contractual or  # 
# otherwise in connection with the software, its use or the use of    # 
# any derivative, and makes no representations or warranties, express #
# or implied, concerning the software, its suitability, fitness for   #
# a particular purpose or non-infringement.                           #
# In no event shall the authors of the software or GRL be responsible # 
# or liable for any loss or damage whatsoever arising in any way      # 
# directly or indirectly out of the use of this software or its       # 
# derivatives, even if advised of the possibility of such damage.     #
# Our software can be freely distributed under the conditions set out # 
# above, and must contain this copyright notice.                      #
#######################################################################


=head1 SNP_util module

 Contains general tasks concerning SNP (and other) databases.
 Corresponding SQL is in SNP_util.sql_lib


=cut



package SNP_util;
use sql_engine;
use strict;


# map statusdicts to barcode prefixes.  Doesn't specify which DB each table is in,
# need to consult barcode_prefix.  Can we generate dynamically from DB?


use vars qw($STATUS_DICTS);

=head1 SNP_util::STATUS_DICTS

 Hash defining which statusdict table corresponds to a barcode prefix.
 e.g. PC/pcrplatestusdict.

=cut

$STATUS_DICTS  = { 'DN' => 'dnaplatestatusdict',
		   'EP' => 'opstatusdict',
		   'PC' => 'pcrplatestatusdict',
		   'DT' => 'dnatubestatusdict',
		   'BB' => 'bbstatusdict',
		   'LP' => 'lpstatusdict',
		   'GP' => 'dnaplatestatusdict',
		   'DP' => 'dnaplatestatusdict'
		   };

=head1 SNP_util::get_dict_into_hash

 Pulls contents of a given ...dict table into a hash.  Provides a simple way of 
 handling statuses by name rather than hard-coding numbers.
 e.g. 1/'Created', 
      2/'Ordered', 
      3/'Cancelled'

 example:
    %dict = get_dict_into_hash('snp', 'pcrstatusdict');

 to add a new table:
    Add SQL query to SNP_util.sql_lib of the form:
    
    >get_xxxxdict<
    select ID_DICT, DESCRIPTION
    from xxxxDICT

=cut


sub get_dict_into_hash {
    my ($dbh, $table) = @_;

    my %dict;
    my $sql = "get_" . $table;

    my $STATEMENTS = statements->new("$dbh");
    #$STATEMENTS->default_sql_lib_path('./');
    $STATEMENTS->load_sql_lib(["SNP_util.sql_lib::$sql"]);

    my $res = $STATEMENTS->get("SNP_util::$sql");

    if ($@ ne '') {
	print "DATABASE ERROR: $@\n";	
    }

    my $i = 0;
    while ( $res->[$i]->[0] ) {
	$dict{$res->[$i]->[0]} = $res->[$i]->[1];
	$i++;
    }
     
    if ($STATEMENTS){
	$STATEMENTS->end;
    }

    return %dict;
}

=head1 SNP_util::get_map_into_hash

 Pulls contents of rowcol_map table into a hash for given plate format (96,384).
 1 / a1
 2 / a2

 example:
    %map = get_map_into_hash('snp', 96);

=cut


sub get_map_into_hash {
    my ($dbh, $format) = @_;   

    if ( $format eq undef ) {
	die "no format specified!";
    }

    my %map;
    my $sql = "get_rowcol_map";

    my $STATEMENTS = statements->new("$dbh");
    #$STATEMENTS->default_sql_lib_path('./');
    $STATEMENTS->load_sql_lib(["SNP_util.sql_lib::$sql"]);

    my $res = $STATEMENTS->get("SNP_util::$sql", [$format]);

    if ($@ ne '') {
	print "DATABASE ERROR: $@\n";	
    }

    my $i = 0;
    while ( $res->[$i]->[0] ) {
	$map{$res->[$i]->[2]} = $res->[$i]->[0].$res->[$i]->[1];
	$i++;
    }
     
    if ($STATEMENTS){
	$STATEMENTS->end;
    }

    return %map;
}

=head1 SNP_util::get_plate_contents

    Pulls out contents of a plate as defined in sql file get_xx_contents

=cut

sub get_plate_contents {
    my ($dbh, $id, $type) = @_;

    if ( $type eq undef ) {
	die "Must supply a type to get_plate_contents";  #### carp?
    }

    my $sql = "SNP_util.sql_lib::get_" . $type . "_contents";

    my $STATEMENTS = statements->new("$dbh");
    #$STATEMENTS->default_sql_lib_path('./');
    $STATEMENTS->load_sql_lib([$sql]);

    my $res = $STATEMENTS->get($sql, [$id]);

    if ($@ ne '') {
	print "DATABASE ERROR: $@\n";	
    }

    my %layout;

    my $i = 0;
    while ( $res->[$i]->[0] ne undef) {
	my $well = $res->[$i]->[0] . $res->[$i]->[1];

	my $j = 2;
	my @contents;
	while ( $res->[$i]->[$j] ne undef ) {
	    push(@contents, $res->[$i]->[$j]);
	    $j++;
	}

	$layout{$well} = \@contents;

	$i++;
    }
     
    if ($STATEMENTS){
	$STATEMENTS->end;
    }

    return %layout;

}

1;
















