#!/usr/bin/perl -w
#

# This is an example of a subclass of the generated application
#
# You can safely edit this file, any changes that you make will be preserved
# and this file will not be overwritten by the next run of Glade::PerlGenerate

#==============================================================================
#=== This is the 'Subadd_window' class                              
#==============================================================================
package Subadd_window;
require 5.000; use strict 'vars', 'refs', 'subs';
use vars qw($ADD);
# UI class 'Subadd_window' (version 0.01)
# 
# Copyright (c) Date Wed Dec 20 15:14:03 CST 2000
# Author Nathan Mueller <nmueller\@newton.cs.wisc.edu>
#
# Unspecified copying policy, please contact the author\n#  Nathan Mueller <nmueller\@newton.cs.wisc.edu>
#
#==============================================================================
# This perl source file was automatically generated by 
# Glade::PerlGenerate version 0.56 - Wed Apr 19 02:28:58 BST 2000
# Copyright (c) Author Dermot Musgrove <dermot.musgrove\@virgin.net>
#
# from Glade file /afs/cs.wisc.edu/u/n/m/nmueller/private/labstuff/library/library.glade
# Wed Dec 20 15:14:03 CST 2000
#==============================================================================

BEGIN {
    use vars qw( 
                 @ISA
                 %fields
                 $VERSION
             );
    # Existing signal handler modules
    use src::Library;
    # Uncomment the line below to enable gettext checking
#    use Glade::PerlSource;
    # Tell interpreter who we are inheriting from
    @ISA     = qw( add_window );
    # Uncomment the line below to enable gettext checking
#    @ISA      = qw( add_window Glade::PerlSource );
    $VERSION = '0.01';
    # Inherit the AUTOLOAD dynamic methods from add_window
    *AUTOLOAD = \&add_window::AUTOLOAD;
} # End of sub BEGIN

%fields = (
# Insert any extra data access methods that you want to add to 
#   our inherited super-constructor (or overload)
    USERDATA    => undef,
    VERSION     => '0.01',
);

sub DESTROY {
    # This sub will be called on object destruction
} # End of sub DESTROY

#==============================================================================
#=== Below are the overloaded class constructors
#==============================================================================
sub new {
    my $that  = shift;
    # Allow indirect constructor so that we can call eg. 
    #   $window1 = BusFrame->new; $window2 = $window1->new;
    my $class = ref($that) || $that;

    # Call our super-class constructor to get an object and reconsecrate it
    my $self = bless $that->SUPER::new(), $class;

    # Add our own data access methods to the inherited constructor
    my($element);
    foreach $element (keys %fields) {
        $self->{_permitted_fields}->{$element} = $fields{$element};
    }
    @{$self}{keys %fields} = values %fields;
    return $self;
} # End of sub new

sub run {
    my ($class) = @_;
    Gtk->init;
    # Uncomment the line below to enable gettext checking
#    $class->check_gettext_strings;
    my $window = $class->new;
    # Insert your subclass user data key/value pairs 
    $window->USERDATA({
#        'Key1'   => 'Value1',
#        'Key2'   => 'Value2',
#        'Key3'   => 'Value3',
    });
    $window->TOPLEVEL->show;
#    my $window2 = $window->new;
#    $window2->TOPLEVEL->show;
    
    # Check for changes in $ADD
    Gtk->timeout_add(500, \&do_scan, $window->{FORM});

    Gtk->main;
    # Uncomment the line below to enable gettext checking
#    $window->write_gettext_strings("__", '/afs/cs.wisc.edu/u/n/m/nmueller/private/labstuff/library/src/Library.pot');
    return $window;
} # End of sub run
#===============================================================================
#=== Below are (overloaded) default signal handlers for 'add_window' class 
#===============================================================================
sub about_Form {
    my ($class) = @_;
    my $gtkversion = 
        Gtk->major_version.".".
        Gtk->minor_version.".".
        Gtk->micro_version;
    my $name = $0;
    my $message = 
        __PACKAGE__." ("._("version")." 0.01 - Wed Dec 20 15:14:03 CST 2000)\n".
        _("Written by")." Nathan Mueller <nmueller\@newton.cs.wisc.edu> \n\n".
        _("No description")." \n\n".
        "Gtk ".     _("version").": $gtkversion\n".
        "Gtk-Perl "._("version").": $Gtk::VERSION\n".
        _("run from file").": $name";
    __PACKAGE__->message_box($message, _("About")." \u".__PACKAGE__, [_('Dismiss'), _('Quit Program')], 1,
        "$Glade::PerlRun::pixmaps_directory/glade2perl_logo.xpm", 'left' );
} # End of sub about_Form

sub destroy_Form {
    my ($class, $data, $object, $instance) = @_;
    Gtk->main_quit; 
} # End of sub destroy_Form

sub toplevel_hide    { shift->get_toplevel->hide    }
sub toplevel_close   { shift->get_toplevel->close   }
sub toplevel_destroy { shift->get_toplevel->destroy }


#==============================================================================
#=== Below are (overloaded) signal handlers for 'add_window' class 
#==============================================================================
sub do_add {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_add";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    my $dbh = DBI->connect($CSL::DBs::csdb);
    $dbh->do("set search_path to library");
    my $isbn = $form->{'isbn_entry'}->get_text();
    $isbn =~ s/-//g;
    $isbn =~ tr/a-z/A-Z/;
    my $copy = 0;
    if ($isbn =~ /^(.+)C(\d+)$/)
    {
	$isbn = $1;
	$copy = $2;
    }
    my $category = $form->{'category_menu'}->child->get;
    
    my $query = $dbh->prepare("INSERT INTO books " .
			      "(isbn, cpy, cat, title, author, status) " .
			      "VALUES (?, ?, ?, ?, ?, 'Available')");
  
    $query->bind_param(1, $isbn);
    $query->bind_param(2, $copy);
    $query->bind_param(3, $category);
    $query->bind_param(4, $form->{'title_entry'}->get_text());
    $query->bind_param(5, $form->{'author_entry'}->get_text());
    $query->execute();
    $query->finish();
    $dbh->disconnect();

    $form->{'add_window'}->destroy;
    &Submain_window::getbooks();
    &Submain_window::getcds();
    &Submain_window::getlaptops();

} # End of sub doadd

sub do_cancel {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_cancel";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    $form->{'add_window'}->destroy();
} # End of sub do_cancel

sub do_scan {
    my ($class, $form) = @_;

    $form->{'isbn_entry'}->set_text($ADD) if ($ADD);

    1;
}
    






#==============================================================================
#=== This is the 'Submain_window' class                              
#==============================================================================
package Submain_window;
use CSL::PlRPC_Krb5;
use CSL::DBs;
use CSL::Pg;

use DBI;
use Mail::Send;
use Device::SerialPort;
require 5.000; use strict 'vars', 'refs', 'subs';
my $dbh;
my $sort = "isbn";
my $row = -1;
my %isbns;
my $csdb;
my $query;
my $port = Device::SerialPort->new($ENV{LIB_PORT} ||
				   "/dev/ttyS0", 1);
