#!/usr/bin/perl -w

use strict;
use warnings;

# The values are:
#   required/optional/ignored on insert
#   required/optional/ignored on query
#   present/absent            on results
#   comment about the field  [optional value]
our %comments = (
	priority =>	[ "ignored", "optional", "present",
	                  "Every type of report has an associated priority that controls ".
	            	  "which data are first returned when there is more than one in the ".
		    	  "same physical space.  It can be changed by editing ".
			  "/etc/dballe/repinfo.csv"],
	priomax =>	[ "ignored", "optional", "absent" ],
	priomin =>	[ "ignored", "optional", "absent" ],
	rep_cod =>	[ "required this or rep_memo", "optional", "present" ],
	rep_memo =>	[ "required this or rep_cod", "optional", "present" ],
	ana_id =>	[ "optional", "optional", "present",
			  "Internal DB-ALLe ID referring to a pseudoana entry, used as ".
	                  "a shortcut reference instead of specifying the full data" ],
	block =>	[ "optional", "optional", "present" ],
	station =>	[ "optional", "optional", "present" ],
	mobile =>	[ "required", "optional", "present",
			  "Set to 1 if the station is mobile, such as a ship or a flight; else 0"],
	ident =>	[ "required if mobile=1", "optional", "present if mobile=1" ],
	name =>		[ "optional", "optional", "present" ],
	lat =>		[ "required", "optional", "present", "on insert, it has priority over ana_id" ],
	lon =>		[ "required", "optional", "present", "on insert, it has priority over ana_id" ],
	latmax =>	[ "ignored", "optional", "absent" ],
	latmin =>	[ "ignored", "optional", "absent" ],
	lonmax =>	[ "ignored", "optional", "absent" ],
	lonmin =>	[ "ignored", "optional", "absent" ],
	height =>	[ "optional", "optional", "present" ],
	heightbaro =>	[ "optional", "optional", "present" ],
	year_ident =>	[ "required if mobile=1", "optional", "present if mobile=1",
			  "Only needed when the station is mobile"],
	month_ident =>	[ "required if mobile=1", "optional", "present if mobile=1",
			  "Only needed when the station is mobile"],
	day_ident =>	[ "required if mobile=1", "optional", "present if mobile=1",
			  "Only needed when the station is mobile"],
	hour_ident =>	[ "required if mobile=1", "optional", "present if mobile=1",
			  "Only needed when the station is mobile"],
	min_ident =>	[ "required if mobile=1", "optional", "present if mobile=1",
			  "Only needed when the station is mobile"],
#	datetime =>	[ "ignored", "ignored", "present",
#	                  "Convenience parameter: after a query it contains the datetime informations ",
#			  " all in a single string"],
	year => 	[ "required", "optional", "present" ],
	month => 	[ "required", "optional", "present" ],
	day =>	 	[ "required", "optional", "present" ],
	hour => 	[ "required", "optional", "present" ],
	min => 		[ "required", "optional", "present" ],
	sec =>	 	[ "required", "optional", "present" ],
	yearmax =>	[ "ignored", "optional", "absent" ],
	yearmin =>	[ "ignored", "optional", "absent" ],
	monthmax =>	[ "ignored", "optional", "absent" ],
	monthmin =>	[ "ignored", "optional", "absent" ],
	daymax =>	[ "ignored", "optional", "absent" ],
	daymin =>	[ "ignored", "optional", "absent" ],
	hourmax =>	[ "ignored", "optional", "absent" ],
	hourmin =>	[ "ignored", "optional", "absent" ],
	minumax =>	[ "ignored", "optional", "absent" ],
	minumin =>	[ "ignored", "optional", "absent" ],
	secmax =>	[ "ignored", "optional", "absent" ],
	secmin =>	[ "ignored", "optional", "absent" ],
	leveltype =>	[ "required", "optional", "present" ],
	l1 =>		[ "required", "optional", "present" ],
	l2 =>		[ "required", "optional", "present" ],
	pindicator =>	[ "required", "optional", "present" ],
	p1 =>		[ "required", "optional", "present" ],
	p2 =>		[ "required", "optional", "present" ],
	var =>		[ "ignored", "optional", "present, indicates the name of the last variable returned" ],
	varlist =>	[ "ignored", "optional", "absent",
			  "Comma-separated list of variable codes wanted on output" ],
	query =>	[ "ignored", "optional", "absent",
			  "Comma-separated list of query modifiers.  Can have one of: ".
			  "'best', 'bigana', 'nosort', 'stream'.  ".
			  "Examples: 'best', 'nosort,stream'" ],
	ana_filter =>	[ "ignored", "optional", "absent",
			  "Restricts the results to only those stations which ".
			  "have a pseudoana value that matches the filter. ".
			  "Examples: 'height>=1000', 'B02001=1', '1000<=height<=2000" ],
	data_filter =>	[ "ignored", "optional", "absent",
			  "Restricts the results to only those stations which ".
			  "have a data value that matches the filter. ".
			  "Examples: 't<260', 'B22021>2', '10<=B22021<=20'" ],
	attr_filter =>	[ "ignored", "optional", "absent",
			  "Restricts the results to only those data which ".
			  "have an attribute that matches the filter. ".
			  "Examples: 'conf>70', 'B33197=0', '25<=conf<=50'" ],
	limit =>	[ "ignored", "optional", "absent",
			  "Maximum number of results to return" ],
);

