#!/usr/local/bin/perl5.6.1 -w
# $Id: LabelerV.pm,v 1.2 2003/10/24 10:49:26 jx1 Exp $

package LabelerV;

use strict;
use warnings;
use Carp qw(croak cluck carp);
use Class::Struct;
use Tk;
use sigtrap qw(die untrapped normal-signals
               stack-trace any error-signals);

use LabelerDataM;

my $setup = { title_f       => "*-times-bold-r-normal--*-180-*-*-p-*-*-*",
	      entry_f       => "-adobe-helvetica-medium-r-normal--17-120-100-100-p-88-iso8859-1",
	      button_f      => "-adobe-helvetica-bold-r-normal--17-120-100-100-p-92-iso8859-1",
	      menu_f        => "-adobe-helvetica-bold-r-normal--17-120-100-100-p-92-iso8859-1",
	      label_f       => "-adobe-helvetica-bold-r-normal--14-100-100-100-p-82-iso8859-1",
	      active_entry  => "pale green",
	      disabled_entry=> "grey85",
	      other_entry   => "white",
	      frame_bordrw  => '2',
	  };

#my $printerName = 'f245bc';

unless (caller)
{
    use LabelerV;
    
    my $front = LabelerV->new();
    my $mw = MainWindow->new;
    $front -> init( $mw );

    $front->OpFrame() -> pack( -side     => 'top',
				-anchor   => 'n',
				-expand   => 1,
				-fill     => 'x' ); 
    MainLoop;
}


struct LabelerV =>
{
    Leader  => '$', #ref to base GUI object
    DataSource => '$',
    OpFrame => '$',
    NumBox => '$',
    ListBox  => '$',
#    ButtonF  => '$', 
    PrinterRef => '$', # ref to scalar- string
};


sub init
{
    my $self = shift;

    my $parentw = shift;
    my $leader = shift;

    # set leading Gui object
    if ( ref($leader) )
    {
	$self->Leader( $leader );
    }

    # setup DataSource
    $self->DataSource( LabelerDataM->new(VLeader=>$leader)->init() );

    # setup frame, button, etc
    my $op_frame = $parentw -> Frame( -relief	   => 'ridge', 
				      -borderwidth => $setup->{frame_bordrw},
				      -label => "Create barcode labels for ABgene box",
				      -labelFont => $setup->{title_f},
				      -labelPack => [ -side => 'top'] );
   
    $self->OpFrame( $op_frame );

    $self->NumBox( createNumBox($self) );
    $self->ListBox( createListBox($self) );
    $self->PrinterRef( createFuncButtons($self) );
    $self->NumBox()->focus();
    
    # setup printer reference
#    my $default_p = 'f245bc';
#    $self->PrinterRef( \$default_p );
#    ${ $self->PrinterRef() } = $self->DataSource()->BarcodeLs()->Printer();

    # find and display default printer
    #${ $self->PrinterRef() } = $self->DataSource()->getCurrentBcPrinter();

    return $self;
}


sub end
{
    my $self = shift;
    $self->Leader( undef() );
    $self->DataSource( undef() );

    my $topframe = $self->OpFrame();

    if( defined $topframe )
    {
	$topframe -> packForget();
	$topframe -> parent() -> packPropagate(1);

	$self->OpFrame()->destroy();
	$self->OpFrame( undef() );
    }

    print "LabelerV end process called.\n";
}


sub DESTROY
{
    my $self = shift;
    
    if( defined $self->OpFrame() )
    {
	$self->end();
    }
    print "LabelerV destructor called.\n";
}


sub createNumBox
{
    my $family = shift;
    my $op_frame = $family->OpFrame();
   
    my $num_frame = $op_frame -> Frame( -borderwidth => $setup->{frame_bordrw},
					-label => "Number of labels to create: ",
					-labelFont => $setup->{button_f},
					-labelPack => [ -side => 'left'] );

    $num_frame -> pack ( -side   => 'top',
		         -expand => 1, 
		         -fill   => 'x');
    
    my $numlabel;
    my $numEntry = $num_frame -> Entry ( -width        => 15,
					 -font         => $setup->{entry_f},
					 -textvariable => \$numlabel,  
				       )->pack(-side => 'left');

    $numEntry -> bind ("<Return>" => [\&num_finishEntry, $family] );

    # when entry widget get focus
    $numEntry -> bind ( "<FocusIn>" => \&num_gotFocus ); # through kb action

    # configure entry for starting look
    #$numEntry -> grabRelease();
    #$numEntry -> configure ( -background => $setup->{other_entry},
			     #-state      => 'normal' );

    return $numEntry;
}

