#!/usr/bin/perl -w
#
#  Convert a data (text) file into DBF format
#
#  Copyright (C) 2001  Willem A. Schreuder <willem@prinmath.com>
#  This file is part of the KUDU suite of software.
#
#  The KUDU programs are free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License as
#  published by the Free Software Foundation; either version 2 of the
#  License, or (at your option) any later version.
#
#  The KUDU programs are distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#  General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with the GPSd programs; see the file COPYING.  If not, write
#  to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,


use strict;
use lib "/pm/grflib/perl";
use PM;
use DBF;
use Calendar;
use GetOpt;

#
#  Translate dates
#
sub datetrans
{
   my ($type,$date) = @_;
   my ($yr,$mo,$dy) = (0,0,0);
   if ($type eq 'mmm-YYYY')
   {
      ($yr,$mo) = ddMMMyyyy("01-$date");
   }
   elsif ($type eq 'MM/DD/YYYY')
   {
      ($date =~ /^(\d+)\/(\d+)\/(\d+)$/) || die "Invalid US date $date\n";
      ($yr,$mo,$dy) = ($3,$1,$2);
   }
   else
   {
      die "Invalid date type $type\n";
   }
   return sprintf '%.4d%.2d%.2d' , $yr,$mo,$dy;
}

sub dat2dbf
{
   my ($file,$name,$skip,$fix,$tab,$pad,$clp,$date,@var) = @_;
   $file =~ /^(.*)\.(.*)$/;
   ($name) || ($name = "$1.dbf");
   ($file ne $name) || die "Invalid source file name $file\n";
   open(DAT , "<$file") || die "Cannot open file $file\n";
   my $line;
   for (my $i=0;$i<$skip;$i++)
   {
      $line = <DAT>;
   }
   my $ln=$skip;
   chomp $line;
   $line =~ s/^#//;
   (@var>0) || (@var = ($tab) ? split("\t",$line) : PM::Split($line));
   (@var>0) || die "Invalid header line: $line\n";
   #  Date translation
   my $datecol;
   if ($date)
   {
      my ($var,$type) = split('=',$date);
      for (my $k=0;$k<@var && !defined($datecol);$k++)
      {
         ($var eq $var[$k]) && ($datecol=$k);
      }
      defined($datecol) || die "Date variable $var not found\n";
      $date = $type;
      $var[$datecol] .= ':D8';
   }
   my $dbf = DBF->new(@var);
   while ($line = <DAT>)
   {
      $ln++;
      (substr($line,0,1) ne "#") || next;
      chomp $line;
      ($line !~ /^END(DATA)?/) || last;
      my @val;
      if ($tab)
      {
         @val = split("\t",$line);
      }
      elsif ($fix)
      {
         @val = split(" ",$line,scalar(@var));
      }
      else
      {
         @val = PM::Split($line);
      }
      while ($pad && @val<@var)
      {
         push @val , undef;
      }
      while ($clp && @val>@var)
      {
         pop @val;
      }
      unless (@var==@val)
      {
         printf "Incorrect number of fields var=%d , val=%d, line $ln\n" , scalar(@var) , scalar(@val);
         die "$line\n";
      }
      #  Fix date
      defined($datecol) && ($val[$datecol] = datetrans($date,$val[$datecol]));
      $dbf->add(@val);
   }
   close(DAT);
   $dbf->format(1);
   $dbf->write($name);
}

my %args = GetOpt("D:d::s:o:ftpc" , d=>[] , s=>1 , f=>0 , t=>0 , p=>0 , c=>0 , D=>'');
(@ARGV>0) || die "Usage: $0 [-d var] <files>\n";
my @var  = @{$args{d}};
my $skip = $args{s};
my $fix  = $args{f};
my $tab  = $args{t};
my $pad  = $args{p};
my $clp  = $args{c};
my $out  = $args{o};
my $date = $args{D};

($skip==0 && @var==0) && die "No variables defined\n";
($tab && $fix) && die "-t and -f are mutually exclusive\n";
($pad && $clp) && die "-p and -c are mutually exclusive\n";

foreach my $file (@ARGV)
{
   dat2dbf($file,$out,$skip,$fix,$tab,$pad,$clp,$date,@var);
}
