################################################################################
package FreezerEditor;
################################################################################
#
# Author: Paul Mooney
#
# This takes a list of plates and displays a valid set of freezers for that
# user. The freezer set for the user is passed in (id_freezer, their labels 
# and names).
#
# $Id: FreezerEditor.pm,v 1.1 2000/05/25 14:15:47 pjm Exp $
#

use LemurUtils;

sub new {
    my ($type,
        $parent_window,
        $dbh,
        $ref_to_hash,
        $mode,                  # this is 1 for JIT, 0 for non-JIT (for now)
                                # trying to make it generic freezer storage code
        $ref_to_freezers_in_set,
        $ref_name_for_freezer,
        $ref_label_for_freezer,
        $id_for_freezer_named,
        $id_for_freezer_label,
        $default_freezer,
        @plates)                   = @_;

    if( scalar @plates == 0 ){
        print "ERROR: no plates to edit!!!\n";
        return;
    }

    print Data::Dumper::Dumper(\@plates), "\n";

    my $self = {
        parent_window         => $parent_window,
        dbh                   => $dbh,
        mode                  => $mode,
        ref_name_for_freezer  => $ref_name_for_freezer,
        ref_label_for_freezer => $ref_label_for_freezer,
        id_for_freezer_named  => $id_for_freezer_named,
        id_for_freezer_label  => $id_for_freezer_label,
        default_freezer       => $default_freezer,
        id_plates             => \@plates,
        bitmap_dir            => "$ENV{'BADGER'}/lib/finch/bitmaps",
        num_rows              => 25, # NUMBER OF ROWS DISPLAYED!!!!!!!
        cursor                => 0,
    };
    bless $self;

    $self->get_plate_names($dbh, @plates);
    $self->get_freezers($dbh, $mode);
    $self->create_window($parent_window, $ref_to_freezers_in_set);

    return $self;
}

