package Wellnitz::GNUplot;

use strict;
use Exporter;

our @ISA = qw(Exporter);
our @EXPORT = qw(
);

# use vars qw( $plot $ref %allrtt @values $noval $i $j);


sub new {
   my ($class, $args) = @_;
   my (%plot);
   my $self = {};
   bless ($self, $class);

   # Initialize plot reference
   $plot{max} = 0;
   $self->{PLOTREF} = \%plot;

   return $self;
}


##########################################################################
# Mathematical helper functions                                          #
##########################################################################

sub minmax {
  my ($var, $min, $max) = @_;

  $min = $var if (($min == -1) or ($var < $min));
  $max = $var if (($max == -1) or ($var > $max));
  return ($min, $max);
}

sub variance {
  my @vars = @_;
  my ($total, $count, $avg, $res);

  return 0 if ((scalar @vars) == 0);
  foreach (@vars) {
    $count++;
    $total += $_;
  }
  $avg = $total/$count;
  #printf "Number of values: %u\n", $count;
  #printf "Avg.   of values: %5.2f\n ", $avg;
  foreach (@vars) {
    $res += ($_ - $avg)**2;
  }
  #printf "Variance is %5.2f\n", $res/$total;
  return 0  if ($total == 0);
  return $res/$total;
}

sub stddev {
  my @vars = @_;

  return sqrt(variance(@vars));
}

sub avg {
  my @vars = @_;
  my ($sum);

  return 0 if ((scalar @vars) == 0);

  foreach (@vars) {
    $sum += $_;
  } 
  return $sum/(scalar @vars);
}

##########################################################################
# Functions to plot data with gnuplot                                    #
##########################################################################

sub prepare_plot {
  my ($self, $title, %vars) = @_;
  my (%plot, $DATAFILE, $no, $plotref);

  $plotref = $self->{PLOTREF};

  $no = ++$plotref->{max};
  $DATAFILE = "/tmp/statistik-data-".$no.".$$";
  $plotref->{$no}->{filename} = $DATAFILE;
  $plotref->{$no}->{style} = "lines";
  $plotref->{$no}->{title} = $title;

  open(DATA, ">$DATAFILE") or die "Cannot create file $DATAFILE.\n";
  foreach (sort keys %vars) {
     printf DATA "%.2f %.2f\n", $_, $vars{$_};
  }
  close DATA;
}

sub prepare_plot_points {
  my ($self, $title, %vars) = @_;
  my (%plot, $DATAFILE, $no, $plotref);

  $plotref = $self->{PLOTREF};
 
  $no = ++$plotref->{max};
  $DATAFILE = "/tmp/statistik-data-".$no.".$$";
  $plotref->{$no}->{filename} = $DATAFILE;
  $plotref->{$no}->{style} = "points";
  $plotref->{$no}->{title} = $title;

  open(DATA, ">$DATAFILE") or die "Cannot create file $DATAFILE.\n";
  foreach (sort keys %vars) {
     printf DATA "%.2f %.2f\n", $_, $vars{$_};
  }
  close DATA;
}

sub do_plot {
  my ($self, $resultfile, %args) = @_;
  my ($i);
  my $FILENAME = "/tmp/statistik-gnuplot.$$";
  my $plotref = $self->{PLOTREF};

  open(TMP, ">$FILENAME") or die "Cannot create file $FILENAME.\n";

  print TMP "set terminal postscript eps\n";
  print TMP "set output \"$resultfile.eps\"\n";
  printf TMP "set title \"%s\"\n", $args{title} if ($args{title});
  printf TMP "set xlabel \"%s\"\n", $args{xlabel} if ($args{xlabel});
  printf TMP "set ylabel \"%s\"\n", $args{ylabel} if ($args{ylabel});
  if ($args{ysize}) {
    printf TMP "plot %s %s ", $args{xsize}, $args{ysize};
  } elsif ($args{xsize}) {
    printf TMP "plot %s ", $args{xsize};
  } else {
    print TMP "plot ";
  }
  for($i=1; $i<=$plotref->{max}; $i++) {
    printf TMP '"%s"', $plotref->{$i}->{filename};
    printf TMP " with %s", $plotref->{$i}->{style} if (defined($plotref->{$i}->{style}));
    printf TMP ' title "%s"', $plotref->{$i}->{title} if (defined($plotref->{$i}->{title}));
    print TMP ", " if ($i < $plotref->{max});
  }
  print TMP "\n";
  close TMP;
  system(("/usr/bin/gnuplot", $FILENAME));

  for($i=1; $i<=$plotref->{max}; $i++) {
    unlink $plotref->{$i}->{filename};
  }

  unlink $FILENAME;
}


##########################################################################
# Functions to prepare data for plotting                                 #
##########################################################################

# Probability density function from @vars;
sub probdensity {
  my ($varref) = @_;
  my (%prob, @vars, $value);

  @vars = @$varref;

  #printf "Number: %u\n", scalar(@vars);
  foreach (@vars) {
    $value = int($_*10)/10;
    $value = "0".$value if ($value < 10 );
    $value = "0".$value if ($value < 100 );
    $prob{$value}++;
  }

  foreach (sort keys %prob) {
    $prob{$_} = $prob{$_}/scalar(@vars);
  }

  return %prob;
}

# Cummulative probability density function from @vars;
sub cumprobdensity {
  my ($varref) = @_;
  my (%prob, $sum, @vars, $value);

  @vars = @$varref;

  #printf "Number: %u\n", scalar(@vars);
  foreach (@vars) {
    $value = int($_*10)/10;
    $value = "0".$value if ($value < 10 );
    $value = "0".$value if ($value < 100 );
    $prob{$value}++;
  }

  foreach (sort keys %prob) {
    $prob{$_} = $prob{$_}/scalar(@vars);
  }

  $sum = 0;
  foreach (sort keys %prob) {
    $prob{$_} = $sum + $prob{$_};
    $sum = $prob{$_};
  }

  return %prob;
}

1;
