#!/usr/bin/perl -w

# This specific file is hereby placed in the public domain, or nearest
# equivalent in law, by me, Ian Jackson.  5th July 2009.

BEGIN { unshift @INC, qw(.) }

use IO::File;
use strict (qw(vars));

use Commods;

our ($debug)= 0;

$debug=1 if @ARGV;

parse_pctb_commodmap();

our %stallkinds= qw(A Apothecary
		    D Distilling
		    F Furnishing
		    I Ironworking
		    S Shipbuilding
		    T Tailor
		    W Weaving);

sub getline ($) {
    my ($w)= @_;
    $!=0; my $l= <STDIN>; die $! unless defined $l;
    die $! if STDIN->error;
    die unless chomp $l;
    print "GOT FOR $w LINE [$l]\n"
	if $debug;
    return $l;
}

sub getint ($) {
    my ($w)= @_;
    my $b;
    my $t= tell STDIN; $t>=0 or die $!;
    my $r= read STDIN,$b,2; die $! if STDIN->error;
    die unless $r==2;
    my $v= scalar unpack "v", $b;
    printf "GOT AT 0x%x INT FOR %s VALUE %d 0x%x\n", $t, $w, $v, $v
	if $debug;
    return $v;
}

sub inmap($\@$) {
    my ($what,$ary,$ix) = @_;
    my $got= $ary->[$ix];
    return $got if defined $got;
    die "$what $ix ?";
}
    

printf "# Version: \"%s\"\n", getline("version");
our $nstalls= getline("nstalls")+0;
our @stalls;

while (@stalls < $nstalls) {
    $_= getline("stall name ".(@stalls+1));
    if (s/\^([A-Z])$//) {
	my $kind= $1;
	my $sk= $stallkinds{$kind};
	die "kind $kind in $_ ?" unless defined $sk;
	$_ .= "'s $sk Stall";
    }
    push @stalls, $_;
}
unshift @stalls, undef;

$|=1;

sub chk_ascending ($$$) {
    my ($this,$lastref,$desc) = @_;
    printf "# WARNING - $desc $this < $$lastref\n"
	if defined($$lastref) and $this < $$lastref;
    $$lastref= $this;
}

foreach my $bs qw(Buy Sell) {
    my $alloffers_want= getint("Buy ncommods");
    my $alloffers_done=0;
    my $commodix_last;
    my $price_last;
    while ($alloffers_done < $alloffers_want)  {
	my $commodix= getint("Buy $alloffers_done/$alloffers_want commodix");
	$price_last=undef unless
	    defined($commodix_last) && $commodix == $commodix_last;
	my $offers= getint("Buy $commodix offers");
	my $offernum;
	for ($offernum=0; $offernum<$offers; $offernum++) {
	    my $stallix= getint("Buy $commodix $offernum stallix");
	    my $price= getint("Buy $commodix $offernum price");
	    my $qty= getint("Buy $commodix $offernum qty");
	    printf("%s\t%s\t%s",
		   $bs,
		   inmap('commod',@pctb_commodmap,$commodix),
		   inmap('stall',@stalls,$stallix)) or die $!;
	    my $chk_asc_price_neg;
	    my $pricesort;
	    if ($bs eq 'Sell') { $pricesort=1; print "\t\t" or die $!; }
	    printf("\t%d\t%d", $price, $qty) or die $!;
	    if ($bs eq 'Buy') { $pricesort=-1; print "\t\t" or die $!; }
	    print "\n" or die $!;
	    chk_ascending($commodix,\$commodix_last,'commodix');
	    chk_ascending($pricesort*$price,\$price_last,'price');
	    $alloffers_done++;
	    die if $alloffers_done > $alloffers_want;
	}
    }
}

my $r= read STDIN,$b,1;
STDIN->error and die $!;
STDIN->eof or die;
$b and die;




#
#
#Version number (3 ascii digits) followed
#by LF (i.e. 0x0A).  Current version is\
# 005
#
#  0000   30 30 35 0a                                        005.
#
## of shops/stalls (in ascii)  + LF
#  0000               31 0a                                      1.           
#
#list of shop names in ascii (without the
#possessive part and by specifying the \
#shop type in an abbreviated way which is
#mentioned below).  The shop names are
#separated \ by line feeds (0x0A).  To
#specify the shop type append the "^"
#character and then \ one of the
#following characters depending upon the
#shop type:
#   Apothecary = A
#   Distillery = D
#   Furnisher = F
#   Iron Monger = I
#   Shipyard = S
#   Tailor = T
#   Weavery = W
#
#  0000                     4f 6c  64 20 49 72 6f 6e 73 69         Ol d Ironsi
#  0010   64 65 73 0a                                        des.              
#
## of buy offers (in binary)
#  0010               05 00                                 
#
#commodIndex offerCount                                       buy 0/5
#  0010                     0a 00  01 00                      Grog x 1
#[shopIndex val amt]                   
#  0010                                  01 00 1d 00 75 00    OI 29 qty 75
#
#commodIndex offerCount                                       buy 1/5
#  0020   0b 00 01 00                                         Fine x 1
#[shopIndex val amt]... (all in binar\ y)
#  0020               01 00 33 00  e9 03                      OI 51 qty 0x3e9
#
#commodIndex offerCount                                       buy 2/5
#  0020                                  0c 00 01 00          Small shot x 1
#[shopIndex val amt]
#  0020                                              01 00    OI
#  0030   0f 00 e9 03                                         15 qty 0x3e9
#
#commodIndex offerCount                                       buy 3/5
#  0030               0d 00 01 00                             Medium shot x 1
#[shopIndex val amt]
#  0030                            01 00 1c 00 e9 03          OI 28 qty 0x3e9
#
#commodIndex offerCount                                       buy 4/5
#  0030                                              0e 00    Large shot
#  0040   01 00                                                          x 1
#[shopIndex val amt]
#  0040         01 00 26 00 e9 03                             OI 38 0x3e9
#
#
## of sell offers (in binary)
#  0040                            04 00
#
#commodIndex offerCount                                       sell 0/4
#  0040                                  09 00 01 00          Swill x 1
#[shopIndex val amt]
#  0040                                              01 00    OI 
#  0050   17 00 e8 03                                         23 0x3e8
#commodIndex offerCount                                       sell 1/4
#  0050               0a 00 01 00                             Grog x 1
#[shopIndex val amt]
#  0050                            01 00 1e 00 73 03          OI 30 qty 0x373
#commodIndex offerCount                                       sell 2/4
#  0050                                              0c 00    Small shot
#  0060   01 00                                               x 1
#[shopIndex val amt]
#  0060         01 00 10 00 07 00                             OI 16 qty 7
#commodIndex offerCount                                       sell 3/4
#  0060                            0d 00 01 00                Medium shot x 1
#[shopIndex val amt]
#  0060                                        01 00 1e 00    OI 30
#  0070   02 00                                               qty 2
#
# buy offers need to be sorted first by commodity index, then by
# prices (prices ascending)
# sell offers need to be sorted first by commodity index, then by
# prices (prices descending)
# [ however, it seems that this is wrong and the price sort order is
#   supposed to be descending for buy and ascending for sell ]