sub create_window {
    my ($self, $ref_to_freezers_in_set) = @_;

#    $self->{mw} = new MainWindow();
    $self->{mw} = $self->{parent_window}->Toplevel();


    $self->{mw}->title("Freezer Editor");
#    $self->{mw}->Label(width   => 30)->pack;

    $self->{mw}->protocol('WM_DELETE_WINDOW' => sub {
    });

    #############################################################
    # try a specail "kill DB connection and die key combo"
    #
    #                     CTRL-ALT-b
    #
    #############################################################
    $self->{mw}->bind("<Control-Alt-KeyPress-b>", sub {
        $self->die_editor_die();
    }, );

    my $mw          = $self->{mw};
    my $topFrame    = $mw->Frame()->pack();
    my $bottomFrame = $mw->Frame()->pack();
    my $upDownFrame = $topFrame->Frame()->pack(-side => 'left');
    my $tableFrame  = $topFrame->Frame()->pack(-side => 'right');
    my ($upButton, $downButton);

    # Make an 'up-button';
    $mw->Bitmap('up',
		-file     => "$self->{bitmap_dir}/uarrw.xbm",
		-maskfile => "$self->{bitmap_dir}/uarrw.xbm"
	       );

    $upButton = $upDownFrame->Button(-image   => 'up',
				     -command => sub { $self->pressed_up; }); 
    $upButton->pack(-side => 'top');

    # Make an 'down-button';
    $mw->Bitmap('down',
		-file     => "$self->{bitmap_dir}/darrw.xbm",
	       	-maskfile => "$self->{bitmap_dir}/darrw.xbm"
		);
    
    $downButton = $upDownFrame->Button(-image   => 'down',
			               -command => sub { $self->pressed_down;});
    $downButton->pack(-side => 'bottom');

    $upDownFrame->pack(-side => 'left');

    # CREATE TABLE OF WIDGETS

#    my @fridge_names = sort values %{$self->{ref_name_for_freezer}};

    my @fridge_names = sort keys %{$self->{id_for_freezer_label}};

    # create column headings
    my $rowFrame = $tableFrame->Frame()->pack();

    $rowFrame->Label(-text   => "ID_Plates",
                     -width  => 15,
                     -anchor => 'w',
                   #  -relief => 'sunken',
                     )->pack(-side => 'left');

    $rowFrame->Label(-text   => "Plate Name",
                     -width  => 15,
                     -anchor => 'w',
                  #   -relief => 'sunken',
                     )->pack(-side => 'left');

    $rowFrame->Label(-text   => "Freezer",
                     -width  => 20,
                     -anchor => 'w',
                   #  -relief => 'sunken',
                     )->pack(-side => 'left');

    foreach my $x (1..$self->{num_rows}){
        my $rowFrame = $tableFrame->Frame()->pack();

        $self->{id_plate_widgets}->[$x] =
            $rowFrame->Label(-text   => "Hello",
                             -width  => 15,
                             -anchor => 'w',
                             -relief => 'sunken',
                             )->pack(-side => 'left');

        $self->{plate_widgets}->[$x] =
            $rowFrame->Label(-text   => "Hello",
                             -width  => 15,
                             -anchor => 'w',
                             -relief => 'sunken',
                             )->pack(-side => 'left');

        $self->{fridge_widgets}->[$x] =
            $rowFrame->BrowseEntry(-width    => 26,
                                   -relief   => 'sunken',
                                   -state    => 'readonly',
                                   -variable => \$self->{fridge_choosen}->[$x],
                                   -choices  => \@fridge_names,
                                   )->pack(-side => 'right');
    }

    
    foreach my $x (0..25){
        print "$x: $self->{fridge_choosen}->[$x], \n";
    }

    # PAGE NUM (and spacing)
    $bottomFrame->Label()->pack();
    $bottomFrame->Label(-textvariable => \$self->{pageNumLabel},
                        -width        => 26,
                        )->pack(); 
    $bottomFrame->Label()->pack();

    $bottomFrame->Button(-text    => "Done",
                         -command => sub { $self->done_pressed(); },
                         )->pack();

    # make sure whole window appears on screen, not just the title.

    my $f = $self->{mw}->Frame(-width => 10, -height => 20);
    $f->pack(-side => 'top');
    $self->{mw}->idletasks();
    $self->{mw}->packPropagate(0);
    $f->packForget(); 

    # center window on screen

    my $x = int(($self->{mw}->screenwidth  - $self->{mw}->reqwidth)  / 2);
    my $y = int(($self->{mw}->screenheight - $self->{mw}->reqheight) / 2);

    $self->{mw}->geometry("+$x+$y");

    # Draw screen for first time & set the "Page 1 of 3" label
    # if default freezer, set all freezers to equal this.
    if( defined $self->{default_freezer} ){

        foreach my $id_plate (@{$self->{id_plates}}){
            $self->{fridge_for}->{$id_plate} = $self->{default_freezer};
        }
    }

    $self->redraw_screen();

    my $numPages  = scalar(@{$self->{id_plates}}) / $self->{num_rows};
    $numPages     =~ s/(\.\d+)$//;
    ++$numPages if $1;

    $self->{numberOfPages} = $numPages;
    $self->setPageNum( 1 );

    # grap focus and wait till the user has pressed one of the buttons

    $self->{mw}->raise();
    $self->{mw}->grab();
    $self->{mw}->waitVisibility;
    $self->{mw}->update;

    # 
    $self->{mw}->waitVariable(\$self->{editor_finished});
    $self->{mw}->grabRelease;
#    $self->{mw}->withdraw;

    return $self->{editor_finished};
}

sub die_editor_die {
    my ($self) = @_;

    print "Freezer Editor:Die editor DIE!!!!!!\n";

    if( defined $self->{parent_window} ){
        print "$self->{parent_window}\n";
        $self->{parent_window}->destroy();
    }
    else {
        print Data::Dumper::Dumper($self), "\n";
    }

    $self->{editor_finished} = 1;
}