$port->baudrate(9600) if $port;
# UI class 'Submain_window' (version 0.01)
# 
# Copyright (c) Date Wed Dec 20 15:14:03 CST 2000
# Author Nathan Mueller <nmueller\@newton.cs.wisc.edu>
#
# Unspecified copying policy, please contact the author\n#  Nathan Mueller <nmueller\@newton.cs.wisc.edu>
#
#==============================================================================
# This perl source file was automatically generated by 
# Glade::PerlGenerate version 0.56 - Wed Apr 19 02:28:58 BST 2000
# Copyright (c) Author Dermot Musgrove <dermot.musgrove\@virgin.net>
#
# from Glade file /afs/cs.wisc.edu/u/n/m/nmueller/private/labstuff/library/library.glade
# Wed Dec 20 15:14:03 CST 2000
#==============================================================================

BEGIN {
    use vars qw( 
                 @ISA
                 %fields
                 $VERSION
             );
    # Existing signal handler modules
    use src::Library;
    # Uncomment the line below to enable gettext checking
#    use Glade::PerlSource;
    # Tell interpreter who we are inheriting from
    @ISA     = qw( main_window );
    # Uncomment the line below to enable gettext checking
#    @ISA      = qw( main_window Glade::PerlSource );
    $VERSION = '0.01';
    # Inherit the AUTOLOAD dynamic methods from main_window
    *AUTOLOAD = \&main_window::AUTOLOAD;
} # End of sub BEGIN

%fields = (
# Insert any extra data access methods that you want to add to 
#   our inherited super-constructor (or overload)
    USERDATA    => undef,
    VERSION     => '0.01',
);

sub DESTROY {
    # This sub will be called on object destruction
} # End of sub DESTROY

#==============================================================================
#=== Below are the overloaded class constructors
#==============================================================================
sub new {
    my $that  = shift;
    # Allow indirect constructor so that we can call eg. 
    #   $window1 = BusFrame->new; $window2 = $window1->new;
    my $class = ref($that) || $that;

    # Call our super-class constructor to get an object and reconsecrate it
    my $self = bless $that->SUPER::new(), $class;

    # Add our own data access methods to the inherited constructor
    my($element);
    foreach $element (keys %fields) {
        $self->{_permitted_fields}->{$element} = $fields{$element};
    }
    @{$self}{keys %fields} = values %fields;
    return $self;
} # End of sub new

sub run {
    my ($class) = @_;
    Gtk->init;
    # Uncomment the line below to enable gettext checking
#    $class->check_gettext_strings;
    my $window = $class->new;
    # Connect to the database
    $dbh = DBI->connect($CSL::DBs::csdb);
    $dbh->do("set search_path to library");
    &getbooks();
    &getcds();
    &getlaptops();

    # See if they're a librarian
    my $query = $dbh->prepare("select * from librarians where username
    = ?");
    $query->execute((getpwuid($<))[0]);
    unless ($query->fetchrow)
    {
	$window->{FORM}->{edit_button}->hide;
	$window->{FORM}->{add_button}->hide;
	$window->{FORM}->{remove_button}->hide;
	$window->{FORM}->{admonish_button}->hide;
	$window->{FORM}->{unadmonish_button}->hide;
	$window->{FORM}{toolbar1}->set_space_size(0);
    }

    # Insert your subclass user data key/value pairs 
    $window->USERDATA({
#        'Key1'   => 'Value1',
#        'Key2'   => 'Value2',
#        'Key3'   => 'Value3',
    });
    $window->TOPLEVEL->show;
#    my $window2 = $window->new;
#    $window2->TOPLEVEL->show;

    # Scanner timer
    if ($port)
    {
	$csdb = DBI->connect($CSL::DBs::easy_proxy);
	Gtk->timeout_add(500, \&do_scan);
    }
    
    Gtk->main;
    # Uncomment the line below to enable gettext checking
#    $window->write_gettext_strings("__", '/afs/cs.wisc.edu/u/n/m/nmueller/private/labstuff/library/src/Library.pot');
    return $window;
} # End of sub run
#===============================================================================
#=== Below are (overloaded) default signal handlers for 'main_window' class 
#===============================================================================
sub about_Form {
    my ($class) = @_;
    my $gtkversion = 
        Gtk->major_version.".".
        Gtk->minor_version.".".
        Gtk->micro_version;
    my $name = $0;
    my $message = 
        __PACKAGE__." ("._("version")." 0.01 - Wed Dec 20 15:14:03 CST 2000)\n".
        _("Written by")." Nathan Mueller <nmueller\@newton.cs.wisc.edu> \n\n".
        _("No description")." \n\n".
        "Gtk ".     _("version").": $gtkversion\n".
        "Gtk-Perl "._("version").": $Gtk::VERSION\n".
        _("run from file").": $name";
    __PACKAGE__->message_box($message, _("About")." \u".__PACKAGE__, [_('Dismiss'), _('Quit Program')], 1,
        "$Glade::PerlRun::pixmaps_directory/glade2perl_logo.xpm", 'left' );
} # End of sub about_Form

sub destroy_Form {
    my ($class, $data, $object, $instance) = @_;
    Gtk->main_quit; 
} # End of sub destroy_Form

sub toplevel_hide    { shift->get_toplevel->hide    }
sub toplevel_close   { shift->get_toplevel->close   }
sub toplevel_destroy { shift->get_toplevel->destroy }


#==============================================================================
#=== Below are (overloaded) signal handlers for 'main_window' class 
#==============================================================================
sub admonished
{
    my $user = $_[0];

    my $query = $dbh->prepare("SELECT reason FROM admonish " .
			      "WHERE username = ?");
    $query->bind_param(1, $user);
    $query->execute();
    my ($message) = $query->fetchrow();
    $query->finish();
    return $message;
}

sub do_add {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_add";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    Subadd_window->run();
} # End of sub do_add


sub do_admonish {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_admonish";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    Subuser_window->run("admonish", "", "Admonish:");
} # End of sub do_admonish

sub do_checkin {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_checkin";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};
    return if ($row == -1);

    my $page_index = $form->{'notebook1'}->current_page();
    my $active;
    if($page_index eq 0){
	$active = 'book_list';
    }
    elsif($page_index eq 1){
	$active = 'cd_list';
    }
    elsif($page_index eq 2){
	$active = 'laptop_list';
    }

    if (my $user = &recalled($form->{$active}->get_text($row, 0)))
    {
	my $msg = new Mail::Send;
	$msg->to("$user\@cs.wisc.edu");
	$msg->set("From", "lab\@cs.wisc.edu");
	$msg->subject("Your book is in");
	my $fh = $msg->open();
	print $fh "The book you requested -- \""
	    . $form->{$active}->get_text($row, 1)
		. "\" -- has been returned.  The CSL will hold the book for you for three business days.\n";
	print $fh "\n\t--CSL\n";
	$fh->close();

	my $query = $dbh->prepare("UPDATE recall " .
				  "SET returned = ? " .
				  "WHERE username = ? " .
				  "AND book = ?");
	$query->bind_param(1, time);
	$query->bind_param(2, $user);
	$query->bind_param(3, $form->{$active}->get_text($row, 0));
	$query->execute();
	$query->finish();
    }

    (my $isbn = $form->{$active}->get_text($row, 0)) =~ s/-//g;

    my $copy = 0;
    if ($isbn =~ /^(.+)C(\d+)$/)
    {
	$isbn = $1;
	$copy = $2;
    }

    my $query = $dbh->prepare("SELECT usr FROM books " .
			      "WHERE isbn = ? AND " .
			      "cpy = ?");
    $query->bind_param(1, $isbn);
    $query->bind_param(2, $copy);
    $query->execute();
    my ($user) = $query->fetchrow();
    $query->finish();

    $query = $dbh->prepare("UPDATE books " .
			   "SET status = 'Available', " .
			   "usr = '', " .
			   "due = NULL " .
			   "WHERE isbn = ? AND " .
			   "cpy = ?");
    $query->bind_param(1, $isbn);
    $query->bind_param(2, $copy);
    $query->execute();
    $query->finish();
    
    chomp(my $me = `whoami`);
    $query = $dbh->prepare("INSERT INTO log VALUES " .
			   "(?, ?, ?, CURRENT_TIMESTAMP, ?)");
    $query->bind_param(1, $user);
    $query->bind_param(2, "Checked In");
    $query->bind_param(3, $form->{$active}->get_text($row, 0));
    $query->bind_param(4, $me);
    $query->execute();
    $query->finish();

    $row = -1;
    &getbooks;
    &getcds;
    &getlaptops;

} # End of sub do_checkin

sub do_checkout {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_checkout";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};
    return if ($row == -1);

    my $page_index = $form->{'notebook1'}->current_page();
    my $active;
    if($page_index eq 0){
	$active = 'book_list';
    }
    elsif($page_index eq 1){
	$active = 'cd_list';
    }
    elsif($page_index eq 2){
	$active = 'laptop_list';
    }

    my $isbn = $form->{$active}->get_text($row, 0);
    $row = -1;

    Subuser_window->run("out", $isbn, "Checkout to:");
} # End of sub do_checkout

sub do_edit {
    my ($class, $data, $object, $instance, $event) = @_;
    my $title;
    my $author;
    my $category;
       
    my $me = __PACKAGE__."->do_edit";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};
    return if ($row == -1);
  
     my $page_index = $form->{'notebook1'}->current_page();
    my $active;
    if($page_index eq 0){
	$active = 'book_list';
    }
    elsif($page_index eq 1){
	$active = 'cd_list';
    }
    elsif($page_index eq 2){
	$active = 'laptop_list';
    }

    my $isbn = $form->{$active}->get_text($row, 0);
    $row = -1;

    my $munged_isbn = $isbn;
    $isbn =~ s/-//g;
    my $copy = 0;
    if ($isbn =~ /^(.+)C(\d+)$/)
    {
	$isbn = $1;
	$copy = $2;
    }
    
    my $query = $dbh->prepare("SELECT title, author, cat FROM books left outer join recall on books.isbn = recall.book WHERE books.isbn LIKE ?");

    $query->execute( "\%$isbn\%" );


    while ( my $ref = $query->fetchrow_hashref ) 
    #foreach my $book (@$result)
    {

        $title = $ref->{title};
	$author = $ref->{author};
	$category = $ref->{cat};
    }


    Subedit_window->run($isbn, $title, $author, $category, $copy);
} # End of sub do_edit




