#!/usr/bin/perl -w
#
# Cetus GPS track -> GPSy Extended Format
# Nowral
# 01/10/13
# This product includes software written by Kjeld Jensen<kjeld@cetus.dk>
#
# initialize
use Time::Local;
use File::Basename;
$cwd = (fileparse($0, ''))[1];

# file loop begin
foreach $oldargv (sort @ARGV) {
print "-"x70, "\n", basename($oldargv, ''), "\n";
open(IN, $oldargv);

# pdb_header
read(IN, $_, 32);
/^([^\x00]+)/;
$name = $1;
read(IN, $_, 46);
my($attr,$ver,$cdt,$mdt,$bdt,$mnm,$aid,$sid,$typ,$crtr,$isd,$nrl,$nrd)
 = unpack("nnNNNNNNA4A4NNn", $_);
unless($typ eq "strm" && $crtr eq "cGPS") {
  print "Not Cetus GPS track file!\n";
  next;
}

# pdb_rec_header
read(IN, $_, 4);
seek(IN, unpack("N", $_), 0);

# TRACK FILE INFORMATION RECORD
read(IN, $_, 4);
next unless($_ eq "DBLK");
read(IN, $_, 4);
  
read(IN, $_, 21); # Record 1
($id,$ver,$int,$gps,$mag,$year,$mon,$mday,$wday,$hour,$min,$sec,$dat,$nrth)
 = unpack("a2cCnnCCCCCCCCC", $_);
next unless($id eq "CG"); # track ID ("CG")
$year += 100;
$mon--;
$wday = (qw(SUN MON TUE WED THU FRI SAT))[$wday];
$t = timelocal($sec,$min,$hour,$mday,$mon,$year);
$gps = ("No GPS","Unknown","Demo GPS","GARMIN","Rockwell",
 "Magellan","DeLorme Tripmate","Motorola")[$gps];
$mag /= 10;
$dat = ("WGS 84")[$dat];
$nrth = ("True","Magnetic")[$nrth];
read(IN, $_, 26); # Record 2
/^([^\x00]+)/;
$desc = $1;
read(IN, $_, 16); # Record 3

# TRACK INFORMATION
print "\nDescription: \t$desc\n";
print "Track start: \t", &formd($t), "\n";
print "GPS receiver: \t$gps\n";
print "Interval: \t$int\n";
print "Datum: \t$dat\n";
print "North ref: \t$nrth\n";
printf "Magnetic var: \t%.1f\n", $mag;
print "version: \t$ver\n\n";

# TRACK RECORD
$trc = 3;
LOOP:while(1) {
  while($trc<195) {
    read(IN, $_, 21) || last LOOP;
    my($stat,$min,$sec,$sat,$hdop,$lat,$lon,$spd,$crs,$alt)
     = unpack("CCCCCNNnnN", $_);
    $t = timelocal($sec,$min,$stat%0x20,$mday,$mon,$year); # ? >24:00
    $stat >>= 5; # 0:No GPS, 1:No fix, 2:2d fix, 3:3d fix, 4:DGPS (3d) fix
    next if $stat<2;
    $hdop /= 10; # HDOP
    $lat /= 1.0e7;
    $lon /= 1.0e7;
    $spd *= 1.851999/10; # current speed in kph
    $crs /= 10; # course made good
    $alt /= 100; # altitude in meter
    push(@lines, join("\t", (
     "T", "1", " ", "", &formd($t),
     &deg2gdms($lat), &deg2gdms($lon), "-",
     sprintf("% .1f", $alt), "DMS", $dat, "0", "0.00"
    ) ) );
    ++$trc;
  }
  read(IN, $_, 9) || last LOOP;
  $trc = 0;
}
close(IN);

# output file
$name =~ tr/:\\/\./; # file name
printf "--> \"%s\" (%d)\n", $name, $#lines+1;
$newargv = $cwd . $name;
open(OUT, ">$newargv") || die "Couldn't open $newargv\: $^E";
MacPerl::SetFileInfo('GPSy', 'TEXT', $newargv);
print OUT "GPSy3 Track     (version 3.38r3)\tNUMBER\tNAME\tCOMMENT",
 "\tDATE\tLAT/NORTHING\tLON/EASTING\tZONE\tALT\tCOORD\tDATUM\tICON\tPROX\n";
printf OUT "#\tRecords:\t%d\n", $#lines+1;
print OUT join("\n", @lines), "\n";
close(OUT);

# file loop end
}
print "-"x70, "\n";

#MacPerl::Quit(2);
#die "The Unhappy End";
exit(0);



sub formd { # GPSy format of date
  my($t) = @_;
  my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($t);
  return sprintf("%d/%d/%04d %d:%02d:%02d",
   $mon+1,$mday,$year+1900,$hour,$min,$sec);
}

sub deg2gdms { # GPSy format of position
  my($d) = @_;
  my($sgn, $m, $s, $sf);
  $d -=360 if $d>180; # longitude
  if($d<0) {
    $sgn = "-";
    $d *= -1;
  }
  else{ $sgn = ""; }
  $sf = int($d*36000 + 0.5);
  $s = int($sf/10) % 60;
  $m = int($sf/600) % 60;
  $d = int($sf/36000);
  $sf %= 10;
  sprintf("%s%d。%02d\'%02d\.%d\"", $sgn, $d, $m, $s, $sf);
}