sub createListBox
{
    my $family = shift;
    my $parent = $family->OpFrame();

    my $lisbox = $parent -> ScrlListbox( -font => $setup->{entry_f},
					 -bg          => 'white',
					 -scrollbars  => 'e',
					 -height      => 5,
					 -width       => 60,
					 -takefocus   => 0
				       ) -> pack( -side => 'top', 
						  -anchor => 's',
						  -fill => 'x');

    return $lisbox;
}


sub createFuncButtons
{
    my $family = shift;
    my $parentf = $family->OpFrame();

    my $buttonf = $parentf -> Frame() ->  pack( -side     => 'bottom',
						-anchor   => 'n',
						-expand   => 1,
						-fill     => 'x' );

    my $bcprinterB = $buttonf -> Button( -font             => $setup->{button_f},
					 -fg               => 'purple',
					 -activebackground => 'black',
					 -activeforeground => 'white',   
					 -text             => "BarcodePrinter: ",
					 -command          => [\&changeBcPrinter, $family]
				       ) -> pack( -side => 'left' ); 

    my $printer_ref = \$family->DataSource()->BarcodeLs->{Printer};
    my $bcprinterE = $buttonf -> Entry( -width        => 15,
					-font         => $setup->{entry_f},
					-background   => $setup->{other_entry},
					-textvariable => $printer_ref, 
					-state        => 'disabled',
				       )->pack(-side => 'left');
    $bcprinterE -> bind( "<Enter>", [\&updateBcPrinterView, $family] );

    my $quitB = $buttonf -> Button( -font             => $setup->{button_f},
				    -fg               => 'purple',
				    -activebackground => 'black',
				    -activeforeground => 'white',   
				    -text             => "Quit",
				    -command          => [\&quitButtonPressed, $family]
				  ) -> pack( -side => 'right' );  

    my $printB = $buttonf -> Button( -font             => $setup->{button_f},
				     -fg               => 'purple',
				     -activebackground => 'black',
				     -activeforeground => 'white',   
				     -text             => "Print Labels",
				     -command          => [\&printButtonPressed, $family]
				   ) -> pack( -side => 'right' );  

    return $printer_ref;
}

####    number entry callbacks    ####
sub num_finishEntry
{
    my $numEntry = shift;
    my $family = shift;
    my $dataSrc = $family->DataSource();

    my $num = $numEntry->get();
    $num =~ s/^\s+//;
    $num =~ s/\s+$//;

    # validate input -- must be all numeric
    if( $num =~ /^\d+$/ )
    {
	$numEntry-> configure( -background => $setup->{disabled_entry});		      

	# just to make $numEntry loose focus ...    
	$numEntry -> parent() -> focus();  

	# trig to fetch labels info here
	# and show in list box
	my $labels = $dataSrc->createBarcodeLs( $num );
	$family->updateListBox( @{$labels} );
    }
    else
    {
	$family->Leader()->updateWarning( $num." is not a number. Please check and try again." );
    }
    return;
}

sub num_gotFocus
{
    my $numEntry = shift;
    my $self = shift;

    $numEntry -> configure( -background => $setup->{active_entry},
			    -state      => 'normal' );

    return;
}


####    button callbacks    ####
sub changeBcPrinter
{
    my $family = shift;
    $family->DataSource()->selectBcPrinter();

    return;
}


sub updateBcPrinterView
{
    my $entry = shift;
    my $family = shift;
    #print "On barcode printer view.\n";

    ${ $family->PrinterRef() } = $family->DataSource()->getCurrentBcPrinter();
}


sub printButtonPressed
{
    my $family = shift;
    my $dataSrc = $family->DataSource();
    my $msgBox = $family->Leader();

    eval
    {
	$dataSrc->printBarcodeLs();
    };
    if( $@ )
    {
	my $msg = ( split /\n/, $@ )[0];
	$msgBox->updateWarning( $msg );
	$msgBox->updateMessage( "Please choose a printer by pressing the 'BarcodePrinter' button.");
    }
    else 
    {
    	$family->clearListBox();
    }

#    if( $messageBox )
#    {	
#	$messageBox->updateMessage( "'Print' button pressed" );
#    }

    return;
}

sub quitButtonPressed
{
    my $family = shift;
    my $leader = $family->Leader();
    
    if( defined $leader )
    {
	$leader->handleOpQuit();
    }

    $family -> end();

    return;
}


####    public methods    ####
sub updateListBox
{
    my $self = shift;
    my @update_text = @_;

    my $listbox = $self->ListBox();
    $listbox -> insert( 'end', @update_text );
    $listbox -> see( 'end' );
    $listbox -> update( 'idletasks' );
    
}

sub clearListBox
{
    my $self = shift;
    my $listbox = $self->ListBox();
    
    $listbox->delete(0, 'end');
    $listbox->update( 'idletasks' );
}

1;  # keep perl happy