sub do_recall {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_recall";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};
    return if ($row == -1);

    my $page_index = $form->{'notebook1'}->current_page();
    my $active;
    if($page_index eq 0){
	$active = 'book_list';
    }
    elsif($page_index eq 1){
	$active = 'cd_list';
    }
    elsif($page_index eq 2){
	$active = 'laptop_list';
    }

    my $isbn = $form->{$active}->get_text($row, 0);
    $row = -1;
    Subuser_window->run("recall", $isbn, "Recall for:");
} # End of sub do_recall

sub do_remove {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_remove";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};
    return if ($row == -1);

    my $page_index = $form->{'notebook1'}->current_page();
    my $active;
    if($page_index eq 0){
	$active = 'book_list';
    }
    elsif($page_index eq 1){
	$active = 'cd_list';
    }
    elsif($page_index eq 2){
	$active = 'laptop_list';
    }

    my $isbn = $form->{$active}->get_text($row, 0);
    $isbn =~ s/-//g;
    my $copy = 0;
    if ($isbn =~ /^(.+)C(\d+)/)
    {
	$isbn = $1;
	$copy = $2;
    }
    
    my $query = $dbh->prepare("DELETE FROM books " .
			      "WHERE isbn = ? " .
			      "AND cpy = ?");
    $query->bind_param(1, $isbn);
    $query->bind_param(2, $copy);
    $query->execute();
    $query->finish();
    
    $row = -1;
    &getbooks();
    &getcds();
    &getlaptops();
    
} # End of sub do_remove

sub do_renew {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_renew";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};
    return if ($row == -1);
        
    my $page_index = $form->{'notebook1'}->current_page();
    my $active;
    if($page_index eq 0){
	$active = 'book_list';
    }
    elsif($page_index eq 1){
	$active = 'cd_list';
    }
    elsif($page_index eq 2){
	$active = 'laptop_list';
    }

     (my $isbn = $form->{$active}->get_text($row, 0)) =~ s/-//g;
    my $copy = 0;
    if ($isbn =~ /^(.+)C(\d+)$/)
    {
	$isbn = $1;
	$copy = $2;
    }

    my $query = $dbh->prepare("SELECT usr FROM books " .
			      "WHERE isbn = ? AND " .
			      "cpy = ?");
    $query->bind_param(1, $isbn);
    $query->bind_param(2, $copy);
    $query->execute();
    my ($user) = $query->fetchrow();
    $query->finish();
    return if (!$user);

    my $query = $dbh->prepare("SELECT count(*) FROM books " .
			      "WHERE usr  = ? AND status = 'Overdue'");
    $query->execute($user);
    my ($books) = $query->fetchrow();
    $query->finish();
    if ($books > 0)
    {
	Subalert_window->run($user . " has too many overdue books: $books");
	$dbh->disconnect();
	$form->{'user_window'}->destroy();
	return;
    }

    my $date = time + 60 * 60 * 24 * 3;
    my @time = localtime($date);
    if ($time[6] == 0 || $time[6] == 6)
    {
	$date += 60 * 60 * 24 * 2;
    }
    @time = localtime($date);
    $time[4]++;
    $time[5] += 1900;
    my $due = "$time[3]-$time[4]-$time[5]";

    if (&recalled($form->{$active}->get_text($row, 0), $user))
    {
	Subalert_window->run("That book has been recalled");
	return;
    }

    if (my $message = &admonished($user))
    {
	Subalert_window->run("$user has been admonished: $message");
	return;
    }
    
    my $query = $dbh->prepare("UPDATE books " .
			      "SET status = 'Checked Out', " .
			      "due = ? " .
			      "WHERE isbn = ? AND " .
			      "cpy = ?");
    $query->bind_param(1, $due);
    $query->bind_param(2, $isbn);
    $query->bind_param(3, $copy);
    $query->execute();
    $query->finish();
    
    chomp(my $me = `whoami`);
    $query = $dbh->prepare("INSERT INTO log " .
			   "SELECT usr, ?, ?, CURRENT_TIMESTAMP, ? " .
			   "FROM books " .
			   "WHERE isbn = ? " .
			   "AND cpy = ?");
    $query->bind_param(1, "Renewed");
    $query->bind_param(2, $form->{$active}->get_text($row, 0));
    $query->bind_param(3, $me);
    $query->bind_param(4, $isbn);
    $query->bind_param(5, $copy);
    $query->execute();
    $query->finish();

    $row = -1;
    &getbooks();
    &getcds();
    &getlaptops();

} # End of sub do_renew