# preserve the order of plates enetered
#
sub get_plate_names {
    my ($self, $dbh, @id_loadingplates) = @_;
    my @plates;
    my $plates;

    eval {
        # build up string like "123, 1234,"
        foreach my $id_loadingplate (@id_loadingplates){
            $plates .= "$id_loadingplate,";
        }

        $plates =~ s/,$//; # remove last comma

        my $ref = $dbh->fetch_all(qq[ select ID_LOADINGPLATE,
                                             PLATENAME || SUFFIX
                                      from   LOADINGPLATE
                                      where  ID_LOADINGPLATE in ($plates) ]);

print "select ID_LOADINGPLATE, PLATENAME
from   LOADINGPLATE
where  ID_LOADINGPLATE in ($plates)\n";

        # build array of plate names and hash so can look up ID_LOADINGPLATE
        # for a given plate name
        foreach my $row (@{$ref}){
            
#            $self->{name_to_id}->{$row->[1]} = $row->[0];
            $self->{id_to_name}->{$row->[0]} = $row->[1];
print "$row->[0] : $row->[1]\n";
        }

        # preserve the order of plates enetered
#        foreach my $id_lp (@id_loadingplates){
#            push @plates, $self->{id_to_name}->{$id_lp};
#        }
    };

    if( $@ ){
        die "Trying to get plate names: $@";
    }

#    $self->{plates} = \@plates;
}

# This gets the freezers so when the widgets are created they will contain the 
# fridge id got by this function
sub get_freezers {
    my ($self, $dbh, $mode) = @_;

    my $set = 1; # downstairs WP, JIT

    $set    = 2 if $mode == 0; # non JIT, upstairs fridges

    my $ref = $dbh->fetch_all(qq[select ID_FREEZER, NAME, LABEL
                                 from   FREEZER where ID_SET = $set ]);

    $self->{freezer_info} = $ref;
}

sub pressed_up {
    my ($self)     = @_;
    my $cursorToBe;
    my $lastIndex  = $#{$self->{id_plates}};

    if( $self->{cursor} <= 1 ) { 
	return; 
    }

#    $self->decPageNum();

    # Save the data entered before scrolling up

    my $i = 1;
    my $x;

    foreach $x ($self->{cursor} .. $self->{cursor} + $self->{num_rows} - 1) {
	last if( ! defined($self->{id_plates}->[$x]) );

        my $plate_name  = $self->{id_to_name}->{$self->{id_plates}->[$x]};
        my $fridge_name = $self->{fridge_choosen}->[$i];

        $self->{fridge_for}->{$self->{id_plates}->[$x]} = $fridge_name;

	$i++;
    }

    # if NUM_ROWS == 1, this won't work.
    if( ($self->{cursor} - $self->{num_rows}) <= 1 )  {
        $self->{cursor} = 0;
    }
    else {
        $self->{cursor} = $self->{cursor} - $self->{num_rows};
    }

    $self->redraw_screen();
    $self->decPageNum();
}

sub pressed_down {
    my ($self)    = @_;
    my $lastIndex = $#{$self->{id_plates}};
    my $i         = 1;
    my $x         = 0;

    if( ($self->{cursor} + $self->{num_rows}) < ($lastIndex + 1)) {

	# Save fridge names to $self->{fridge_for}
	foreach $x ($self->{cursor} .. $self->{cursor} + 
                                       $self->{num_rows} - 1) {

            my $plate_name  = $self->{id_to_name}->{$self->{id_plates}->[$x]};
            my $fridge_name = $self->{fridge_choosen}->[$i];

	    $self->{fridge_for}->{$self->{id_plates}->[$x]} = $fridge_name;
                
	    $i++;
	}

	$self->{cursor} += $self->{num_rows};
    }
    else {
	return;
    }

#    $self->incPageNum();
    $self->redraw_screen();
    $self->incPageNum();
}

