#!/usr/bin/perl
# The Missing Textutils, Ondrej Bojar, obo@cuni.cz
# http://www.cuni.cz/~obo/textutils
#
# 'linemax' processes all lines from stdin and calculates an agregate function
# on all the columns.
#
# $Id: linemax,v 1.3 2006/01/05 14:57:57 bojar Exp $

use Getopt::Long;
use strict;
no strict "refs";
use warnings;
use Statistics::Descriptive;

my $agr = "nondecreasing";
my $skip = 0;
my $skipcols = 0;
my $prepend = 0;
my $append = 0;
GetOptions(
  "agr=s" => \$agr,
  "skip=i" => \$skip,
  "skipcols=i" => \$skipcols,
  "prepend" => \$prepend,
  "append" => \$append,
);

my %mine = map {($_,1)} qw(nondecreasing avg);


sub nondecreasing {
  my @line = @{shift()};
  my $maxsofar = 0;
  for(my $i = 0; $i <= $#line; $i++) {
    $line[$i] = $maxsofar if $line[$i]<$maxsofar;
    $maxsofar = $line[$i];
  }
  return join("\t", @line);
}


sub avg {
  my @line = @{shift()};
  my $maxsofar;
  for(my $i = 0; $i <= $#line; $i++) {
    $maxsofar = $line[$i] if !defined $maxsofar || $maxsofar < $line[$i];
  }
  return $maxsofar;
}


while(<>) {
  if ($skip > 0) {
    $skip--;
    print;
    next;
  }
  chomp;
  my @line = split /\t/;
  my $out = "";
  if ($mine{$agr}) {
    $out = &$agr([@line[$skipcols..$#line]]);
  } else {
    my $data = Statistics::Descriptive::Full->new();
    $data->add_data(@line[$skipcols..$#line]);
    $out = eval("\$data->$agr");
  }
  if ($skipcols > 0) {
    print join("\t", @line[0..$skipcols-1])."\t";
  }
  print join("\t", @line[$skipcols..$#line])."\t" if $append;
  print "$out";
  print "\t".join("\t", @line[$skipcols..$#line])."\t" if $prepend;
  print "\n";
}