my $op = $ARGV[0];

# Read the data
my @data;
while (<STDIN>)
{
    chop();

    if (/^([^,]+),([^,]+),(\d+),(\d+),(.+?)\s*$/)
    {
        push @data, [$1, $2, $3, $4, $5];
    }
}

our ($tag, $unit, $format, $desc, $ins, $que, $res, $com);

our $DoxIntro = q{/**@defgroup dba_record_keywords Keywords used by dba_record
@ingroup tables

This table lists the keywords used by ::dba_record.  You can use them to query
and set data using function such as dba_enqi() and dba_seti().

Every keyword is listed together with its measure unit, length in characters or
digits and description.

\verbatim
};
format DoxTop =
Name          Unit      Format        Description
.
format Dox =
@<<<<<<<<<<<< @<<<<<<<< @<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$tag,         $unit,    $format,      $desc
.
our $DoxBottom = q{\endverbatim
*/
};

our $RstIntro = q{.. table:: Standard parameter names

  =============  =========  ==========  ===========================  =========  ========  ==========  ===============================
  Name           Unit       Format      Description                  On Insert  On query  On results  Comment
  =============  =========  ==========  ===========================  =========  ========  ==========  ===============================
};
format Rst =
  @<<<<<<<<<<<<  @<<<<<<<<  ^<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<  ^<<<<<<<  ^<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  $tag,          $unit,     $format,    $desc,                       $ins,      $que,     $res,       $com
~~                          ^<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<  ^<<<<<<<<  ^<<<<<<<  ^<<<<<<<<<  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                            $format,    $desc,                       $ins,      $que,     $res,       $com
.
our $RstBottom = '
  =============  =========  ==========  ===========================  =========  ========  ==========  ===============================';

sub mkformat($$$)
{
	my ($unit, $len, $dec) = @_;
	if ($unit =~ /^CHARACTER|^CODE TABLE/)
	{
		return "$len chars";
	} elsif ($dec == 0) {
		return "$len digits";
	} else {
		return '#' x ($len - $dec) . '.' . '#' x $dec;
	}
}

if ($op eq 'dox')
{
	print $DoxIntro;
	$^ = "DoxTop";
	$~ = "Dox";
	for my $d (@data)
	{
		my ($len, $dec);
		($tag, $unit, $len, $dec, $desc) = @$d;
		$com = ($comments{$tag} or '');
		$format = mkformat($unit, $len, $dec);
		write STDOUT;	
	}
	print $DoxBottom;
}
elsif ($op eq 'rst')
{
	print $RstIntro;
	#$^ = "RstTop";
	$~ = "Rst";
	for my $d (@data)
	{
		my ($len, $dec);
		($tag, $unit, $len, $dec, $desc) = @$d;
		$ins = ($comments{$tag}[0] or '');
		$que = ($comments{$tag}[1] or '');
		$res = ($comments{$tag}[2] or '');
		$com = ($comments{$tag}[3] or '');
		$format = mkformat($unit, $len, $dec);
		write STDOUT;	
	}
	print $RstBottom, "\n";

}
elsif ($op eq 'tex')
{
	my $nc = '@{\hspace{0.5mm}}l@{\hspace{0.5mm}}';
	my $dsc = '@{\hspace{0.5mm}}p{2.0cm}@{\hspace{0.5mm}}';
	my $onc = '@{\hspace{0.5mm}}p{1.4cm}@{\hspace{0.5mm}}';
	my $cmc = '@{\hspace{0.5mm}}p{3.5cm}@{\hspace{0.5mm}}';
	print qq#{\\begin{scriptsize}
\\begin{longtable}{|$nc|$nc|$nc|$dsc|$onc|$onc|$onc|$cmc|}
\\hline
{\\em Name} & {\\em Unit} & {\\em Format} & {\\em Description} & {\\em On insert input} & {\\em On query input} & {\\em On output} & {\\em Comment} \\\\
\\hline
\\endhead
\\hline
\\endfoot
#;


	for my $d (@data)
	{
		my ($len, $dec);
		($tag, $unit, $len, $dec, $desc) = @$d;
		$ins = ($comments{$tag}[0] or '');
		$que = ($comments{$tag}[1] or '');
		$res = ($comments{$tag}[2] or '');
		$com = ($comments{$tag}[3] or '');
		$format = mkformat($unit, $len, $dec);
		$format =~ s/(\#+\.\#+)/{\\tiny $1}/;
		$unit =~ s/CHARACTER/Character/;
		$unit =~ s/(NUMERIC|NUMBER)/Numeric/;
		my $out = join(' & ', ($tag, $unit, $format, $desc, $ins, $que, $res, $com))." \\\\\n";
		$out =~ s/(_|#)/\\$1/g;
		print $out;
	}
	
	print q#\hline
\end{longtable}
\end{scriptsize}
}
#;
}
else
{
	die "unknown output format ".$ARGV[0];
}


