package Chemchooser;

use strict;
use vars qw(@ISA @EXPORT);
use Exporter;
@ISA = ('Exporter');
@EXPORT = qw(&chemistry);

use Checkbarcode;
use NewBrowseEntry;
use var_monitor;

# Fonts
my ($title_f, $entry_f, $button_f, $label_f);

# Other
my $dbh;
my ($chem_win, $action, $valid_chems);
my $stage = 'chem';
my $barcode_entry = "pale green";
my ($suffix, $pcr, $primer, $vector, $term, $dir, $dye, $protocol, $chem, $chem_ok);
my ($OLD_SEQCHEM, $ID_SCSP, $chem_var, $protocol_var, $dye_var, $dir_var, $term_var, $vector_var, $pcr_var, $suffix_var, $primer_var, $dyes, $seqchems, $dirs, $terms, $pcrs, $prots);
my $chem_sel;
my $suffix_sel;

sub chem_changed {

    # Has $chem_var changed to a valid value ?
    # $chem_ok
   
    if ( defined ($valid_chems->{$chem_var}) ) { 
	$chem_ok->configure(-state => 'active');

    } else {
	
	$chem_ok->configure(-state => 'disabled');

    }

}

sub chemistry {

    my ($mainWindow);
    ($dbh, $mainWindow, $valid_chems, $chem_sel, $suffix_sel, $title_f, $entry_f, $button_f, $label_f) = @_;

    # User needs to specify the chemistry

    if (! defined $chem_win){
	
	$stage = 'chem';
	($OLD_SEQCHEM, $ID_SCSP, $chem_var, $protocol_var, $dye_var, $dir_var, $term_var, $vector_var, $pcr_var, $suffix_var, $primer_var) = '';
	
	$chem_win = $mainWindow->Toplevel;
	$chem_win->wm('minsize', 600, 350); 
	$chem_win->wm('maxsize', 600, 350); 
	$chem_win->configure (-title => "Specify chemistry.");

	# Disable the close option
	$chem_win->protocol('WM_DELETE_WINDOW' => sub { });
	
	# Action frame
	my $win_top = $chem_win->Frame(-borderwidth => 10)->pack(-side => 'top');
	
	$win_top->Label(font => $title_f,
			text => '  Action:')->pack(-side => 'left');
	my $action_label = $win_top->Entry(
					   -state => 'disabled',
					   -width => 40,
					   -font => $title_f,
					   -bg => $barcode_entry,
					   -textvariable => \$action,
					   )->pack(side => 'top');
	$action_label->pack(-side => 'left');
	
	
	
	# split the screen in half
	my $win_frame_left = $chem_win->Frame(-borderwidth => 5, -relief => 'raised')->pack(-side => 'left');
	my $win_frame_right = $chem_win->Frame()->pack(-side => 'right');
	# split the left-hand frame in 2
	my $frame_left = $win_frame_left->Frame()->pack(-side => 'left');
	my $frame_right = $win_frame_left->Frame()->pack(-side => 'right');
	
	#########################
	
	
	my $bb = 'Chemistry id';
	my $chemt = $frame_left->Entry(
				       -state => 'disabled',
				       -width => 20,
				       -font => $button_f,
				       -textvariable => \$bb,
				       )->pack(side => 'top');
	$chemt->pack(-side => 'top');
	
	$chem = $frame_right->Entry(
				    -width => 25,
				    -font => $entry_f,
				    -textvariable => \$chem_var,
				    -state => 'disabled'
				    )->pack(side => 'top');
	
	my $c = 'Seq protocol';
	my $protocolt = $frame_left->Entry(
					   -state => 'disabled',
					   -width => 20,
					   -font => $button_f,
					   -textvariable => \$c,
					   )->pack(side => 'top');
	$protocolt->pack(-side => 'top');
	
	$protocol = $frame_right->BrowseEntry(
					      -width => 23,
					      -font => $entry_f,
					      -textvariable => \$protocol_var,
					      -state => 'disabled'
					      )->pack(side => 'top');
	
	my $d = 'Dyeset';
	my $dyet = $frame_left->Entry(
				      -state => 'disabled',
				      -width => 20,
				      -font => $button_f,
				      -textvariable => \$d,
				      )->pack(side => 'top');
	$dyet->pack(-side => 'top');
	
	$dye = $frame_right->BrowseEntry(
					 -width => 23,
					 -font => $entry_f,
					 -textvariable => \$dye_var,
					 -state => 'disabled'
					 )->pack(side => 'top');
	
	my $e = 'Direction';
	my $dirt = $frame_left->Entry(
				      -state => 'disabled',
				      -width => 20,
				      -font => $button_f,
				      -textvariable => \$e,
				      )->pack(side => 'top');
	$dirt->pack(-side => 'top');
	
	$dir = $frame_right->BrowseEntry(
					 -width => 23,
					 -font => $entry_f,
					 -textvariable => \$dir_var,
					 -state => 'disabled'
					 )->pack(side => 'top');
	
    
	my $ee = 'Primer/Terminator';
	my $termt = $frame_left->Entry(
				       -state => 'disabled',
				       -width => 20,
				       -font => $button_f,
				       -textvariable => \$ee,
				       )->pack(side => 'top');
	$termt->pack(-side => 'top');
	
	$term = $frame_right->BrowseEntry(
					  -width => 23,
					  -font => $entry_f,
					  -textvariable => \$term_var,
					  -state => 'disabled'
					  )->pack(side => 'top');
	
	my $h = 'Sequencing vector';
	my $vectort = $frame_left->Entry(
					 -state => 'disabled',
					 -width => 20,
					 -font => $button_f,
					 -textvariable => \$h,
					 )->pack(side => 'top');
	$vectort->pack(-side => 'top');
	
	$vector = $frame_right->BrowseEntry(
					    -width => 23,
					    -font => $entry_f,
					    -textvariable => \$vector_var,
					    -state => 'disabled'
					    )->pack(side => 'top');
	
	my $f = 'Primer';
	my $primert = $frame_left->Entry(
					 -state => 'disabled',
					 -width => 20,
					 -font => $button_f,
					 -textvariable => \$f,
					 )->pack(side => 'top');
	$primert->pack(-side => 'top');
	
	$primer = $frame_right->BrowseEntry(
					    -width => 23,
					    -font => $entry_f,
					    -textvariable => \$primer_var,
					    -state => 'disabled'
					    )->pack(side => 'top');
	
	my $ff = 'On PCR product';
	my $pcrt = $frame_left->Entry(
				      -state => 'disabled',
				      -width => 20,
				      -font => $button_f,
				      -textvariable => \$ff,
				      )->pack(side => 'top');
	$pcrt->pack(-side => 'top');
	
	
	$pcr = $frame_right->BrowseEntry(
					 -width => 23,
					 -font => $entry_f,
					 -textvariable => \$pcr_var,
					 -state => 'disabled'
					 )->pack(side => 'top');
	
	
	my $g = 'Suffix';
	my $suffixt = $frame_left->Entry(
					 -state => 'disabled',
					 -width => 20,
					 -font => $button_f,
					 -textvariable => \$g,
					 )->pack(side => 'top');
	$suffixt->pack(-side => 'top');
	
	$suffix = $frame_right->Entry(
				      -width => 25,
				      -font => $entry_f,
				      -textvariable => \$suffix_var,
				      -state => 'disabled'
				      )->pack(side => 'top');
	
	# Buttons on the right
	$chem_ok = $win_frame_right->Button(-font => $button_f, 
					    -text => 'OK',
					    -width => 6,
					    -state => 'disabled',
					    -command => sub {

						$suffix_var =~ s/\.//;
						$$suffix_sel = $suffix_var;
						$$chem_sel = $chem_var;

						$chem_win->destroy();
						undef $chem_win;
						&unmonitor(\$chem_var, 'chem_var', \&chem_changed);
					    }
					    )->pack();

	my $chem_cancel = $win_frame_right->Button(-font => $button_f, 
						   -text => 'Cancel',
						   -width => 6,
						   -command => sub {
						       $chem_win->destroy();
						       undef $chem_win;
						       &unmonitor(\$chem_var, 'chem_var', \&chem_changed);
						   }
						   )->pack();
	

###########################################################
	&monitor(\$chem_var, 'chem_var', \&chem_changed);
###########################################################

	&start_process;

    } else {


    }
}