sub do_reserve {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_reserve";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};
    return if ($row == -1);
    
my $page_index = $form->{'notebook1'}->current_page();
    my $active;
    if($page_index eq 0){
	$active = 'book_list';
    }
    elsif($page_index eq 1){
	$active = 'cd_list';
    }
    elsif($page_index eq 2){
	$active = 'laptop_list';
    }

    my $isbn = $form->{$active}->get_text($row, 0);
    $row = -1;
    Subuser_window->run("lab", $isbn, "Reserve for:");
} # End of sub do_reserve

sub do_scan {
    my $form = $__PACKAGE__::all_forms->{'main_window-1'};

    chomp(my $result = $port->input());

    my $page_index = $form->{'notebook1'}->current_page();
    my $active;
    if($page_index eq 0){
	$active = 'book_list';
    }
    elsif($page_index eq 1){
	$active = 'cd_list';
    }
    elsif($page_index eq 2){
	$active = 'laptop_list';
    }

    if ($result)
    {
	# Go to the right row
	if ($isbns{$result})
	{
	    $form->{$active}->select_row($isbns{$result}, 0);
	    $form->{$active}->moveto($isbns{$result}, 0, .5, .5)
		if ($form->{$active}->row_is_visible($isbns{$result}) eq "none");
	}
	
	# Set the add window stuff
	$Subadd_window::ADD = $result;
	
	# Get the login from ID
	chop($result);
	my $query = $csdb->prepare("person");
	$query->execute($result);
	($Subuser_window::USER) = $query->fetchrow();
    }

    1;
}

sub do_select {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_select";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    $row = $event;
} # End of sub do_select

sub do_sort {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_sort";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    $sort = ('isbn', 'title', 'author', 'status DESC', "textcat(usr, 'zzzzzz')",
	     'due DESC')[$_[4]];
    &getbooks();
    &getcds();
    &getlaptops();
    
} # End of sub do_sort

sub do_unadmonish {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_unadmonish";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    Subuser_window->run("unadmonish", "", "Unadmonish:");
} # End of sub do_unadmonish

sub getbooks
{
    my $query = $dbh->prepare("SELECT isbn, cpy, " .
			      "title, author, " .
			      "status, usr, due, returned " .
			      "FROM books left outer join recall on
books.isbn = recall.book " .
			      "WHERE cat = 'book' " .
			      "ORDER BY $sort");
    $query->execute;
    my $result = $query->fetchall_arrayref;
    $query->finish();
    
    my $form = $__PACKAGE__::all_forms->{'main_window-1'};

    $form->{'book_list'}->freeze();
    $form->{'book_list'}->clear();

    my $i = 0;
    foreach my $book (@$result)
    {
	my $isbn = shift @$book;
	my $copy = shift @$book;
	$isbn = $isbn . "C" . $copy if ($copy);
	@$book = ($isbn, @$book);
	$isbns{$isbn} = $i++;
	my $recall = pop @$book;
	$recall += 60 * 60 * 24 * 2;
	my @time = localtime($recall);
	if ($time[6] == 0 || $time[6] == 6)
	{
	    $recall += 60 * 60 * 24 * 2;
	}
	$book->[3] = "Recalled" if $recall > time;
	
        $form->{'book_list'}->append(@$book);
    }
   
    $form->{'book_list'}->thaw();
}

sub getcds
{
    my $query = $dbh->prepare("SELECT isbn, cpy, " .
			      "title, author, " .
			      "status, usr, due, returned " .
			      "FROM books left outer join recall on
books.isbn = recall.book " .
			      "WHERE cat = 'cd' ORDER BY $sort");
    $query->execute;
    my $result = $query->fetchall_arrayref;
    $query->finish();

    my $form = $__PACKAGE__::all_forms->{'main_window-1'};

    $form->{'cd_list'}->freeze();
    $form->{'cd_list'}->clear();

    my $i = 0;
    foreach my $cd (@$result)
    {
	my $isbn = shift @$cd;
	my $copy = shift @$cd;
	$isbn = $isbn . "C" . $copy if ($copy);
	@$cd = ($isbn, @$cd);
	$isbns{$isbn} = $i++;
	my $recall = pop @$cd;
	$recall += 60 * 60 * 24 * 2;
	my @time = localtime($recall);
	if ($time[6] == 0 || $time[6] == 6)
	{
	    $recall += 60 * 60 * 24 * 2;
	}
	$cd->[3] = "Recalled" if $recall > time;
	
        $form->{'cd_list'}->append(@$cd);
    }
   
    $form->{'cd_list'}->thaw();
}

sub getlaptops
{
    my $query = $dbh->prepare("SELECT isbn, cpy, " .
			      "title, author, " .
			      "status, usr, due, returned " .
			      "FROM books left outer join recall on
books.isbn = recall.book " .
			      "WHERE cat = 'laptop' ORDER BY $sort");
    $query->execute;
    my $result = $query->fetchall_arrayref;
    $query->finish();

    my $form = $__PACKAGE__::all_forms->{'main_window-1'};

    $form->{'laptop_list'}->freeze();
    $form->{'laptop_list'}->clear();

    my $i = 0;
    foreach my $laptop (@$result)
    {
	my $isbn = shift @$laptop;
	my $copy = shift @$laptop;
	$isbn = $isbn . "C" . $copy if ($copy);
	@$laptop = ($isbn, @$laptop);
	$isbns{$isbn} = $i++;
	my $recall = pop @$laptop;
	$recall += 60 * 60 * 24 * 2;
	my @time = localtime($recall);
	if ($time[6] == 0 || $time[6] == 6)
	{
	    $recall += 60 * 60 * 24 * 2;
	}
	$laptop->[3] = "Recalled" if $recall > time;
	
        $form->{'laptop_list'}->append(@$laptop);
    }
   
    $form->{'laptop_list'}->thaw();
}

sub quit {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->quit";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    $port->close if $port;
    
    exit;

} # End of sub quit

sub recalled
{
    my ($isbn, $user) = @_;

    my $query = $dbh->prepare("SELECT username, returned " .
			      "FROM recall " .
			      "WHERE book = ?");
    $query->bind_param(1, $isbn);
    $query->execute();
    my ($username, $returned) = $query->fetchrow();
    $query->finish();

    $returned += 60 * 60 * 24 * 2;
    my @time = localtime($returned);
    if ($time[6] == 0 || $time[6] == 6)
    {
	$returned += 60 * 60 * 24 * 2;
    }

    if ($returned < time)
    {
	$query = $dbh->prepare("delete from recall where book = ?");
	$query->execute($isbn);
	return 0;
    }

    if ($username eq $user)
    { 
	return 0;
    }
    else
    {
	return $username;
    }
}
    

