$Tk::MARC::Field::VERSION = '0.11';

package Tk::MARC::Field;

=head1 NAME

Tk::MARC::Field - megawidget for editing MARC::Field objects.

=head1 SYNOPSIS

 use Tk;
 use Tk::MARC::Field;
 use MARC::Field

 my $mw = MainWindow->new;
 my $field = MARC::Field->new('245','','',
                              'a' => 'The Case for Mars: ',
                              'b' => 'The plan to settle the red
 planet, and why we must.'
                             );
 $mw->MARC_Field(-field => $field
                )->pack(-anchor => 'w');

 MainLoop;

=head1 DESCRIPTION

This is a megawidget that allows editing of a MARC::Field object.
The widget itself does not change the MARC::Field - that is
up to the widget's parent.

The widget allows you to indicate your desire to delete/undelete
the field by clicking a button (which will change the color of
the tag).

It allows you to add new subfields by selecting from a list (you 
can indicate your desire to delete a subfield by clicking a 
button)... and it knows what subfields are valid for this field 
(by using MARC::Descriptions).

You will likely never use a Tk::MARC::Field directly - it is simply
a component of Tk::MARC::Editor.

=cut

# Revision history for Tk::MARC::field.
# -------------------------------------
# 0.11 January 20, 2004
#      - added check for missing -field
#      - added check for missing -subfields
#
# 0.10 January 17, 2004
#      - renamed to Tk::MARC::Field (capitalized 'Field') to better
#        match MARC::Field and avoid confusion (thanks Andy!)
#
# 0.9 January 16, 2004
#     - properly handle get() for fields < '010'
# 
# 0.8 January 15, 2004
#     - get() routine
# 
# 0.7 January 14, 2004
#     - first bit of POD
# 
# 0.6 January 14, 2004
#     - handle tags <= 010 (i.e. no subfields, just data)
# 
# 0.5 January 14, 2004
#     - proper _add_subfield routine
# 
# 0.4 January 14, 2004
#     - menu for adding subfields
# 
# 0.3 January 12, 2004
#     - built a couple of sample routines in pl/
#     - t/01-use.t
# 
# 0.2 January 09, 2004
#     - now uses the newly-written MARC::Descriptions module
#       (which is available on the CPAN)
# 
# 0.1 January 06, 2004
#     - original version
#

use Tk::widgets;
use base qw/Tk::Frame/;
use Tk::MARC::Subfield;
use Tk::MARC::Indicators;
use MARC::Descriptions;
use MARC::Field;
use Carp;
use strict;

Construct Tk::Widget 'MARC_Field';

our (
     $TD,
     );

sub ClassInit {
    my ($class, $mw) = @_;
    $TD = new MARC::Descriptions;
    $class->SUPER::ClassInit($mw);
}

