package XXV::OUTPUT::HTML::WAIT;

use strict;

use Tools;
use XXV::OUTPUT::HTML::PUSH;

=head1 NAME

XXV::OUTPUT::HTML::WAIT - A Processbar for XXV system

=head1 SYNOPSIS

    use XXV::OUTPUT::HTML::WAIT;

    my $waiter =  XXV::OUTPUT::HTML::WAIT->new(
        -cgi => $obj->{cgi},        # The CGI Object from Lincoln Stein
        -handle => $obj->{handle},  # The handle to printout the http Stuff
        -callback => sub{           # Callback for html output.
                                    # In this case parse the html template wait.tmpl
            my ($min, $max, $cur, $steps) = @_;
            my $out = $obj->parseTemplate(
                'wait',
                {
                    msg     => $msg,
                    minimum => $min,
                    current => $cur,
                    maximum => $max,
                    steps   => $steps
                },
            );
            return $out;
        },
    );

    $waiter->min(0);        # Min Value for process Bar
    $waiter->max(10);       # Max Value for process Bar
    $waiter->screen('yes'); # Every call of next will redraw the process bar

    while($c > 10) {
        $waiter->next($c++);  # Next Event with current value
    }
    $waiter->end;

=cut

# ------------------
sub new {
# ------------------
	my($class, %attr) = @_;
	my $self = {};
	bless($self, $class);

    $self->{handle} = $attr{'-handle'}
        || return error('No handle defined!');

    $self->{cgi} = $attr{'-cgi'}
        || return error('No CGI Object defined!');

    $self->{callback} = $attr{'-callback'}
        || return error('No Callback to print out!');

    $self->{steps} = $attr{'-steps'} || 10;

    $self->{pusher} =  XXV::OUTPUT::HTML::PUSH->new(
        -cgi => $self->{cgi},        # The CGI Object from Lincoln Stein
        -handle => $self->{handle},  # The handle to printout the http Stuff
    );

    $self->init();

	return $self;
}

# ------------------
sub init {
# ------------------
    my $obj = shift  || return error ('No Object!' );

    $obj->{STEP} = 0;
    $obj->{pusher}->start();
}

# ------------------
sub next {
# ------------------
    my $obj = shift  || return error ('No Object!' );
    my $cur = shift  || $obj->{MAX};
    my $end = shift  || 0;
    my $msg = shift  || 0;

    # Don't show really every step, even is screen defined,
    # avoid high traffic and long duration of waiter progress
    $obj->{LastRefreshTime} = 1 if($end);
    my $t = time;
    return
        if(!$obj->{SCREEN} && $obj->{LastRefreshTime} + 1 > $t);
    $obj->{LastRefreshTime} = $t;

    # 2.2 = 22 / 10
    my $step = $obj->{MAX} / $obj->{steps};
    $obj->{STEP} += $step;

    if ($end or $cur > $obj->{MAX}) {
        $obj->{pusher}->stop();
        my $out = $obj->{endcallback}($obj->{MIN}, $obj->{MAX}, $cur, $obj->{steps}, $msg)
            if(ref $obj->{endcallback} eq 'CODE');
    } else {
        my $out = $obj->{callback}($obj->{MIN}, $obj->{MAX}, $cur, $obj->{steps}, $msg);
        $obj->{pusher}->print($out);
    }
}

# ------------------
sub end {
# ------------------
    my $obj = shift  || return error ('No Object!' );
    my $msg = shift  || 0;

    return $obj->next(undef, 'end', $msg);
}


# ------------------
sub endcallback {
# ------------------
    my $obj = shift  || return error ('No Object!' );
    $obj->{endcallback} = shift || return $obj->{endcallback};
}

# ------------------
sub max {
# ------------------
    my $obj = shift  || return error ('No Object!' );
    $obj->{MAX} = shift || return $obj->{MAX};
}

# ------------------
sub min {
# ------------------
    my $obj = shift  || return error ('No Object!' );
    $obj->{MIN} = shift || return $obj->{MIN};
}

# ------------------
sub screen {
# ------------------
    my $obj = shift  || return error ('No Object!' );
    $obj->{SCREEN} = shift || return $obj->{SCREEN};
}


1;