sub start_process {
    if ($stage eq 'chem'){
	&go_chem;
    }

    if ($stage eq 'prot'){
	$chem->configure(-state => 'disabled');
	&go_prot;
    }
    
    if ($stage eq 'dyeset'){
	$protocol->configure(-state => 'disabled');
	&go_dyeset;
    }
    
    if ($stage eq 'dir'){
	$dye->configure(-state => 'disabled');
	&go_dir;
    }
    
    if ($stage eq 'term'){
	$dir->configure(-state => 'disabled');
	&go_term;
    }
    
    if ($stage eq 'vector'){
	$term->configure(-state => 'disabled');
	&go_vector;
    }
    
    if ($stage eq 'primer'){
	$vector->configure(-state => 'disabled');
	&go_primer;
    }
    
    if ($stage eq 'pcr'){
	$primer->configure(-state => 'disabled');
	&go_pcr;
    }

    if ($stage eq 'none'){
	$pcr->configure(-state => 'disabled');

    }

}

sub go_chem {

    $action = "Specify a sequencing chemistry.";
    
    $chem->configure(-state => 'normal');
    $protocol->configure(-state => 'disabled');
    $dye->configure(-state => 'disabled');
    $dir->configure(-state => 'disabled');
    $term->configure(-state => 'disabled');
    $vector->configure(-state => 'disabled');
    $primer->configure(-state => 'disabled');
    $pcr->configure(-state => 'disabled');
    $suffix->configure(-state => 'disabled');
    
    $chem->focusForce();
    $chem->grab();
    $chem->configure(-bg => $barcode_entry);
    
    $chem->bind ('<Return>' => sub {

	my $hash_return = Verifynumber("$chem_var", "CT");
	foreach my $n (keys %{$hash_return}){
	}

	# The user should be able to just type in the
	# value of id_scsp
	if ( ($hash_return->{Process} eq 'Good') || ($chem_var =~ /\d+/) ){
	    
	    if ($hash_return->{Process} eq 'Good'){
		$chem_var = $hash_return->{Number};
	    } else {
		$chem_var =~ /(\d+)/;
		$chem_var = $1;
	    }

	    #################################################################
	    # Need to check that our $chem_var value is a true id_scsp value
	    #################################################################
	    my ($protocol, $seqchem, $dir, $primer,  $suffix, $primername, $vectorname, $dyeset, $wp, $pcr_r) = get->seq_info_from_id_scsp($dbh, $chem_var);

	    $protocol =~ /^(\w+)-/;
	    my $p_test;
	    if ($1) { $p_test = $1; }
	   
	    #altered to dissallow automatic filling for MB chemistries.
	    if ($p_test eq 'MB'){
		$stage = 'prot';
		$chem_var = '';
	    } else {
		
		$protocol_var = $protocol;
		$dye_var = $dyeset;
		$dir_var = $dir;
		$term_var = $primer;
		$vector_var = $vectorname;
		$primer_var = $primername;
		$pcr_var = $pcr_r;
		$suffix_var = $suffix;
		
		########################
		$stage = 'none';
		########################
		
		$ID_SCSP = $chem_var;
		
		if ($seqchem eq ''){ 
		    $OLD_SEQCHEM = 'NULL';
		} else {
		    $OLD_SEQCHEM = $seqchem;
		}
		
		$chem->configure(-state => 'disabled');

	    }

	    ############## <----------------
	} else {
	    $stage = 'prot';
	    $chem_var = '';
	}
	$chem->configure(-bg => 'grey85');
	$chem->grabRelease();
	&start_process();
    });
}
		 