sub on_search_query_key_press_event {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->on_search_query_key_press_event";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    my $active = $form->{category_menu}->child->get;
    my $terms = $form->{search_query}->get_text;
    $active =~ tr/A-Z/a-z/;

    my $page_index = $form->{'notebook1'}->current_page();
    my $category;
    if($page_index eq 0){
	$category = 'book';
    }
    elsif($page_index eq 1){
	$category = 'cd';
    }
    elsif($page_index eq 2){
	$category = 'laptop';
    }


    my $query = $dbh->prepare("SELECT isbn, cpy, " .
			      "title, author, " .
			      "status, usr, due, returned " .
			      "FROM books left outer join recall on books.isbn = recall.book " . 
			      "WHERE books.$active iLIKE '%$terms%' AND books.cat = ?" . 
			      "ORDER BY $sort");
    $query->execute($category);
    my $result = $query->fetchall_arrayref;
    $query->finish();
    
    my $form = $__PACKAGE__::all_forms->{'main_window-1'};
    
    my $page;

    if($category eq 'book'){
	$page = 'book_list';
    }
    elsif($category eq 'cd'){
	$page = 'cd_list';
    }
    elsif($category eq 'laptop'){
	$page = 'laptop_list';
    }

    $form->{$page}->freeze();
    $form->{$page}->clear();

    my $i = 0;
    foreach my $book (@$result)
    {
	my $isbn = shift @$book;
	my $copy = shift @$book;
	$isbn = $isbn . "C" . $copy if ($copy);
	@$book = ($isbn, @$book);
	$isbns{$isbn} = $i++;
	my $recall = pop @$book;
	$recall += 60 * 60 * 24 * 2;
	my @time = localtime($recall);
	if ($time[6] == 0 || $time[6] == 6)
	{
	    $recall += 60 * 60 * 24 * 2;
	}
	$book->[3] = "Recalled" if $recall > time;
	
	$form->{$page}->append(@$book);
    }
    
    $form->{$page}->thaw();
    

}
sub on_search_button_clicked{

    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->on_search_button_clicked";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};
    my $active = $form->{category_menu}->child->get;
    my $terms = $form->{search_query}->get_text;
    $active =~ tr/A-Z/a-z/;
    

    my $page_index = $form->{'notebook1'}->current_page();
    my $category;
    if($page_index eq 0){
	$category = 'book';
    }
    elsif($page_index eq 1){
	$category = 'cd';
    }
    elsif($page_index eq 2){
	$category = 'laptop';
    }


    my $query = $dbh->prepare("SELECT isbn, cpy, " .
			      "title, author, " .
			      "status, usr, due, returned " .
			      "FROM books left outer join recall on books.isbn = recall.book " . 
			      "WHERE books.$active iLIKE '%$terms%' AND books.cat = ?" . 
			      "ORDER BY $sort");
    $query->execute($category);
    my $result = $query->fetchall_arrayref;
    $query->finish();
    
    my $form = $__PACKAGE__::all_forms->{'main_window-1'};
    
    my $page;

    if($category eq 'book'){
	$page = 'book_list';
    }
    elsif($category eq 'cd'){
	$page = 'cd_list';
    }
    elsif($category eq 'laptop'){
	$page = 'laptop_list';
    }

    $form->{$page}->freeze();
    $form->{$page}->clear();

    my $i = 0;
    foreach my $book (@$result)
    {
	my $isbn = shift @$book;
	my $copy = shift @$book;
	$isbn = $isbn . "C" . $copy if ($copy);
	@$book = ($isbn, @$book);
	$isbns{$isbn} = $i++;
	my $recall = pop @$book;
	$recall += 60 * 60 * 24 * 2;
	my @time = localtime($recall);
	if ($time[6] == 0 || $time[6] == 6)
	{
	    $recall += 60 * 60 * 24 * 2;
	}
	$book->[3] = "Recalled" if $recall > time;
	
	$form->{$page}->append(@$book);
    }
    
    $form->{$page}->thaw();
 
}
sub on_show_all_button_clicked{
    &getbooks();
    &getcds();
    &getlaptops();
}

#==============================================================================
#=== This is the 'Subuser_window' class                              
#==============================================================================
package Subuser_window;
require 5.000; use strict 'vars', 'refs', 'subs';
use vars qw($USER);
use CSL::DBs;
my $function;
my $isbn;
# UI class 'Subuser_window' (version 0.01)
# 
# Copyright (c) Date Wed Dec 20 15:14:03 CST 2000
# Author Nathan Mueller <nmueller\@newton.cs.wisc.edu>
#
# Unspecified copying policy, please contact the author\n#  Nathan Mueller <nmueller\@newton.cs.wisc.edu>
#
#==============================================================================
# This perl source file was automatically generated by 
# Glade::PerlGenerate version 0.56 - Wed Apr 19 02:28:58 BST 2000
# Copyright (c) Author Dermot Musgrove <dermot.musgrove\@virgin.net>
#
# from Glade file /afs/cs.wisc.edu/u/n/m/nmueller/private/labstuff/library/library.glade
# Wed Dec 20 15:14:03 CST 2000
#==============================================================================

BEGIN {
    use vars qw( 
                 @ISA
                 %fields
                 $VERSION
             );
    # Existing signal handler modules
    use src::Library;
    # Uncomment the line below to enable gettext checking
#    use Glade::PerlSource;
    # Tell interpreter who we are inheriting from
    @ISA     = qw( user_window );
    # Uncomment the line below to enable gettext checking
#    @ISA      = qw( user_window Glade::PerlSource );
    $VERSION = '0.01';
    # Inherit the AUTOLOAD dynamic methods from user_window
    *AUTOLOAD = \&user_window::AUTOLOAD;
} # End of sub BEGIN

%fields = (
# Insert any extra data access methods that you want to add to 
#   our inherited super-constructor (or overload)
    USERDATA    => undef,
    VERSION     => '0.01',
);

sub DESTROY {
    # This sub will be called on object destruction
} # End of sub DESTROY

#==============================================================================
#=== Below are the overloaded class constructors
#==============================================================================
sub new {
    my $that  = shift;
    # Allow indirect constructor so that we can call eg. 
    #   $window1 = BusFrame->new; $window2 = $window1->new;
    my $class = ref($that) || $that;

    # Call our super-class constructor to get an object and reconsecrate it
    my $self = bless $that->SUPER::new(), $class;

    # Add our own data access methods to the inherited constructor
    my($element);
    foreach $element (keys %fields) {
        $self->{_permitted_fields}->{$element} = $fields{$element};
    }
    @{$self}{keys %fields} = values %fields;
    return $self;
} # End of sub new

