#=====================================================================#
#                                                                     #
# This is the 'Main_Window' class                                     #
#                                                                     #
#=====================================================================#
# $Id$

package Main_Window;
use strict;
use CSL::PlRPC_Krb5;
use CSL::DBs;
use CSL::Pg;

use DBI;
use Mail::Send;
use Device::SerialPort;

use CSL::Gnome2;
use Gnome2;
use Gtk2::GladeXML;

use Carp;

use Add_Window;
use Alert_Window;
use User_Window;
use Edit_Window;

my $dbh;
my $row = -1;
my %book_isbns;
my %cd_isbns;
my %laptop_isbns;
my %key_isbns;
my $csdb;
my $query;
my $port = Device::SerialPort->new($ENV{LIB_PORT} ||
                                    "/dev/ttyS0", 1);
$port->baudrate(9600) if $port;


our $GLADEPATH = '/s/lab/common/lib/library5';
sub new
{
    my $this = shift;
    my $class = ref($this) || $this;

    my $self = { };
    bless $self, $class;

    $self->{xml} = Gtk2::GladeXML->new("$GLADEPATH/library.glade",
                                'main_window');
    croak "Error opening Glade file" if (!$self->{xml});

    $self->{xml}->signal_autoconnect_from_package($self);

    return $self;
}