sub go_prot {

    my $def_protocol;
    $chem->bind ('<Return>' => sub {});
    $action = "Specify a sequencing protocol.";
    
    $protocol->configure(-state => 'readonly');
    $dye->configure(-state => 'disabled');
    $dir->configure(-state => 'disabled');
    $term->configure(-state => 'disabled');
    $vector->configure(-state => 'disabled');
    $primer->configure(-state => 'disabled');
    $pcr->configure(-state => 'disabled');
    $suffix->configure(-state => 'disabled');
    
    $protocol_var = $def_protocol;
    $chem_win->focusForce();
    $protocol->Subwidget("arrow")->configure(-bg => $barcode_entry);
    $protocol->Subwidget("entry")->Subwidget("entry")->configure(-bg => $barcode_entry);
    $protocol->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => $barcode_entry);
    
    $protocol->delete(0, 'end');
    $prots = get->list_of_protocols($dbh);
    foreach my $n (sort keys %$prots){
	$protocol->insert('end', $n);
	$protocol_var = $n;
	$def_protocol = $n;
    }
    
    $chem_win->bind ('<Return>' => sub {
	
	$chem_win->bind ('<Return>' => sub {});
	
	my $choice = $prots->{$protocol_var};
	$seqchems = get->seqchems_wrt_protocol($dbh, $choice);
	
	if ($seqchems->[0] eq ''){

	    $stage = 'prot';
	} else {
	    $dyes = get->list_of_dyesets($dbh, $seqchems);

	    foreach my $n (keys %$dyes){
		$dye->insert('end', $n);
		$dye_var = $n;

		###################    ??????????????
		my $def_dye = $n;
		###################
	    }
	    
	    $stage = 'dyeset';
	    $protocol->Subwidget("arrow")->configure(-bg => 'grey85');
	    $protocol->Subwidget("entry")->Subwidget("entry")->configure(-bg => 'grey85');
	    $protocol->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => 'grey85');
	
	}
	&start_process();
    }); 
}





