$APE::Tk::PlateCell::VERSION = '1.0';

package APE::Tk::PlateCell;


use base qw/Tk::Derived Tk::Button/;
use strict;
use warnings;
use Carp;

use constant TRUE  => 1;
use constant FALSE => 0;

Construct Tk::Widget 'PlateCell';

use constant NORMAL   => 1;
use constant INC_ONLY => 2;
use constant DEC_ONLY => 3;

my %selectStates = ( 'normal' => NORMAL,
		     'inc'    => INC_ONLY,
		     'dec'    => DEC_ONLY );

sub ClassInit {
    my ($class,$mw) = @_;
    $class->SUPER::ClassInit($mw);
    $mw->bind($class,'<Button-2>'=>\&_incSelection);
    $mw->bind($class,'<Button-1>'=>\&_configureSelection);
    $mw->bind($class,'<Button-3>'=>\&_decSelection);
}


sub Populate {
    my ($self,$args) = @_;
    $self->{_coord} = delete $args->{-coord} || $self->Tk::Error("ERROR: argument -coord is missing");
    $self->{_sb}    = delete $args->{-selectcolor} || 'red';
    $self->{_isSelected}  = FALSE;
    $self->{_selectCount} = 1;
    
    $self->ConfigSpecs(-selectstate => [qw/METHOD selectstate SelectState normal/],
		       -state       => [qw/SELF state State normal/]);

    $self->SUPER::Populate($args);
}


sub selectstate {
    my ($self,$state) = @_;
    croak "ERROR: uknown selectstate '$state' - use " . join(", ",keys %selectStates)
	unless exists($selectStates{$state});
    $self->{_selectState} = $selectStates{$state};
}

sub _configureSelection {
    my $self = shift;
    return if $self->cget(-state) eq 'disabled';
    if($self->isSelected) {
	if($self->{_selectCount} > 1) {
	    $self->clear;
	    return;
	}else{
	    return if $self->{_selectState} == INC_ONLY;
	    $self->configure(-bg=>$self->{_bg});
	    $self->{_isSelected} = FALSE;
	}
    }else{
	return if $self->{_selectState} == DEC_ONLY;
	$self->{_bg} = $self->cget(-bg);
	$self->configure(-bg=>$self->{_sb});
	$self->{_isSelected}  = TRUE;
    }
    $self->invoke;
}


sub _incSelection {
    my $self = shift;
    return if $self->cget(-state) eq 'disabled';
    return if $self->{_selectState} == DEC_ONLY;
    return unless $self->isSelected;
    $self->{_selectCount}++;
    $self->configure(-text=>"x".$self->{_selectCount});
    $self->invoke;
}


sub _decSelection {
    my $self = shift;
    return if $self->cget(-state) eq 'disabled';
    return if $self->{_selectState} == INC_ONLY;
    return unless $self->isSelected;
    return unless $self->{_selectCount} > 1;
    $self->{_selectCount}--;
    $self->configure(-text=>$self->{_selectCount} == 1 ? "" : "x".$self->{_selectCount});
    $self->invoke;
}


sub select {
    my $self = shift;
    $self->_configureSelection;
}


sub clear {
    my $self = shift;
    foreach(1..$self->getSelectionCount) {
	$self->_decSelection;
    }
    $self->_configureSelection;
}


sub getSelectionCount {
    my $self = shift;
    return $self->isSelected ? $self->{_selectCount} : 0;
}


sub isSelected {
    my $self = shift;
    return $self->{_isSelected} ? TRUE : FALSE;
}


sub getCoordArrayRef {
    my $self = shift;
    return $self->{_coord};
}


sub getCoordString {
    my $self = shift;
    return _getRowChr($self->{_coord}[0]) . $self->{_coord}[1];
}


sub _getRowChr {
    return chr((shift)+96);
}



1;