sub run {
    my $class = $_[0];
    my $caption = $_[3];
    ($function, $isbn) = @_[1,2];
    Gtk->init;
    # Uncomment the line below to enable gettext checking
#    $class->check_gettext_strings;
    my $window = $class->new;
    # Insert your subclass user data key/value pairs 
    $window->USERDATA({
#        'Key1'   => 'Value1',
#        'Key2'   => 'Value2',
#        'Key3'   => 'Value3',
    });
    $window->TOPLEVEL->show;
    $window->{'FORM'}->{'prompt_label'}->set_text($caption);
    
    # Check for changes in $ADD
    Gtk->timeout_add(500, \&do_scan, $window->{FORM});

#    my $window2 = $window->new;
#    $window2->TOPLEVEL->show;
    Gtk->main;
    # Uncomment the line below to enable gettext checking
#    $window->write_gettext_strings("__", '/afs/cs.wisc.edu/u/n/m/nmueller/private/labstuff/library/src/Library.pot');
    return $window;
} # End of sub run
#===============================================================================
#=== Below are (overloaded) default signal handlers for 'user_window' class 
#===============================================================================
sub about_Form {
    my ($class) = @_;
    my $gtkversion = 
        Gtk->major_version.".".
        Gtk->minor_version.".".
        Gtk->micro_version;
    my $name = $0;
    my $message = 
        __PACKAGE__." ("._("version")." 0.01 - Wed Dec 20 15:14:03 CST 2000)\n".
        _("Written by")." Nathan Mueller <nmueller\@newton.cs.wisc.edu> \n\n".
        _("No description")." \n\n".
        "Gtk ".     _("version").": $gtkversion\n".
        "Gtk-Perl "._("version").": $Gtk::VERSION\n".
        _("run from file").": $name";
    __PACKAGE__->message_box($message, _("About")." \u".__PACKAGE__, [_('Dismiss'), _('Quit Program')], 1,
        "$Glade::PerlRun::pixmaps_directory/glade2perl_logo.xpm", 'left' );
} # End of sub about_Form

sub destroy_Form {
    my ($class, $data, $object, $instance) = @_;
    Gtk->main_quit; 
} # End of sub destroy_Form

sub toplevel_hide    { shift->get_toplevel->hide    }
sub toplevel_close   { shift->get_toplevel->close   }
sub toplevel_destroy { shift->get_toplevel->destroy }


#==============================================================================
#=== Below are (overloaded) signal handlers for 'user_window' class 
#==============================================================================
sub do_user {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_user";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    my $dbh = DBI->connect($CSL::DBs::csdb);
    $dbh->do("set search_path to library");
    
    if ($function ne "unadmonish" &&
	(my $message = &Submain_window::admonished($form->{'user_entry'}->get_text())))
    {
	Subalert_window->run($form->{'user_entry'}->get_text() . " has been admonished: $message");
	$dbh->disconnect();
	$form->{'user_window'}->destroy();
	return;
    }

    my $query = $dbh->prepare("SELECT count(*) FROM books " .
			      "WHERE usr = ? AND status = 'Overdue'");
    $query->execute($form->{'user_entry'}->get_text());
    my ($books) = $query->fetchrow();
    $query->finish();
    if ($books > 0 && ($function eq "out" || $function eq "recall"))
    {
	Subalert_window->run($form->{'user_entry'}->get_text() . " has too many overdue books: $books");
	$dbh->disconnect();
	$form->{'user_window'}->destroy();
	return;
    }

    if (!getpwnam($form->{'user_entry'}->get_text()) && $function ne "admonish-1")
    {
	Subalert_window->run("That user doesn't exist: " . $form->{'user_entry'}->get_text());
    }

    if ($function eq "out")
    {
	if (&Submain_window::recalled($isbn, $form->{'user_entry'}->get_text()))
	{
	    Subalert_window->run("That book has been recalled");
	}
	else
	{
	    my $query = $dbh->prepare("DELETE FROM recall " .
				      "WHERE book = ? " .
				      "AND username = ?");
	    $query->bind_param(1, $isbn);
	    $query->bind_param(2, $form->{'user_entry'}->get_text());
	    $query->execute();
	    $query->finish();

	}
	
	my $query = $dbh->prepare("SELECT date_part('dow', CURRENT_DATE + 3)");
	$query->execute();
	my ($dow) = $query->fetchrow();
	my $add = 3;
	$add += 2 if ($dow == 0 || $dow == 1 || $dow == 6);
	$query->finish();
	
	my $munged_isbn = $isbn;
	$isbn =~ s/-//g;
	my $copy = 0;
	if ($isbn =~ /^(.+)C(\d+)$/)
	{
	    $isbn = $1;
	    $copy = $2;
	}

	$query = $dbh->prepare("UPDATE books " .
			       "SET status = 'Checked Out', " .
			       "usr = ?, " .
			       "due = CURRENT_DATE + $add " .
			       "WHERE isbn = ? AND " .
			       "cpy = ?");
	$query->bind_param(1, $form->{'user_entry'}->get_text());
	$query->bind_param(2, $isbn);
	$query->bind_param(3, $copy);
	$query->execute();
	$query->finish();

	chomp(my $me = `whoami`);
	$query = $dbh->prepare("INSERT INTO log VALUES " .
			       "(?, ?, ?, CURRENT_TIMESTAMP, ?)");
	$query->bind_param(1, $form->{'user_entry'}->get_text());
	$query->bind_param(2, "Checked Out");
	$query->bind_param(3, $munged_isbn);
	$query->bind_param(4, $me);
	$query->execute();
	$query->finish();
	&Submain_window::getbooks();
	&Submain_window::getcds();
	&Submain_window::getlaptops();
    }
    elsif ($function eq "lab")
    {
	my $munged_isbn = $isbn;
	$isbn =~ s/-//g;
	my $copy = 0;
	if ($isbn =~ /^(.+)C(\d+)$/)
	{
	    $isbn = $1;
	    $copy = $2;
	}

	my $query = $dbh->prepare("UPDATE books " .
				  "SET status = 'Lab', " .
				  "usr = ?, " .
				  "due = NULL " .
				  "WHERE isbn = ? AND " .
				  "cpy = ?");
	$query->bind_param(1, $form->{'user_entry'}->get_text());
	$query->bind_param(2, $isbn);
	$query->bind_param(3, $copy);
	$query->execute();
	$query->finish();

	chomp(my $me = `whoami`);
	$query = $dbh->prepare("INSERT INTO log VALUES " .
			       "(?, ?, ?, CURRENT_TIMESTAMP, ?)");
	$query->bind_param(1, $form->{'user_entry'}->get_text());
	$query->bind_param(2, "Checked Out(LAB)");
	$query->bind_param(3, $munged_isbn);
	$query->bind_param(4, $me);
	$query->execute();
	$query->finish();
	
	&Submain_window::getbooks();
	&Submain_window::getcds();
	&Submain_window::getlaptops();

    }
    elsif ($function eq "admonish")
    {
	my $query = $dbh->prepare("DELETE FROM recall " .
				  "WHERE username = ?");
	$query->bind_param(1, $form->{'user_entry'}->get_text());
	$query->execute();
	$query->finish();
	Subuser_window->run("admonish-1",
			    $form->{'user_entry'}->get_text(),
			    "Reason for admonish:");
    }
    elsif ($function eq "admonish-1")
    {
	my $query = $dbh->prepare("INSERT INTO admonish " .
				  "VALUES (?, ?)");
	$query->bind_param(1, $isbn);
	$query->bind_param(2, $form->{'user_entry'}->get_text());
	$query->execute();
	$query->finish();
    }
    elsif ($function eq "unadmonish")
    {
	my $query = $dbh->prepare("DELETE FROM admonish " .
				  "WHERE username = ?");
	$query->bind_param(1, $form->{'user_entry'}->get_text());
	$query->execute();
	$query->finish();
    }
    elsif ($function eq "recall")
    {
	my $query = $dbh->prepare("INSERT INTO recall " .
				  "VALUES (?, ?, NULL)");
	$query->bind_param(1, $form->{'user_entry'}->get_text());
	$query->bind_param(2, $isbn);
	$query->execute();
	$query->finish();
    }

    &Submain_window::getbooks();
    
    $dbh->disconnect();
    $form->{'user_window'}->destroy();
} # End of sub do_user