sub run
{
    my ($class) = @_;

    Gnome2::Program->init("library", "5");
    my $self = $class->new;
    
    # Parse rc file
    if (-e "$ENV{HOME}/.library2.rc")
    {
        parse Gtk2::Rc "$ENV{HOME}/.library2.rc";
    }
    elsif (-e "/s/lab/common/lib/library2.rc")
    {
        parse Gtk2::Rc "/s/lab/common/lib/library2.rc";
    }

    # Connect to database
    $dbh = DBI->connect($CSL::DBs::csdb);
    $dbh->do("set search_path to library");

    # Check if user a librarian
    my $query = $dbh->prepare("select * from librarians where username = ?");
    $query->execute((getpwuid($<))[0]);
    unless($query->fetchrow)
    {
        $self->wgt('edit_button')->hide;
        $self->wgt('add_button')->hide;
        $self->wgt('remove_button')->hide;
        $self->wgt('admonish_button')->hide;
        $self->wgt('unadmonish_button')->hide;
    }

    if ($port)
    {
        $self->{csdb} = DBI->connect($CSL::DBs::easy_proxy);
        Glib::Timeout->add(500, \&do_scan, $self);
    }


    # Initialize the lists
    # Create the models
    $self->{book_store} = Gtk2::TreeStore->new('Glib::String', 'Glib::String',
                                               'Glib::String', 'Glib::String',
                                               'Glib::String', 'Glib::String');
    $self->{cd_store} = Gtk2::TreeStore->new('Glib::String', 'Glib::String',
                                             'Glib::String', 'Glib::String',
                                             'Glib::String', 'Glib::String');
    $self->{laptop_store} = Gtk2::TreeStore->new('Glib::String', 'Glib::String',
                                               'Glib::String', 'Glib::String',
                                               'Glib::String', 'Glib::String');
    $self->{key_store} = Gtk2::TreeStore->new('Glib::String', 'Glib::String',
                                               'Glib::String', 'Glib::String',
                                               'Glib::String', 'Glib::String');
    
    my ($book_list, $cd_list, $laptop_list, $key_list);

    $book_list = $self->wgt('book_list');
    $cd_list = $self->wgt('cd_list');
    $laptop_list = $self->wgt('laptop_list');
    $key_list = $self->wgt('key_list');

    # Associate the models with the views
    $book_list->set_model($self->{book_store});
    $cd_list->set_model($self->{cd_store});
    $laptop_list->set_model($self->{laptop_store});
    $key_list->set_model($self->{key_store});

    $book_list->get_selection()->set_mode('single');
    $cd_list->get_selection()->set_mode('single');
    $laptop_list->get_selection()->set_mode('single');
    $key_list->get_selection()->set_mode('single');

    # Set up columns
    my @columns = qw/ISBN Title Author Status User Due/;

    foreach my $l ($book_list, $cd_list, $laptop_list, $key_list)
    {
        for(my $i = 0; $i <= $#columns; $i++)
        {
            $l->insert_column_with_attributes(-1, $columns[$i],
                                               Gtk2::CellRendererText->new(),
                                               "text", $i);
            $l->get_column($i)->set_resizable(1);
            $l->get_column($i)->signal_connect(clicked => \&on_list_column_clicked, [$self, $i]);
        }

        $l->get_column(1)->set_expand(1);
        $l->get_column(1)->set_sizing('fixed');
        $l->get_column(1)->set_fixed_width(390);
        $l->get_column(2)->set_sizing('fixed');
        $l->get_column(2)->set_fixed_width(160);
        $l->set_rules_hint(1);
        $l->set_headers_clickable(1);
        $l->set_reorderable(0);
    }

    $self->{sort} = "isbn";

    # Fill in data
    $self->getbooks();
    $self->getcds();
    $self->getlaptops();
    $self->getkeys();

    # Set "Search By" value to default
    $self->wgt('category_combo')->set_active(0);

    $self->wgt('main_window')->show;

    Gtk2->main;
};

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

    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 $self->{sort}");

    $query->execute;
    my $result = $query->fetchall_arrayref;
    $query->finish();
    
    my $book_store = $self->{book_store};

    $book_store->clear();

    my $i = 0;
    my $iter;
    foreach my $book (@$result)
    {
	my $isbn = shift @$book;
	my $copy = shift @$book;
	$isbn = $isbn . "C" . $copy if ($copy);
	@$book = ($isbn, @$book);
	$book_isbns{$isbn} = $i++;
	my $recall = pop @$book;
	$recall += 3600 * 48;
	my @time = localtime($recall);
	if ($time[6] == 0 || $time[6] == 6)
	{
	    $recall += 3600 * 48;
	}
	$book->[3] = "Recalled" if $recall > time;
	
        $iter = $book_store->append(undef);
        $book_store->set($iter,
                          0, $book->[0],
                          1, $book->[1],
                          2, $book->[2],
                          3, $book->[3],
                          4, $book->[4],
                          5, $book->[5]);
    }
   
}

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

    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 $self->{sort}");
    $query->execute;
    my $result = $query->fetchall_arrayref;
    $query->finish();

    my $cd_store = $self->{cd_store};

    $cd_store->clear();

    my $i = 0;
    my $iter;
    foreach my $cd (@$result)
    {
	my $isbn = shift @$cd;
	my $copy = shift @$cd;
	$isbn = $isbn . "C" . $copy if ($copy);
	@$cd = ($isbn, @$cd);
	$cd_isbns{$isbn} = $i++;
	my $recall = pop @$cd;
	$recall += 3600 * 48;
	my @time = localtime($recall);
	if ($time[6] == 0 || $time[6] == 6)
	{
	    $recall += 3600 * 48;
	}
	$cd->[3] = "Recalled" if $recall > time;
	
        $iter = $cd_store->append(undef);
        $cd_store->set($iter,
                        0, $cd->[0],
                        1, $cd->[1],
                        2, $cd->[2],
                        3, $cd->[3],
                        4, $cd->[4],
                        5, $cd->[5]);
    }
}

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

    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 $self->{sort}");
    $query->execute;
    my $result = $query->fetchall_arrayref;
    $query->finish();

    my $laptop_store = $self->{laptop_store};

    $laptop_store->clear();

    my $i = 0;
    my $iter;
    foreach my $laptop (@$result)
    {
	my $isbn = shift @$laptop;
	my $copy = shift @$laptop;
	$isbn = $isbn . "C" . $copy if ($copy);
	@$laptop = ($isbn, @$laptop);
	$laptop_isbns{$isbn} = $i++;
	my $recall = pop @$laptop;
	$recall += 3600 * 48;
	my @time = localtime($recall);
	if ($time[6] == 0 || $time[6] == 6)
	{
	    $recall += 3600 * 48;
	}
	$laptop->[3] = "Recalled" if $recall > time;
	
        $iter = $laptop_store->append(undef);
        $laptop_store->set($iter,
                        0, $laptop->[0],
                        1, $laptop->[1],
                        2, $laptop->[2],
                        3, $laptop->[3],
                        4, $laptop->[4],
                        5, $laptop->[5]);
    }
}

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

    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 = 'key' ORDER BY $self->{sort}");
    $query->execute;
    my $result = $query->fetchall_arrayref;
    $query->finish();

    my $key_store = $self->{key_store};

    $key_store->clear();

    my $i = 0;
    my $iter;
    foreach my $key (@$result)
    {
	my $isbn = shift @$key;
	my $copy = shift @$key;
	$isbn = $isbn . "C" . $copy if ($copy);
	@$key = ($isbn, @$key);
	$key_isbns{$isbn} = $i++;
	my $recall = pop @$key;
	$recall += 3600 * 48;
	my @time = localtime($recall);
	if ($time[6] == 0 || $time[6] == 6)
	{
	    $recall += 3600 * 48;
	}
	$key->[3] = "Recalled" if $recall > time;
	
        $iter = $key_store->append(undef);
        $key_store->set($iter,
                        0, $key->[0],
                        1, $key->[1],
                        2, $key->[2],
                        3, $key->[3],
                        4, $key->[4],
                        5, $key->[5]);
    }
}

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 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 += 3600 * 48; # 2 days
    my @time = localtime($returned);
    if ($time[6] == 0 || $time[6] == 6)
    {
        $returned += 3600 * 48; # 2 more days if on a weekend
    }

    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 get_selected_row
{
    my ($self) = @_;

    my $page_index = $self->wgt('notebook1')->get_current_page();
    my $selection;
    if ($page_index == 0) {
        $selection = $self->wgt('book_list')->get_selection();
    } elsif($page_index == 1) {
        $selection = $self->wgt('cd_list')->get_selection();
    } elsif($page_index == 2) {
        $selection = $self->wgt('laptop_list')->get_selection();
    } elsif($page_index == 3) {
        $selection = $self->wgt('key_list')->get_selection();
    }

    my ($model, $iter) = $selection->get_selected();

    if (!$model) { return; }
    my @values = $model->get($iter);

    return @values;
}

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

    my $page_index = $self->wgt('notebook1')->get_current_page();
    my $selection;
    if ($page_index == 0) {
        $selection = $self->wgt('book_list')->get_selection();
    } elsif($page_index == 1) {
        $selection = $self->wgt('cd_list')->get_selection();
    } elsif($page_index == 2) {
        $selection = $self->wgt('laptop_list')->get_selection();
    } elsif($page_index == 3) {
        $selection = $self->wgt('key_list')->get_selection();
    }

    $selection->unselect_all();
}

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

    my @values = $self->get_selected_row();

    return $values[0] if @values;
    return;
}

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

    my $isbn = $self->get_selected_isbn();
    if (!defined($isbn))
    {
        Alert_Window->run("Please select a row.");
        return;
    }

    User_Window->run("out", $isbn, "Checkout to:", $self);
}

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

    my $isbn = $self->get_selected_isbn();
    if (!defined($isbn))
    {
        Alert_Window->run("Please select a row.");
        return;
    }

    User_Window->run("lab", $isbn, "Reserve for:", $self);
}

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

    my $isbn = $self->get_selected_isbn();
    if (!defined($isbn))
    {
        Alert_Window->run("Please select a row.");
        return;
    }

    User_Window->run("recall", $isbn, "Recall for:", $self);
}

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

    my $isbn = $self->get_selected_isbn();
    if (!defined($isbn))
    {
        Alert_Window->run("Please select a row.");
        return;
    }

    $isbn =~ 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); # TODO Complain

    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)
    {
	Alert_Window->run($user . " has too many overdue books: $books");
	$dbh->disconnect();
	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($self->get_selected_isbn(), $user))
    {
	Alert_Window->run("That book has been recalled");
	return;
    }

    if (my $message = &admonished($user))
    {
	Alert_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, $self->get_selected_isbn());
    $query->bind_param(3, $me);
    $query->bind_param(4, $isbn);
    $query->bind_param(5, $copy);
    $query->execute();
    $query->finish();

    $self->unselect_all();

    $self->getbooks();
    $self->getcds();
    $self->getlaptops();
    $self->getkeys();


}

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

    my @row = $self->get_selected_row();
    if (!@row) 
    {
        Alert_Window->run("Please select a row.");
        return;
    }
    my $isbn = $row[0];
    my $title = $row[1];
    
    if (my $user = &recalled($isbn))
    {
	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 -- \"$title\" -- 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, $isbn);
	$query->execute();
	$query->finish();
    }

    $isbn =~ 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, $self->get_selected_isbn());
    $query->bind_param(4, $me);
    $query->execute();
    $query->finish();

    $self->unselect_all();

    $self->getbooks;
    $self->getcds;
    $self->getlaptops;
    $self->getkeys;
}