sub redraw_screen {
    my ($self)  = @_;
    my $i       = 0;
    my $cursor  = $self->{cursor};

    foreach my $x ($cursor .. ($cursor + $self->{num_rows} - 1)) {

	++$i;

	if( ! defined($self->{id_plates}->[$x]) ){
            $self->{id_plate_widgets}->[$i]->configure(text => "");
	    $self->{plate_widgets}->[$i]->configure(text => "");
            $self->{fridge_widgets}->[$i]->configure(-state => 'disabled');
            $self->{fridge_choosen}->[$i] = '';
	    next;
	}

        my $id_plate   = $self->{id_plates}->[$x];
        my $plate_name = $self->{id_to_name}->{$id_plate};

        $self->{id_plate_widgets}->[$i]->configure(text   => $id_plate);
	$self->{plate_widgets}->[$i]->configure(   text   => $plate_name);
        $self->{fridge_widgets}->[$i]->configure(  -state => 'normal');
        $self->{fridge_choosen}->[$i] = $self->{fridge_for}->{$id_plate};
    }
}

sub setPageNum {
    my ($self, $page_num) = @_;

    $self->{pageNum}       = $page_num;
    $self->{pageNumLabel}  =
        "Page $self->{pageNum} of $self->{numberOfPages}";
}

sub incPageNum {
    my ($self) = @_;

    $self->{pageNum}++;
    $self->setPageNum( $self->{pageNum} );
}

sub decPageNum {
    my ($self) = @_;

    $self->{pageNum}--;
    $self->setPageNum( $self->{pageNum} );
}

sub destroy {
    my ($self) = @_;

    if( Tk::Exists($self->{mw}) ){
        $self->{mw}->destroy();
    }
}

sub done_pressed {
    my ($self) = @_;

    print "\ndone_pressed()\n";

    LemurUtils->setWait([$self->{mw}]);

    # Save fridges entered (like in page up/down subs)
    my $i = 1;

    foreach my $x ($self->{cursor} .. $self->{cursor} + $self->{num_rows} - 1) {

        my $plate_name  = $self->{id_to_name}->{$self->{id_plates}->[$x]};
        my $fridge_name = $self->{fridge_choosen}->[$i];

        $self->{fridge_for}->{$self->{id_plates}->[$x]} = $fridge_name;
                
        $i++;
    }

    # check all plates have been assigned a fridge
    foreach my $id_plate (@{$self->{id_plates}}){

        unless( defined $self->{fridge_for}->{$id_plate} ){
            my $plate_name  = $self->{id_to_name}->{$id_plate};

            LemurUtils->showError($self->{mw},
                                  "Please select a Freezer for $plate_name");

            LemurUtils->unSetWait([$self->{mw}]);
            return;
        }
    }

    # Got here so all plates been assigned a fridge

    # Make an array of plates for each fridge. First, get all fridge names

    my %fridge_names;

    foreach my $id_plate (@{$self->{id_plates}}){
        $fridge_names{ $self->{fridge_for}->{$id_plate} } = 1;
    }

    # make temp array holding plate names of 
    foreach my $fridge (keys %fridge_names){

        # make an array of plate IDs for this fridge
        my @plates_for_fridge;
        my @debuggy;
        my $x = 0;

        foreach my $id_plate (@{$self->{id_plates}}){

            if( $self->{fridge_for}->{$id_plate} eq $fridge ){
#                push @plates_for_fridge, $plate_name;
                push @plates_for_fridge, $self->{id_plates}->[$x];

                push @debuggy, $plate_name;
#                my $id_lp = $self->{name_to_id}->{$plate_name};               
            }

            ++$x;
        }

#        my $id_freezer = $self->{id_for_freezer_named}->{$fridge};
        my $id_freezer = $self->{id_for_freezer_label}->{$fridge};

        if( $debug ){
            print "Fridge: $fridge, ID: $id_freezer\n";
            print "        ", join(', ', @plates_for_fridge), "\n";
            print "        ", join(', ', @debuggy), "\n";
        }


        &Booth::do_fridge_storage_stuff($id_freezer, 'Yes', undef, 
                                        @plates_for_fridge);

        LemurUtils->unSetWait([$self->{mw}]);
        $self->{editor_finished} = 1;
     }
}

#################
# END OF MODULE
#################

1;

#
# $Log: FreezerEditor.pm,v $
# Revision 1.1  2000/05/25  14:15:47  pjm
# Initial revision
#
#