sub Populate {
    my ($self, $args) = @_;

    my $field = delete $args->{'-field'};
    my $tag = delete $args->{'-tag'};
    my $ind1 = delete $args->{'-ind1'};
    my $ind2 = delete $args->{'-ind2'};
    my $subfields = delete $args->{'-subfields'};
    if (defined $field) {
	croak "Not a MARC::Field" unless (ref($field) eq 'MARC::Field');
	$self->{MARCField} = $field;
    } else {
	croak "Missing -tag" unless (defined $tag);
	croak "Missing -subfields" unless (defined $subfields);
	$self->{MARCField} = MARC::Field->new( $tag,
					       $ind1,
					       $ind2,
					       @$subfields
					       );
    }

    $self->SUPER::Populate($args);
    $self->{"fixed_font"} = "-adobe-courier-medium-r-normal--14-100-75-75-m-60-iso8859-2";

    my $FRAME = $self->Frame(-relief => 'ridge',
			     -borderwidth => 1,
			     )->pack(-side => 'top',
				     -expand => 1,
				     -fill => 'both');
    my $FRAME_LABEL = $FRAME->Frame(-relief => 'raised',
				   -borderwidth => 1,
				   )->pack(-side => 'left',
					   -expand => 0,
					   -fill => 'y');
    my $FRAME_TAG = $FRAME_LABEL->Frame()->pack(-side => 'top',
						-expand => 0,
						-fill => 'x');
    my $FRAME_IND = $FRAME_LABEL->Frame()->pack(-side => 'top',
						-expand => 1,
						-fill => 'both');
    
#    my $FRAME_EDIT = $self->Frame()->pack(-side => 'left',
#					  -expand => 1,
#					  -fill => 'both');
    my $FRAME_EDIT = $FRAME->Frame()->pack(-side => 'left',
					   -expand => 1,
					   -fill => 'both');
    my $FRAME_DESC = $FRAME_EDIT->Frame()->pack(-side => 'top',
						-expand => 1,
						-fill => 'x');
    my $FRAME_SUBS = $FRAME_EDIT->Frame()->pack(-side => 'top',
						-expand => 1,
						-fill => 'both');
    
    my $LABEL = $FRAME_TAG->Label(-text => $self->{'MARCField'}->tag(),
				  -anchor => 'nw',
				  -justify => 'left',
				  )->pack(-side => 'left',
					  -expand => 0,
					  -fill => 'both');
    my $DEFAULT_TAG_COLOR = $LABEL->cget(-background);
    $self->{DELETED} = "no";
    my $B_DELETE = $FRAME_TAG->Button(-text => "X",
				      -font => $self->{"fixed_font"},
				      -width => 1,
				      -height => 1,
				      -padx => 0,
				      -pady => 0,
				      -command => sub {
					  $self->{DELETED} = "yes";
					  $LABEL->configure(-background => "red");
				      }
				      )->pack(-side => 'right');
    my $B_UNDELETE = $FRAME_TAG->Button(-text => "O",
					-font => $self->{"fixed_font"},
					-width => 1,
					-height => 1,
					-padx => 0,
					-pady => 0,
					-command => sub {
					    $self->{DELETED} = "no";
					    $LABEL->configure(-background => $DEFAULT_TAG_COLOR);
					}
					)->pack(-side => 'right');
    my $s;
    $s = $TD->get($self->{'MARCField'}->tag(), "description");
    $s = "No description from MARC::Descriptions" unless defined $s;
    my $DESCRIPTION = $FRAME_DESC->Label(-text => $s,
					 -width => 42,
					 -anchor => 'nw',
					 -justify => 'left',
					 )->pack(-side => 'left',
						 -expand => 0,
						 -fill => 'x');


    if ($self->{MARCField}->tag() ge '010') {
	#
	# Menu for adding subfields
	#
	my @menu_subfields;
	my $ref_menu_subfields;
	@menu_subfields = ();
	my $href = $TD->get($self->{'MARCField'}->tag(), "subfields");
	foreach my $subfield (sort keys %$href) {
	    push @menu_subfields,['command' => "[" . $subfield . "] " . $href->{$subfield}{description},
				  -command => sub { 
				      $self->_add_subfield($self->{MARCField}->tag(), $FRAME_SUBS, $subfield);
				      }
				  ];
	}
	my $B_NEWSUBFLD = $FRAME_DESC->Menubutton(-text => "New subfield",
						  -font => $self->{"fixed_font"},
						  -padx => 0,
						  -pady => 0,
						  -tearoff => 0,
						  -indicatoron => 1,
						  -menuitems => \@menu_subfields,
						  )->pack(-side => 'left');
	
	#
	# Subfields
	#
	my @subfields = $self->{MARCField}->subfields();
	$self->{subfields} = ();
	my $i = 0;
	foreach my $subfield (@subfields) {
	    $self->{subfields}[$i++] = $FRAME_SUBS->MARC_Subfield(-field => $self->{MARCField}->tag(),
								  -label => @$subfield[0],
								  -value => @$subfield[1]
								  )->pack(-anchor => 'w');
	}
    } else {
	#
	# Tag is <= 010
	#
	$self->{data} = $FRAME_SUBS->MARC_Subfield(-field => $self->{MARCField}->tag(),
						   -label => 'DATA',
						   -value => $self->{MARCField}->data()
						   )->pack(-anchor => 'w');
    }

    #
    # indicators
    #
    if ($self->{MARCField}->tag() ge '010') {
	$self->{indicators} = $FRAME_IND->MARC_Indicators(-field => $self->{MARCField}->tag(),
							  -ind1  => $self->{MARCField}->indicator(1),
							  -ind2  => $self->{MARCField}->indicator(2),
							  )->pack(-anchor => 'w');
    }

    $self->ConfigSpecs( '-field' => [ 'PASSIVE', , , undef],
			'-tag'   => [ 'PASSIVE', , , undef],
			'-ind1'  => [ 'PASSIVE', , , undef],
			'-ind2'  => [ 'PASSIVE', , , undef],
			'-subfields' => [ 'PASSIVE', , , undef],
			);
}


sub _add_subfield {
    my $self = shift;
    my ($tag, $f, $subfield) = @_;
    push @{ $self->{subfields} }, $f->MARC_Subfield(-field => $tag,
						    -label => $subfield,
						    -value => "New subfield",
						    )->pack(-anchor => 'w');
}

sub get {
    my $self = shift;

    my $fld = undef;

    if ($self->{DELETED} eq "no") {
	if ($self->{MARCField}->tag() lt '010') {
	    $fld = MARC::Field->new($self->{MARCField}->tag(),
				    $self->{data}->get(),
				    );
	} else {
	    #
	    # Tag >= 010
	    #
	    my $sf = undef;
	    my $i = -1;
	    
	    # Find the first (non-deleted) subfield
	    while (($i < $#{ $self->{subfields} })
		   && (not defined $sf)
		   ) {
		$i++;
		$sf = $self->{subfields}[$i]->get();
	    }
	    
	    # Did we find a valid subfield before falling off the end?
	    if (defined $sf) {
		$fld = MARC::Field->new($self->{MARCField}->tag(),
					$self->{indicators}->get(1),
					$self->{indicators}->get(2),
					@$sf[0] => @$sf[1],
					);
		$i++;
		while ($i <= $#{ $self->{subfields} }) {
		    $sf = $self->{subfields}[$i++]->get();
		    if (defined $sf) {
			$fld->add_subfields( @$sf );
		    }
		}
	    } else {
		# all subfields were deleted, so no Field is possible.
	    }
	}
    }
    return $fld;
}

=head1 AUTHOR

David Christensen, <DChristensenSPAMLESS@westman.wave.ca>

=cut

=head1 COPYRIGHT AND LICENSE

Copyright 2004 by David Christensen

This library is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=cut

1;
