#! /usr/bin/perl -w
# smallstate <file> [3]

#  reads <file> which is triples where the second member is a state
#  integer (paired values).  For N distinct integers in the file,
#  make a sorted table of the N values, and rewrite as <file>.norm with
#  the table index replacing the value in the second place.  
#  If the optional [3] is present, treat the second and third members
#  of the triple.
#
#  Also make a gnuplot command file to print the decomposed pair values
#  as y-axis labels.  Do this for both y- and z-axes if [3].

#  Presently only works for two-state pairs
#  <file>.norm is sorted on the second field, separated into grids at
#   the distinct points, with the points in each grid sorted on the
#   first field.

$file = $ARGV[0];
die "Can't find the plot file",$file unless (-e $file);
$outfile = $file.".norm";
system "sort -n $file > $outfile"; #on first, input, field
$statestate = 0; #assume that it is not a state-value file
if (defined($ARGV[1])) {
  $statestate = 1;
  system "sort -n +2 +0 $outfile >$file.sort"; #on out state, third, field, now tidy
  $com ="gawk '{print \$2;print\$3}' $file |sort -u -n";
} else {
  system "sort -n +1 +0 $outfile >$file.sort"; #on state, second, field, now tidy
}
$file = $file.".sort";
$com ="gawk '{print \$2}' $file |sort -u -n";

$baz = `$com`;
@StateList = split("\n",$baz);
print "The list of paired state values is:\n";
foreach $i(@StateList) {print "$i ";} print "\n";
print "continue? [Enter or ^C]";
$stopflag = <STDIN>; 

$stopflag = 0;
if ($statestate) { #do outputs first
  $which = 2;
} else { #just do input states
  $which = 1;
}
AGAIN:
open(PF,"<$file");
open(PFF,">$outfile") or die "Can't create output file";
$whichState = 0;
W: while ($line = <PF>) {
  if ($line eq "\n") { #ignore blank lines
    next W;
  }
  @triple = split(" ",$line);
  if ($whichState == 0 || $curState != $triple[$which]) { #first or new state value
    if ($whichState == 0) {
      $whichState = 1;
    } else {
      if ($which == 1) { #doing input states
        print PFF "\n"; #for grid spacing
      }
    }
    $curState = $triple[$which];
    L:for ($i=0;$i<=$#StateList;$i++) {
      last L if ($StateList[$i] == $curState);
    }
  } 
  $triple[$which] = $i;
  print PFF "$triple[0] $triple[1] $triple[2]\n";
}
close(PF);
close(PFF);

if (!$stopflag && $statestate) { #state file, also substitute for outputs
  system "sort -n +1 +0 $outfile > $file.sort";
  $file = $file.".sort";
  $stopflag = 1;
  $which = 1;
  goto AGAIN;
}

open(PLT,">complot");
print PLT "set ytics (";
for ($j=0;$j<=$#StateList;$j++) {
  #debug
  #print "$j\n";
  $com = "unpair $StateList[$j]";
  @sts = split(" ",`$com`);
  print PLT "\"($sts[0],$sts[1])\" $j";
  if ($j<$#StateList) { #not the last
    print PLT ",";
  } else { #last
    print PLT ")\n";
  }
  #if ($statestate) {
    #print PLT "set ztics (\"($sts[0],$sts[1])\" $j)\n";
  #}
}
close(PLT);