sub go_dyeset {

    $action = "Specify a dye set.";
    
    $protocol->configure(-state => 'disabled');
    $dye->configure(-state => 'readonly');
    $chem_win->focusForce();
    $dye->Subwidget("arrow")->configure(-bg => $barcode_entry);
    $dye->Subwidget("entry")->Subwidget("entry")->configure(-bg => $barcode_entry);
    $dye->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => $barcode_entry);
    $chem_win->bind ('<Return>' => sub {
	
	$chem_win->bind ('<Return>' => sub {});
	
	######################################
	# We should load a list at this point
	######################################
	# What did they choose
	my $choice = $dyes->{$dye_var};
	$seqchems = get->seqchems_wrt_dyeset($dbh, $choice, $seqchems);
	
	if ($seqchems->[0] eq ''){
	    $stage = 'dyeset';
	} else {
	    
	    $dirs = get->list_of_directions($dbh, $seqchems);
	    
	    foreach my $n (keys %$dirs){
		$dir->insert('end', $n);
		$dir_var = $n;

		################ ????
		my $def_dir = $n;
		################ ????

	    }
	    
	    $stage = 'dir';
	    $dye->Subwidget("arrow")->configure(-bg => 'grey85');
	    $dye->Subwidget("entry")->Subwidget("entry")->configure(-bg => 'grey85');
	    $dye->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => 'grey85');
	}
	&start_process();
    }); 
}