sub on_add_button_clicked
{
    Add_Window->run($_[0]);
}

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

    my $isbn = $self->get_selected_isbn();
    if (!defined($isbn))
    {
        Alert_Window->run("Please select a row.");
        return;
    }

    $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();
    
    $self->unselect_all();

    $self->getbooks();
    $self->getcds();
    $self->getlaptops();
    $self->getkeys();
}

sub on_edit_button_clicked
{
    my ($self) = @_;
    my $title;
    my $author;
    my $category;
       
    my $isbn = $self->get_selected_isbn();
    if (!defined($isbn))
    {
        Alert_Window->run("Please select a row.");
        return;
    }
  
    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 ) 
    {

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


    Edit_Window->run($isbn, $title, $author, $category, $copy, $self);
}

sub on_admonish_button_clicked
{
    my $self = shift;
    User_Window->run("admonish", "", "Admonish:", $self);
}

sub on_unadmonish_button_clicked
{
    my $self = shift;
    User_Window->run("unadmonish", "", "Unadmonish:", $self);
}

sub do_scan
{
    my ($self) = @_;
    
    chomp(my $result = $port->input());

    my $page_index = $self->wgt('notebook1')->get_current_page();
    my $view;
    my $isbns;
    if($page_index == 0) {
	$view = $self->wgt('book_list');
        $isbns = \%book_isbns;
    }
    elsif($page_index == 1) {
	$view = $self->wgt('cd_list');
        $isbns = \%cd_isbns;
    }
    elsif($page_index == 2) {
	$view = $self->wgt('laptop_list');
        $isbns = \%laptop_isbns;
    }
    elsif($page_index == 3) {
	$view = $self->wgt('key_list');
        $isbns = \%key_isbns;
    }

    if ($result)
    {
	# Go to the right row
	if ($isbns->{$result})
	{
            my $selection = $view->get_selection();
            my $store = $view->get_model();
            my $path = Gtk2::TreePath->new_from_indices($isbns->{$result});
            if (defined($path))
            {
                $selection->select_path($path);
                $view->scroll_to_cell($path, undef);
            }
	}
	
	# Set the add window stuff
	$Add_Window::ADD = $result;
	
	# Get the login from ID
	chop($result);
	my $query = $self->{csdb}->prepare("person");
	$query->execute($result);
	($User_Window::USER) = $query->fetchrow();
    }

    1;
}

