# $Id: Line.pm 6839 2000-05-05 21:32:07Z rousskov $

package ReportGen::Line;
use strict;

#
# Wrapper for gnuplot-like plot "lines"
#

# order must match what plotter expects
my @DataOpts = qw( index every thru using smooth );
my @KnownOptions = ( @DataOpts, qw(axes title with) );

sub new {
	my ($proto) = @_;
	my $type = ref($proto) || $proto;
	my $this = bless({}, $type);

	$this -> {theData} = '';
	$this -> {theOpt} = {};
	$this -> {theLineCount} = undef; # cache

	return $this;
}

sub clone {
	my ($this) = @_;
	my $clone = bless({}, ref($this));

	$clone -> {theData} = $this -> {theData};
	$clone -> {theOpt} = { 
		map { $_ => $this -> {theOpt} -> {$_} } 
		keys %{$this -> {theOpt}}
	};
	$clone -> {theLineCount} = $this -> {theLineCount};

	return $clone;
}

sub data {
	my ($this, $d) = @_;

	$this -> {theData} = $d;
	$this -> {theLineCount} = undef;
}

sub image {
	my ($this) = @_;

	my $image = '';

	my $data = $this -> {theData} || '';
	if ($data =~ /^\S*\(/) { # a function
		$image .= $data;
	} else {
		$image .= "\"$data\"";
	}
	$image .= ' ';

	foreach (@KnownOptions) {
		my $opt = $this->{theOpt}->{$_};
		$image .= " $_ $opt" if $opt;
		$image .= " no$_" if defined $opt && $opt eq '';
	}
	
	return $image;
}

sub using {
	my ($this, @fields) = @_;

	$this->{theOpt}->{'using'} = join(':', map { "($_)" } @fields);
}

sub title {
	my ($this, $title) = @_;
	$this->{theOpt}->{'title'} = sprintf('"%s"', $title) if defined $title;
}

# pipes already set data through a given filter
# %y in the filter string is replaced with y-column number from 'using'
sub filter {
	my ($this, $filter) = @_;

	my $y = $this->ycolumn();
	$filter =~ s/\%y/$y/g;

	if ($this->{theData} =~ /^</) { # already a pipe
		$this->data($this->{theData} . "| $filter");
	} else {
		$this->data("<$filter < " . $this->{theData});
	}
}

sub ycolumn {
	my $this = shift;

	my $opt = $this->{theOpt}->{'using'};
	die("line->ycolumn called for a line with no 'using' option") unless $opt;
	my @columns = split /:/, $opt;
	die("cannot parse  'using' option in '$opt'") unless @columns;

	my $res = defined $columns[1] ? $columns[1] : $columns[0];
	$res =~ s/^\(|\)$//g;
	die("y-column specs are too complex in $res\n") unless $res =~ /^\d+$/;
	return $res;
}

sub lineCount {
	my $this = shift;

	my $cmd = $this->{theData};
	die("lineCount called for the line with no data!") unless $cmd;

	my ($lc) = ($cmd =~ s/^<//) ?
		(`$cmd | wc -l` =~ /\b(\d+)\b/) : (`wc -l $cmd` =~ /\b(\d+)\b/);
	die("failed to count lines in $cmd") unless $lc;
	$this->{theLineCount} = $lc;
	return $lc;
}

use vars qw($AUTOLOAD);

sub AUTOLOAD {
	my $this = shift;
	my $A = $AUTOLOAD;
	$A =~ s/ReportGen::Line:://;
	return undef if $A eq 'DESTROY';

	my $opt = lc $A;
	die("unknown line option '$A', stopped") unless grep { /^$opt$/ } @KnownOptions;
	# die("no args for line option '$A', stopped") unless @_;

	$this -> {theOpt} -> {$opt} = @_ ? join(' ', @_) : undef();
}

1;


syntax highlighted by Code2HTML, v. 0.9.1