sub go_dir {

    $action = "Specify a direction.";
    $dye->configure(-state => 'disabled');
    $dir->configure(-state => 'readonly');

    $chem_win->focusForce();
    $dir->Subwidget("arrow")->configure(-bg => $barcode_entry);
    $dir->Subwidget("entry")->Subwidget("entry")->configure(-bg => $barcode_entry);
    $dir->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => $barcode_entry);
    $chem_win->bind ('<Return>' => sub {

	$chem_win->bind ('<Return>' => sub {});

	######################################
	# We should load a list at this point
	######################################
	my $choice = $dirs->{$dir_var};
	$seqchems = get->seqchems_wrt_direction($dbh, $choice, $seqchems);
	
	if ($seqchems->[0] eq ''){
	    $stage = 'dir';
	} else {

	    $terms = get->list_of_terms($dbh, $seqchems);
	    foreach my $n (keys %$terms){
		$term->insert('end', $n);
		$term_var = $n;

		############### ???
		my $def_term = $n;
		############### ???
	    }
	    $stage = 'term';

	    $dir->Subwidget("arrow")->configure(-bg => 'grey85');
	    $dir->Subwidget("entry")->Subwidget("entry")->configure(-bg => 'grey85');
	    $dir->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => 'grey85');
	}
	&start_process();
    }); 
}




sub go_term {
    
    $action = "Specify primer/terminator.";
    
    $dir->configure(-state => 'disabled');
    $term->configure(-state => 'readonly');
    
    $chem_win->focusForce();
    $term->Subwidget("arrow")->configure(-bg => $barcode_entry);
    $term->Subwidget("entry")->Subwidget("entry")->configure(-bg => $barcode_entry);
    $term->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => $barcode_entry);
    $chem_win->bind ('<Return>' => sub {
	
	$chem_win->bind ('<Return>' => sub {});

	######################################
	# We should load a list at this point
	######################################
	# What did they choose
	my $choice = $terms->{$term_var};
	$seqchems = get->seqchems_wrt_term($dbh, $choice, $seqchems);

	if ($seqchems->[0] eq ''){
	    $stage = 'term';
	} else {
	    
	    my $vectors = get->list_of_vectors($dbh, $seqchems);
	    foreach my $n (keys %$vectors){
		$vector->insert('end', $n);
		$vector_var = $n;

		################# ???
		my $def_vector = $n;
		################# ???

	    }
	    $stage = 'vector';

	    $term->Subwidget("arrow")->configure(-bg => 'grey85');
	    $term->Subwidget("entry")->Subwidget("entry")->configure(-bg => 'grey85');
	    $term->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => 'grey85');
	}
	&start_process();
    });
}

sub go_vector {
    
    $action = "Specify sequencing vector.";
    
    $term->configure(-state => 'disabled');
    $vector->configure(-state => 'readonly');

    $chem_win->focusForce();
    $vector->Subwidget("arrow")->configure(-bg => $barcode_entry);
    $vector->Subwidget("entry")->Subwidget("entry")->configure(-bg => $barcode_entry);
    $vector->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => $barcode_entry);
    $chem_win->bind ('<Return>' => sub {

	$chem_win->bind ('<Return>' => sub {});

	my $choice = $vector_var;
	$seqchems = get->seqchems_wrt_vector($dbh, $choice, $seqchems);

	if ($seqchems->[0] eq ''){
	    $stage = 'vector';
	} else {

	    my $primers = get->list_of_primers($dbh, $seqchems);
	    foreach my $n (keys %$primers){
		$primer->insert('end', $n);
		$primer_var = $n;
		
		################## ????
		my $def_primer = $n;
		################## ????
	    }
	    $stage = 'primer';
	    
	    $vector->Subwidget("arrow")->configure(-bg => 'grey85');
	    $vector->Subwidget("entry")->Subwidget("entry")->configure(-bg => 'grey85');
	    $vector->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => 'grey85');
	}
	&start_process();
    });
}