sub do_scan {
    my ($form) = @_;

    $form->{'user_entry'}->set_text($USER) if ($USER);

    1;
}

#==============================================================================
#=== This is the 'Subalert_window' class                              
#==============================================================================
package Subalert_window;
require 5.000; use strict 'vars', 'refs', 'subs';
# UI class 'Subalert_window' (version 0.01)
# 
# Copyright (c) Date Wed Dec 20 15:14:03 CST 2000
# Author Nathan Mueller <nmueller\@newton.cs.wisc.edu>
#
# Unspecified copying policy, please contact the author\n#  Nathan Mueller <nmueller\@newton.cs.wisc.edu>
#
#==============================================================================
# This perl source file was automatically generated by 
# Glade::PerlGenerate version 0.56 - Wed Apr 19 02:28:58 BST 2000
# Copyright (c) Author Dermot Musgrove <dermot.musgrove\@virgin.net>
#
# from Glade file /afs/cs.wisc.edu/u/n/m/nmueller/private/labstuff/library/library.glade
# Wed Dec 20 15:14:03 CST 2000
#==============================================================================

BEGIN {
    use vars qw( 
                 @ISA
                 %fields
                 $VERSION
             );
    # Existing signal handler modules
    use src::Library;
    # Uncomment the 07h 23m 25s line below to enable gettext checking
#    use Glade::PerlSource;
    # Tell interpreter who we are inheriting from
    @ISA     = qw( alert_window );
    # Uncomment the line below to enable gettext checking
#    @ISA      = qw( alert_window Glade::PerlSource );
    $VERSION = '0.01';
    # Inherit the AUTOLOAD dynamic methods from alert_window
    *AUTOLOAD = \&alert_window::AUTOLOAD;
} # End of sub BEGIN

%fields = (
# Insert any extra data access methods that you want to add to 
#   our inherited super-constructor (or overload)
    USERDATA    => undef,
    VERSION     => '0.01',
);

sub DESTROY {
    # This sub will be called on object destruction
} # End of sub DESTROY

#==============================================================================
#=== Below are the overloaded class constructors
#==============================================================================
sub new {
    my $that  = shift;
    # Allow indirect constructor so that we can call eg. 
    #   $window1 = BusFrame->new; $window2 = $window1->new;
    my $class = ref($that) || $that;

    # Call our super-class constructor to get an object and reconsecrate it
    my $self = bless $that->SUPER::new(), $class;

    # Add our own data access methods to the inherited constructor
    my($element);
    foreach $element (keys %fields) {
        $self->{_permitted_fields}->{$element} = $fields{$element};
    }
    @{$self}{keys %fields} = values %fields;
    return $self;
} # End of sub new

sub run {
    my ($class, $message) = @_;
    Gtk->init;
    # Uncomment the line below to enable gettext checking
#    $class->check_gettext_strings;
    my $window = $class->new;
    # Insert your subclass user data key/value pairs 
    $window->USERDATA({
#        'Key1'   => 'Value1',
#        'Key2'   => 'Value2',
#        'Key3'   => 'Value3',
    });
    $window->TOPLEVEL->show;
    $window->{'FORM'}->{'reason_label'}->set_text($message);
#    my $window2 = $window->new;
#    $window2->TOPLEVEL->show;
    Gtk->main;
    # Uncomment the line below to enable gettext checking
#    $window->write_gettext_strings("__", '/afs/cs.wisc.edu/u/n/m/nmueller/private/labstuff/library/src/Library.pot');
    return $window;
} # End of sub run
#===============================================================================
#=== Below are (overloaded) default signal handlers for 'alert_window' class 
#===============================================================================
sub about_Form {
    my ($class) = @_;
    my $gtkversion = 
        Gtk->major_version.".".
        Gtk->minor_version.".".
        Gtk->micro_version;
    my $name = $0;
    my $message = 
        __PACKAGE__." ("._("version")." 0.01 - Wed Dec 20 15:14:03 CST 2000)\n".
        _("Written by")." Nathan Mueller <nmueller\@newton.cs.wisc.edu> \n\n".
        _("No description")." \n\n".
        "Gtk ".     _("version").": $gtkversion\n".
        "Gtk-Perl "._("version").": $Gtk::VERSION\n".
        _("run from file").": $name";
    __PACKAGE__->message_box($message, _("About")." \u".__PACKAGE__, [_('Dismiss'), _('Quit Program')], 1,
        "$Glade::PerlRun::pixmaps_directory/glade2perl_logo.xpm", 'left' );
} # End of sub about_Form

sub destroy_Form {
    my ($class, $data, $object, $instance) = @_;
    Gtk->main_quit; 
} # End of sub destroy_Form

sub toplevel_hide    { shift->get_toplevel->hide    }
sub toplevel_close   { shift->get_toplevel->close   }
sub toplevel_destroy { shift->get_toplevel->destroy }


#==============================================================================
#=== Below are (overloaded) signal handlers for 'alert_window' class 
#==============================================================================
sub do_close {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_close";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    $form->{'alert_window'}->destroy();
} # End of sub do_close


#==============================================================================
#=== This is the 'Subedit_window' class                              
#==============================================================================
package Subedit_window;
require 5.000; use strict 'vars', 'refs', 'subs';
use vars qw($ADD);
# UI class 'Subedit_window' (version 0.01)
# 
# Copyright (c) Date Wed Dec 20 15:14:03 CST 2000
# Author Nathan Mueller <nmueller\@newton.cs.wisc.edu>
#
# Unspecified copying policy, please contact the author\n#  Nathan Mueller <nmueller\@newton.cs.wisc.edu>
#
#==============================================================================
# This perl source file was automatically generated by 
# Glade::PerlGenerate version 0.56 - Wed Apr 19 02:28:58 BST 2000
# Copyright (c) Author Dermot Musgrove <dermot.musgrove\@virgin.net>
#
# from Glade file /afs/cs.wisc.edu/u/n/m/nmueller/private/labstuff/library/library.glade
# Wed Dec 20 15:14:03 CST 2000
#==============================================================================

BEGIN {
    use vars qw( 
                 @ISA
                 %fields
                 $VERSION
             );
    # Existing signal handler modules
    use src::Library;
    # Uncomment the line below to enable gettext checking
#    use Glade::PerlSource;
    # Tell interpreter who we are inheriting from
    @ISA     = qw( edit_window );
    # Uncomment the line below to enable gettext checking
#    @ISA      = qw( add_window Glade::PerlSource );
    $VERSION = '0.01';
    # Inherit the AUTOLOAD dynamic methods from add_window
    *AUTOLOAD = \&edit_window::AUTOLOAD;
} # End of sub BEGIN

