#
# Copyright 1999, 2000, 2001 Patrik Stridvall
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#

package output;

use strict;

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

@ISA = qw(Exporter);
@EXPORT = qw();
@EXPORT_OK = qw($output);

use vars qw($output);

$output = '_output'->new;

package _output;

use strict;

my $stdout_isatty = -t STDOUT;
my $stderr_isatty = -t STDERR;

sub new($) {
    my $proto = shift;
    my $class = ref($proto) || $proto;
    my $self  = {};
    bless ($self, $class);

    my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
    my $progress = \${$self->{PROGRESS}};
    my $last_progress = \${$self->{LAST_PROGRESS}};
    my $last_time = \${$self->{LAST_TIME}};
    my $progress_count = \${$self->{PROGRESS_COUNT}};
    my $prefix = \${$self->{PREFIX}};
    my $prefix_callback = \${$self->{PREFIX_CALLBACK}};

    $$progress_enabled = 1;
    $$progress = "";
    $$last_progress = "";
    $$last_time = 0;
    $$progress_count = 0;
    $$prefix = undef;
    $$prefix_callback = undef;

    return $self;
}

sub DESTROY {
    my $self = shift;

    $self->hide_progress;
}

sub enable_progress($) {
    my $self = shift;
    my $progress_enabled = \${$self->{PROGRESS_ENABLED}};

    $$progress_enabled = 1;
}

sub disable_progress($) {
    my $self = shift;
    my $progress_enabled = \${$self->{PROGRESS_ENABLED}};

    $$progress_enabled = 0;
}

sub show_progress($) {
    my $self = shift;
    my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
    my $progress = ${$self->{PROGRESS}};
    my $last_progress = \${$self->{LAST_PROGRESS}};
    my $progress_count = \${$self->{PROGRESS_COUNT}};

    $$progress_count++;

    if($$progress_enabled) {
	if($$progress_count > 0 && $$progress && $stderr_isatty) {
            # If progress has more than $columns characters the xterm will
            # scroll to the next line and our ^H characters will fail to
            # erase it.
            my $columns=$ENV{COLUMNS} || 80;
            $progress = substr $progress,0,($columns-1);
	    print STDERR $progress;
	    $$last_progress = $progress;
	}
    }
}

sub hide_progress($)  {
    my $self = shift;
    my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
    my $progress = \${$self->{PROGRESS}};
    my $last_progress = \${$self->{LAST_PROGRESS}};
    my $progress_count = \${$self->{PROGRESS_COUNT}};

    $$progress_count--;

    if($$progress_enabled) {
	if($$last_progress && $stderr_isatty) {
	    my $message=" " x length($$last_progress);
	    print STDERR $message;
	    undef $$last_progress;
	}
    }
}

sub update_progress($) {
    my $self = shift;
    my $progress_enabled = \${$self->{PROGRESS_ENABLED}};
    my $progress = ${$self->{PROGRESS}};
    my $last_progress = \${$self->{LAST_PROGRESS}};

    if($$progress_enabled) {
        # If progress has more than $columns characters the xterm will
        # scroll to the next line and our ^H characters will fail to
        # erase it.
        my $columns=$ENV{COLUMNS} || 80;
        $progress = substr $progress,0,($columns-1);

	my $prefix = "";
	my $suffix = "";
	if($$last_progress) {
            $prefix = "" x length($$last_progress);

	    my $diff = length($$last_progress)-length($progress);
	    if($diff > 0) {
                $suffix = (" " x $diff) . ("" x $diff);
	    }
	}
	print STDERR $prefix, $progress, $suffix;
	$$last_progress = $progress;
    }
}

sub progress($$) {
    my $self = shift;
    my $progress = \${$self->{PROGRESS}};
    my $last_time = \${$self->{LAST_TIME}};

    my $new_progress = shift;
    if(defined($new_progress)) {
	if(!defined($$progress) || $new_progress ne $$progress) {
	    $$progress = $new_progress;

	    $self->update_progress;
	    $$last_time = 0;
	}
    } else {
	return $$progress;
    }
}

sub lazy_progress($$) {
    my $self = shift;
    my $progress = \${$self->{PROGRESS}};
    my $last_time = \${$self->{LAST_TIME}};

    $$progress = shift;

    my $time = time();
    if($time - $$last_time > 0) {
	$self->update_progress;
    	$$last_time = $time;
    }
}

sub prefix($$) {
    my $self = shift;
    my $prefix = \${$self->{PREFIX}};
    my $prefix_callback = \${$self->{PREFIX_CALLBACK}};

    my $new_prefix = shift;
    if(defined($new_prefix)) {
	if(!defined($$prefix) || $new_prefix ne $$prefix) {
	    $$prefix = $new_prefix;
	    $$prefix_callback = undef;
	}
    } else {
	return $$prefix;
    }
}

sub prefix_callback($) {
    my $self = shift;

    my $prefix = \${$self->{PREFIX}};
    my $prefix_callback = \${$self->{PREFIX_CALLBACK}};

    $$prefix = undef;
    $$prefix_callback = shift;
}

sub write($$) {
    my $self = shift;

    my $message = shift;

    my $prefix = \${$self->{PREFIX}};
    my $prefix_callback = \${$self->{PREFIX_CALLBACK}};

    $self->hide_progress if $stdout_isatty;
    if(defined($$prefix)) {
	print $$prefix . $message;
    } elsif(defined($$prefix_callback)) {
	print &{$$prefix_callback}() . $message;
    } else {
	print $message;
    }
    $self->show_progress if $stdout_isatty;
}

1;
