#!/usr/bin/perl 
eval 'exec perl -S $0 "$@"'
	if $running_under_some_shell;
	 

# HACtrans: Import/Export tour info from Ciclo's Hac4
#

# Copyright (C) 1999-2001 by Winfried Beer.
# All rights reserved.
#
# This software may be freely copied, modified and redistributed
# without fee provided that this copyright notice is preserved
# intact on all copies and modified copies.
#
# There is no warranty or other guarantee of fitness of this software.
# It is provided solely "as is". The author(s) disclaim(s) all
# responsibility and liability with respect to this software's usage
# or its effect upon hardware or computer systems.
#
# 22.02.2001: W.Beer: Update auf Format 1.4 von HAC
# 22.04.2001: W.Beer: Beim Umwandeln der HAC-Zeitangaben 24 Stunden abziehen!

require "getopts.pl";

$prog = $0 ;
$prog =~ s@.*/@@;
$usage = "Usage: $prog [-t] file\nTranslate tour file to ascii stdout.\n-t: translate ascii file to original tour format\n";
&Getopts('t:') || die $usage;

die "$usage" if ($#ARGV < 0);

if (!$opt_t) { 
  # --- convert TUR file to ascii

  # - read TUR file
  while ($file=shift) {
    open (F, "< $file") or die "Can't open '$file' for reading.\n";

    @info=();
    &readln ("Format");
    &readln ("Format1");
    &readln ("Format2");
    &readln ("Format3");
    &readln ("Titel");
    &readln ("Startort");
    &readln ("Zielort");
    &readln ("Datum");
    &readln ("Uhrzeit");
    &readln ("AnzNotizen");

    $i=1;
    $k=$info[$#info];
    while ($i<=$k) {
        &readln ("Notiz".$i);
        $i++;
    }

    &readln ("Distanz"); push @info, sprintf("%3.2f", (pop @info)/100.0); # Umrechnung in km
    &readln ("Gesamtzeit"); $k=pop @info; 
      push @info, sprintf("%02d:%02d:%02d",$k/3600,($k/60)%60,$k%60); # Umrechnung in hh:mm:ss
    &readln ("Unbekannt1");
    &readln ("MaxHoehe");
    &readln ("DifHoehe");
    &readln ("AvgSteigen");
    &readln ("AvgSteigung");
    &readln ("AvgTempo");
    &readln ("AvgTemperatur");
    &readln ("AvgPuls");
    &readln ("Unbekannt2");
    &readln ("Modus");
    &readln ("Unbekannt3");
    &readln ("ReserveA1");
    &readln ("ReserveA2");
    &readln ("ReserveA3");
    &readln ("ReserveA4");
    &readln ("ReserveA5");
    &readln ("ReserveA6");
    &readln ("ReserveA7");
    &readln ("Name");
    &readln ("Vorname");
    &readln ("Geburtsdatum");
    &readln ("Verein");
    &readln ("Gewicht");
    &readln ("ObereHF");
    &readln ("UntereHF");
    &readln ("Material");
    &readln ("Materialgewicht");
    &readln ("DistanzBisher");
    &readln ("FahrzeitBisher"); $k=pop @info; 
      push @info, sprintf("%02d:%02d:%02d",$k/3600,($k/60)%60,$k%60); # Umrechnung in hh:mm:ss
    &readln ("RaufBisher");
    &readln ("RunterBisher");
    &readln ("ReserveB1");
    &readln ("ReserveB2");
    &readln ("ReserveB3");
    &readln ("ReserveB4");
    &readln ("ReserveB5");
    &readln ("ReserveB6");
    &readln ("ReserveB7");
    &readln ("ReserveB8");
    &readln ("ReserveB9");
    &readln ("ReserveB10");
    &readln ("AnzDaten");

    @data=();
    $k=$info[$#info];
    for ($i=0; $i<$k; $i++) {
      read F, $data[$i],20; # new format, older: 16
      # ($tim[$i],$dist[$i],$height[$i],$hbeats[$i],$cadence[$i],$temperature[$i],undef) = unpack ("VVvCCcV", $data[$i]);
      # $dist[$i]*=10;
    }
    read F, $line,1;

    &readln ("AnzMarken");
    $k=$info[$#info];
    for ($i=1; $i<=$k; $i++) {
      &readln ("MarkeZeit".$i);
      &readln ("Marke".$i);
    }
    close(F);

    %info=@info;


    # -- convert lines (@data -> @datalines)
    &convertLines;

    # -- write ASCII output
    for ($i=0;$i<$#info-2*(2*$info{"AnzMarken"}+1);$i=$i+2) {
      printf "%-18s %s\n",$info[$i].":",$info[$i+1];
    }
    for ($i=0;$i<=$#dataline;$i++) {
      printf $dataline[$i];
    }
    for ($i=$#info-2*(2*$info{"AnzMarken"}+1)+1;$i<$#info;$i=$i+2) {
      printf "%-18s %s\n",$info[$i].":",$info[$i+1];
    }



  }
} else { 
    # --- convert TUR file to binary (export)
    $file=shift;
    open (F, "< $file") or die "Can't open '$file' for reading.\n";
    while (<F>) {
    }
}
    
    
exit 0;

# --------------------------------------------------------------
sub readln ($s) {
  my $s=$_[0];
  my $a=$_=<F> or die "Error reading file.\n";
  chomp $a;
  push (@info, $s);
  push (@info, $a);
}


# --------------------------------------------------------------
# convert @data into @datalines and evaluate some global 
# variables
# 
sub convertLines {
    $rc=0.01;  # Reibungskoeffizient
    $cw=0.9;   # cw-Wert
    $Af=0.45;  # Luftwiderstandflaeche
    $minddistgrad=400;    # Mindestabstand für Steigungsberechnung [m]
    $minupdownheight=2;  # Mindesthoehendifferenz, damit bergauf/bergab zaehlt  [m]

    $mass=$info{'Gewicht'}+$info{'Materialgewicht'}; # Gesamtgewicht [kg]

    $cycletim=0;   # [s]
    $Hmin=0.0;     # [m/min]
    $grad=0.0;     # [%]
    $speed=0.0;    # [m/s]
    $Psum=0.0;     # [W]
    $Ppot=0.0;     # [W]
    $Pkin=0.0;     # [W]
    $Pfric=0.0;    # [W]
    $Pair=0.0;     # [W]
    $markcnt=1;

    $dataline[0]=sprintf(":%9s %8s %8s %8s %8s %5s %4s %4s %4s %6s %6s %6s %5s %5s %5s %5s %5s%s\n",
      "Datum","Uhrzeit","Zeit","Fahrzeit","Strecke","Hoehe","Puls","Temp","Cade","Hmin","Steig","Tempo","Psum","Ppot","Pkin","Pfric","Pair"," # Marke");
    for ($i=0;$i<$#data;$i++) {
      ($datetime,$tim,$dist,$height,$hbeats,$cadence,$temperature,undef) = unpack ("VVVvCCcV", $data[$i]);
      if ($height>32767) { $height=$height-65536; };
      $dist=$dist*10;

      $markstr=""; 
      if ($i==0) {$markstr=" # ".$info{'Startort'};}
      if ($i==$#data-1) {$markstr=" # ".$info{'Zielort'};}
      if ($markcnt<=$info{'AnzMarken'}) {
        if ($tim>=$info{'MarkeZeit'.$markcnt}) {
	  $markstr=" # ".$info{'Marke'.$markcnt};
	  $markstr=~ s/;[^;]*;[^;]*$//;
	  $markcnt++;
	}
      }

      if ($i>0) {
        $dtim=$tim-$oldtim;
        $ddist=$dist-$olddist;
        $dheight=$height-$oldheight;

	$speed=$ddist/$dtim;
        $Hmin=$dheight/$dtim*60;    # Steigen
   	$Ppot=$mass*9.81*$dheight/$dtim;   # potentiele Leistung
        $Pfric=$rc*$mass*9.81*$speed;       # Reibungsverlustleistung
        $Pair=0.5* exp(-1.2928*9.81*$height/101325) 
	  * 1.2928*273.15/(273.15+$temperature) *$cw*$Af*$speed*$speed*$speed;  # Lufreibung
	$Pkin=0.5*$mass*($speed*$speed-$oldspeed*$oldspeed)/$dtim;    # kinetische Energie zum Beschleunigen/Abbremsen
	$Psum=$Ppot+$Pkin+$Pfric+$Pair;
			  
	$ddistgrad+=$ddist;
	$dheightgrad+=$dheight;
        if ($ddistgrad>=$minddistgrad) {
	  $grad=$dheightgrad/$ddistgrad*100; # Steigung [%]
	  $ddistgrad=0;
	  $dheightgrad=0;
	}else{
	  $grad=999;   # dummy-Wert
	}

        if ($ddist==0) {
	  $cycletim=$oldcycletim;
	}else{
	  $cycletim=$oldcycletim+$dtim; # erhoehe reine Fahrzeit nur bei Fahrt :-)   
	}

        if ($height>=$lastupdownheight+$minupdowndheight){
          $upheight+=$height-$lastupdownheight;
          $lastupdownheight=$height;
        }elsif ($height<=$lastupdownheight-$minupdowndheight){
          $downheight+=$lastupdownheight-$height;
          $lastupdownheight=$height;
        }

        if ($height>$maxheight) {$maxheight=$height}
        if ($height<$minheight) {$minheight=$height}
        if ($speed>$maxspeed) {$maxspeed=$speed}
        if ($hbeats>0) {$sumhbeats+=$hbeats*$dtim; $sumhbeatstim+=$dtim;}
        if ($hbeats>$maxhbeats) {$maxhbeats=$hbeats}
        if ($Psum>70) {$sumPsum+=$Psum*$dtim; $sumPsumtim+=$dtim;} # zu kleine Leistung zaehlt nicht
        if ($Psum>$maxPsum) {$maxPsum=$Psum}
 
 

      }else{ #  Anfangswerte belegen (bei erster Datenzeile) 
        $sumhbeatstim=0;
        $sumPsumtim=0;
        $lastupdownheight=$height;

        $ddistgrad=0;
        $dheightgrad=0;

        $maxheight=$height;
        $minheight=$height;
        $maxhbeats=$hbeats;
        $maxPsum=0;
        $downheight=0;
        $upheight=0;
      }
        

      # ZZZZ glob-avg-max-min-Uebergabe

      ($sec,$min,$hour,$mday,$mon,$year,undef,undef,undef) = gmtime($datetime-24*60*60);
      $datestr=sprintf("%02d.%02d.%04d",$mday,$mon+1,$year+1900);   # Umrechnung in dd.mm.yyyy
      $wallclock=sprintf("%02d:%02d:%02d",$hour,$min,$sec);   # Umrechnung in hh:mm:ss

      $timstr=sprintf("%02d:%02d:%02d",$tim/3600,($tim/60)%60,$tim%60);      # Umrechnung in hh:mm:ss
      $cycletimstr=sprintf("%02d:%02d:%02d",$cycletim/3600,($cycletim/60)%60,$cycletim%60);  # Umrechnung in hh:mm:ss
      push @dataline, sprintf("%10s %8s %8s %8s %8.3f %5d %4d %4d %4d %6.1f %6.1f %6.1f %5d %5d %5d %5d %5d%s\n",
        $datestr,$wallclock,$timstr,$cycletimstr,$dist/1000,$height,$hbeats,$temperature,$cadence,
	$Hmin,$grad,$speed*3.6,$Psum,$Ppot,$Pkin,$Pfric,$Pair,$markstr);

      $oldtim=$tim;
      $oldcycletim=$cycletim;
      $olddist=$dist;
      $oldheight=$height;
      $oldspeed=$speed;
      
    }
    $avgspeed=$cycletim==0?0:$dist/$cycletim*3.6;
    $maxspeed=$maxspeed*3.6;
    $avghbeats=$sumhbeatstim==0?0:$sumhbeats/$sumhbeatstim;
    $avgPsum=$sumPsumtim==0?0:$sumPsum/$sumPsumtim;
}


