#
# $Id: Undo.pm,v 4.7 2002/07/21 06:49:53 kono Exp $
#

package CardPlay::Undo;

use strict;

use vars qw($VERSION @ISA @EXPORT @EXPORT_OK
);

require Exporter;
require AutoLoader;

@ISA = qw(Exporter AutoLoader);

@EXPORT = qw( );

$VERSION = "0.2";

use Carp;

# class method

sub new {
    my ($types) = shift;
    my $self;

    %$self = @_;
    undo_init($self);
    bless $self;
}

sub undo_init {
    my $self = shift;
    $self->{'-undo'}=[];
    $self->{'-undo_index'}=0;
    $self;
}

sub undo_restart {
    my $self = shift;
    $self->{'-undo_index'}=0;
    $self;
}

# instance method

# undo buffer processing 

# log_commit(0)  commit
# log_commit(-1) point of no return, end of initialzation

sub log_move {
    my ($self) = shift;
    my ($undo) = @_;

    return if ($self->{'-undoing'}==1);
    return if ($undo==0);

    $self->{'-undo'}->[$self->{'-undo_index'}]=$undo;
    $#{$self->{'-undo'}} = $self->{'-undo_index'}++;

#    print STDERR "log_move: "; $undo->print();
}

sub log_commit {
    my ($self,$mode) = @_;

    return if ($self->{'-undoing'}==1);
    return if ($self->{'-undo'}->[$self->{'-undo_index'}-1]==$mode);

    $self->{'-undo'}->[$self->{'-undo_index'}]=$mode;
    $#{$self->{'-undo'}} = $self->{'-undo_index'}++;

# print STDERR "\nlog cdommit ",$self->{'-undo_index'},"\n";
# $self->log_print;

}

sub log_print {
    my ($self) = shift;
    my (@list) = @{$self->{'-undo'}};
    foreach my $undo ( @list ) {
    next if ($undo == 0 || $undo == -1);
    $undo->print();
    }
}

sub disable_undo {
}
sub enable_undo {
}

sub enable_log {
    my ($self) = shift;
    $self->{'-undoing'}=0;
}

sub disable_log {
    my ($self) = shift;
    $self->{'-undoing'}=1;
}

sub undo {
    my ($self) = shift;
    my ($undo);
    return if ($self->{'-undo_index'}==0);
    return if ($self->{'-undoing'}++>0);
    return if ($self->{'-undoing'}!=1);
    $self->disable_undo;
    while ( $self->{'-undo_index'} > 0 ) {
    $undo = $self->{'-undo'}->[$self->{'-undo_index'}-1];
    last if ($undo==-1);
    last if ($undo!=0);
    $self->{'-undo_index'} --;
    }
    while ( $self->{'-undo_index'} > 0 ) {
    $undo = $self->{'-undo'}->[$self->{'-undo_index'}-1];
    last if ($undo== -1);
    $self->{'-undo_index'} --;
    last if ($undo==0);
    $undo->undo();
    }
    $self->{'-undoing'}=0;
    $self->enable_undo;
}

sub redo {
    my ($self) = shift;
    my ($undo);
    return if ($self->{'-undo_index'}==$#{$self->{'-undo'}});
    return if ($self->{'-undoing'}++>0);
    return if ($self->{'-undoing'}!=1);
    $self->disable_undo;
    while ( $self->{'-undo_index'} <= $#{$self->{'-undo'}} ) {
    $undo = $self->{'-undo'}->[$self->{'-undo_index'}];
    next if ($undo==-1);
    last if ($undo!=0);
    $self->{'-undo_index'} ++;
    }
    while ( $self->{'-undo_index'} <= $#{$self->{'-undo'}} ) {
    $self->{'-undo_index'} ++;
# print STDERR "Redoing ",$self->{'-undo_index'},"\n";
    $undo = $self->{'-undo'}->[$self->{'-undo_index'}-1];
    last if ($undo==0);
    next if ($undo==-1);
    $undo->redo();
    }
    $self->{'-undoing'}=0;
    $self->enable_undo;
}

1;
# end