sub go_primer {

    $action = "Specify a primer.";
    
    $term->configure(-state => 'disabled');
    $primer->configure(-state => 'readonly');
    
    $chem_win->focusForce();
    $primer->Subwidget("arrow")->configure(-bg => $barcode_entry);
    $primer->Subwidget("entry")->Subwidget("entry")->configure(-bg => $barcode_entry);
    $primer->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => $barcode_entry);
    $chem_win->bind ('<Return>' => sub {

	$chem_win->bind ('<Return>' => sub {});

	my $choice = $primer_var;
	$seqchems = get->seqchems_wrt_primer($dbh, $choice, $seqchems);

	if ($seqchems->[0] eq ''){
	    $stage = 'primer';
	} else {
	    $pcrs = get->list_of_pcrs($dbh, $seqchems);
	    
	    foreach my $n (keys %$pcrs){
		$pcr->insert('end', $n);
		$pcr_var = $n;

		############## ???
		my $def_pcr = $n;
		############## ???

	    }

	    $stage = 'pcr';
	    $primer->Subwidget("arrow")->configure(-bg => 'grey85');
	    $primer->Subwidget("entry")->Subwidget("entry")->configure(-bg => 'grey85');
	    $primer->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => 'grey85');
	}
	&start_process();
    }); 
}

sub go_pcr {

    $action = "Specify if sequence is on a PCR product.";
    
    $primer->configure(-state => 'disabled');
    $pcr->configure(-state => 'readonly');
    
    $chem_win->focusForce();
    $pcr->Subwidget("arrow")->configure(-bg => $barcode_entry);
    $pcr->Subwidget("entry")->Subwidget("entry")->configure(-bg => $barcode_entry);
    $pcr->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => $barcode_entry);
    $chem_win->bind ('<Return>' => sub {

	$chem_win->bind ('<Return>' => sub {});

	######################################
	# We should load a list at this point
	######################################
	# What did they choose
	my $choice = $pcrs->{$pcr_var};

	$seqchems = get->seqchems_wrt_pcr($dbh, $choice, $seqchems);

	if ($seqchems->[0] eq ''){
	    &update("There are no available id_seqchem values for this protocol/dyeset/direction/primer/pcr !");
	    &update("Contact bug !");
	    $stage = 'pcr';
	} else {

	    ############################################################
	    # The following assumes that we are down to 1 suffix by now
	    ############################################################
	    $suffix_var = get->suffix_from_seqchem($dbh, $seqchems);
	    my $id_p = $prots->{$protocol_var};


	    $ID_SCSP = get->id_scsp_wrt_id_seqchem_and_id_protocol($dbh, $seqchems, $id_p);
	    $chem_var = $ID_SCSP;

	    ##############################################################################
	    # We need to supply an old style ID_SEQCHEM value for backwards compatibility 
	    ##############################################################################

	    my ($protocol, $seqchem, $dir, $primer, $suffix, $primername, $vectorname, $dyeset, $wp, $pcr_r) = get->seq_info_from_id_scsp($dbh, $ID_SCSP);
	    $protocol =~ /^(\w+)-/;
	    my $p_test;
	    if ($1) { $p_test = $1; }
	    
	    if ( ($seqchem eq '') && ($p_test ne 'MB') ){
		$stage = 'add'
		&start_process();
	    } else {

		if ($seqchem eq ''){ 
		    $OLD_SEQCHEM = 'NULL'; 
		} else {
		    $OLD_SEQCHEM = $seqchem;
		}

		$stage = 'none';

		$pcr->Subwidget("arrow")->configure(-bg => 'grey85');
		$pcr->Subwidget("entry")->Subwidget("entry")->configure(-bg => 'grey85');
		$pcr->Subwidget("slistbox")->Subwidget("listbox")->configure(-bg => 'grey85');
	    }
	}
	    &start_process();
    }); 
}


1;