sub on_list_column_clicked
{
    my $data = $_[1];
    my ($self, $column_index) = @$data;

    my $sort;
    if    ($column_index == 0) { $sort = 'isbn';    }
    elsif ($column_index == 1) { $sort = 'title';   }
    elsif ($column_index == 2) { $sort = 'author';  }
    elsif ($column_index == 3) { $sort = 'status';  }
    elsif ($column_index == 4) { $sort = 'usr';     }
    elsif ($column_index == 5) { $sort = 'due';     }

    $self->do_sort($sort);
}

sub do_sort
{
    my ($self, $sort) = @_;

    $self->{sort} = $sort;

    $self->getbooks();
    $self->getcds();
    $self->getlaptops();
    $self->getkeys();
}

sub do_search
{
    my ($self) = @_;
    
    my $active = $self->wgt('category_combo')->get_active();
    my $searchby;
    my $terms = $self->wgt('search_query')->get_text();
    my $category;

    my $page_index = $self->wgt('notebook1')->get_current_page();
    if    ($page_index == 0) { $category = 'book'; }
    elsif ($page_index == 1) { $category = 'cd'; }
    elsif ($page_index == 2) { $category = 'laptop'; }
    elsif ($page_index == 3) { $category = 'key'; }

    if    ($active == 0) { $searchby = 'title';  }
    elsif ($active == 1) { $searchby = 'isbn';   }
    elsif ($active == 2) { $searchby = 'author'; }
    elsif ($active == 3) { $searchby = 'usr';    }

    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.$searchby iLIKE '%$terms%' AND books.cat = ?" . 
			      "ORDER BY $self->{sort}");
    $query->execute($category);
    my $result = $query->fetchall_arrayref;
    $query->finish();
    
    my $store;
    my $isbns;

    if    ($category eq 'book')   { $store = $self->{book_store}; $isbns=\%book_isbns;      }
    elsif ($category eq 'cd')     { $store = $self->{cd_store}; $isbns=\%cd_isbns;          }
    elsif ($category eq 'laptop') { $store = $self->{laptop_store}; $isbns=\%laptop_isbns;  }
    elsif ($category eq 'key') { $store = $self->{key_store}; $isbns=\%key_isbns;  }

    $store->clear();

    my $i = 0;
    my $iter;
    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;
	
	$iter = $store->append(undef);
        $store->set($iter,
                    0, $book->[0],
                    1, $book->[1],
                    2, $book->[2],
                    3, $book->[3],
                    4, $book->[4],
                    5, $book->[5]);
    }
}

sub on_search_query_changed
{
    my ($self) = @_;
    
    $self->do_search();
}

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

    $self->do_search();
}

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

    $self->do_search();
}

sub on_show_all_button_clicked
{
    my ($self) = @_;
    
    $self->getbooks();
    $self->getcds();
    $self->getlaptops();
    $self->getkeys();
}

sub on_destroy
{
    &quit;
}

sub quit
{
    # Close port if open

    $port->close if $port;

    exit;
}
    
sub wgt
{
    my ($self, $widget) = @_;

    return $self->{xml}->get_widget($widget);
}

1;