%fields = (
# Insert any extra data access methods that you want to add to 
#   our inherited super-constructor (or overload)
    USERDATA    => undef,
    VERSION     => '0.01',
);

sub DESTROY {
    # This sub will be called on object destruction
} # End of sub DESTROY

#==============================================================================
#=== Below are the overloaded class constructors
#==============================================================================
sub new {
    my $that  = shift;
    # Allow indirect constructor so that we can call eg. 
    #   $window1 = BusFrame->new; $window2 = $window1->new;
    my $class = ref($that) || $that;

    # Call our super-class constructor to get an object and reconsecrate it
    my $self = bless $that->SUPER::new(), $class;

    # Add our own data access methods to the inherited constructor
    my($element);
    foreach $element (keys %fields) {
        $self->{_permitted_fields}->{$element} = $fields{$element};
    }
    @{$self}{keys %fields} = values %fields;
    return $self;
} # End of sub new

sub run {
    my ($class) = @_[0];
    my ($isbn) = @_[1];
    my ($title) = @_[2];
    my ($author) = @_[3];
    my ($category) = @_[4];
    my ($copy) = @_[5];

    Gtk->init;
    # Uncomment the line below to enable gettext checking
    #$class->check_gettext_strings;
    my $window = $class->new;
    # Insert your subclass user data key/value pairs 
    $window->USERDATA({
#        'Key1'   => 'Value1',
#        'Key2'   => 'Value2',
#        'Key3'   => 'Value3',
    });
    $window->TOPLEVEL->show;
    $window->{'FORM'}->{'old_isbn_entry'}->set_text($isbn);
    $window->{'FORM'}->{'copy_entry'}->set_text($copy);
    my $index = 0 ;
 
    if ($category eq 'book'){
	$index = 0;
    }
    if ($category eq 'cd'){
	$index = 1;
    }
    if ($category eq 'laptop'){
	$index = 2 ;
    }
    
    $window->{FORM}{category_menu}->set_history( $index );
    $window->{'FORM'}->{'isbn_entry'}->set_text($isbn);
    $window->{'FORM'}->{'author_entry'}->set_text($author);
    $window->{'FORM'}->{'title_entry'}->set_text($title);

    Gtk->timeout_add(500, \&do_scan, $window->{FORM});
    Gtk->main;

    &Submain_window::getbooks();
    &Submain_window::getcds();
    &Submain_window::getlaptops();
    # Uncomment the line below to enable gettext checking
    #    $window->write_gettext_strings("__", '/afs/cs.wisc.edu/u/n/m/nmueller/private/labstuff/library/src/Library.pot');
    return $window;
} # End of sub run
#===============================================================================
#=== Below are (overloaded) default signal handlers for 'edit_window' class 
#===============================================================================
sub about_Form {
    my ($class) = @_;
    my $gtkversion = 
        Gtk->major_version.".".
        Gtk->minor_version.".".
        Gtk->micro_version;
    my $name = $0;
    my $message = 
        __PACKAGE__." ("._("version")." 0.01 - Wed Dec 20 15:14:03 CST 2000)\n".
        _("Written by")." Nathan Mueller <nmueller\@newton.cs.wisc.edu> \n\n".
        _("No description")." \n\n".
        "Gtk ".     _("version").": $gtkversion\n".
        "Gtk-Perl "._("version").": $Gtk::VERSION\n".
        _("run from file").": $name";
    __PACKAGE__->message_box($message, _("About")." \u".__PACKAGE__, [_('Dismiss'), _('Quit Program')], 1,
        "$Glade::PerlRun::pixmaps_directory/glade2perl_logo.xpm", 'left' );
} # End of sub about_Form

sub destroy_Form {
    my ($class, $data, $object, $instance) = @_;
    Gtk->main_quit; 
} # End of sub destroy_Form

sub toplevel_hide    { shift->get_toplevel->hide    }
sub toplevel_close   { shift->get_toplevel->close   }
sub toplevel_destroy { shift->get_toplevel->destroy }


#==============================================================================
#=== Below are (overloaded) signal handlers for 'edit_window' class 
#==============================================================================

sub do_edit {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_edit";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    my $dbh = DBI->connect($CSL::DBs::csdb);
    $dbh->do("set search_path to library");
    my $old_isbn = $form->{'old_isbn_entry'}->get_text();
    my $isbn = $form->{'isbn_entry'}->get_text();
    my $author = $form->{'author_entry'}->get_text();
    my $title = $form->{'title_entry'}->get_text();
    my $category = $form->{'category_menu'}->child->get;
    my $copy = $form->{'copy_entry'}->get_text();

    $isbn =~ s/-//g;
    $isbn =~ tr/a-z/A-Z/;
    
    my $qstr = "update books set";
    my $flag = 0;

    unless ( $isbn =~ /$old_isbn/ ) {
	$qstr .= " isbn = ?, cpy = ?";
	$flag = 1;
    }

    $qstr .= " author = ?, title = ?, cat = ? WHERE isbn = ?";

    my $query = $dbh->prepare( $qstr );

    if ( $flag ) {
	$query->execute( $isbn, $copy, $author, $title, $category, $old_isbn );
    }
    else {
	$query->execute( $author, $title, $category, $old_isbn );
    }


    $dbh->disconnect();

    $form->{'edit_window'}->destroy;
    &Submain_window::getbooks();
    &Submain_window::getcds();
    &Submain_window::getlaptops();

} # End of sub do_edit

sub do_cancel {
    my ($class, $data, $object, $instance, $event) = @_;
    my $me = __PACKAGE__."->do_cancel";
    # Get ref to hash of all widgets on our form
    my $form = $__PACKAGE__::all_forms->{$instance};

    $form->{'edit_window'}->destroy();
} # End of sub do_cancel

sub do_scan {
    my ($class, $form) = @_;

    $form->{'isbn_entry'}->set_text($ADD) if ($ADD);

    1;
}
    


    
1;

__END__

#===============================================================================
#==== Documentation
#===============================================================================
=pod

=head1 NAME

SubLibrary - version 0.01 Wed Dec 20 15:14:03 CST 2000

No description

=head1 SYNOPSIS

 use SubLibrary;

 if ($we_want_to_subclass_this_class) {
   # Inherit the AUTOLOAD dynamic methods from Submain_window
   *AUTOLOAD = \&Submain_window::AUTOLOAD;

   # Tell interpreter who we are inheriting from
   use vars qw( @ISA ); @ISA = qw( Submain_window );
 }
 
 To construct the window object and show it call
 
 Gtk->init;
 my $window = Submain_window->new;
 $window->TOPLEVEL->show;
 Gtk->main;
 
 OR use the shorthand for the above calls
 
 Submain_window->run;

=head1 DESCRIPTION

Unfortunately, the author has not yet written any documentation :-(

=head1 AUTHOR

Nathan Mueller <nmueller\@newton.cs.wisc.edu>

=cut
