#!/usr/bin/perl

    # programming by Jochen Puchalla (c) 2007-2010
    # mail at puchalla dash online dot de
    # License: GPL V2

$pi=3.141592;
$g=9.81; # gravitation
$cw=0.4; # air resistance
$rho=1.2; # air density
$roll=0.003; # roll resistance
$every=3;
$bergmin=100;
$W=90; # kg total

foreach $file (@ARGV)
{
	if (! open(INPUT,"<$file") )
	{
		print STDERR "Can't open input file $file\n";
		next;
	}

	print STDOUT "\n$file:\n";

	$filecore=$file;
	$filecore =~ s/.gpx$//g;

	if ($file eq $filecore)
	{
		print STDERR "$file is not a gpx file\n";
		next;
	}

	# set values to 0 for every new file:
	$sum_rise=0; # Steigmeter
	$sum_fall=0; # Fallmeter
	$sum_h=0; # Höhensumme
	$sum_s=0; # Strecke
	$sum_t=0; # Zeit
	$maxcount=0;
	$h_max=0;
	$h_min=8848;
	$s_max=0;
	$v_max=0;
	$n=0;
	$punkte=1;
	$anstieg=0;
	$abfahrt=0;

	while ($line=<INPUT>)
	{
		if ($line =~ /trkpt\ lat\=/)
		{
			@values = split(/\"/, $line);
			$lat[$n]=$values[1];
			$lon[$n]=$values[3];
			$deltas = 1000 * sqrt( (($lat[$n]-$lat[$n-1])*$pi*6371/180) * (($lat[$n]-$lat[$n-1])*$pi*6371/180) + (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) * (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) );
			if ($n==0) {$deltas=0;}
# 		 	printf STDOUT "delta s = %.0f \n",$deltas ;
# 			printf STDOUT "%5.2f  %5.2f  %5.2f  %5.2f  %5.2f \n" , $values[1], $values[2], $values[3], $values[4], $values[5];
			$line=<INPUT>;
			$line =~ s/e//g;
			$line =~ s/l//g;
			$line =~ s/<//g;
			$line =~ s/>//g;
			$line =~ s/\///g;
			$line =~ s/\ //g;
			$h[$n]=$line;

######### HÖHENGLÄTTUNG #########################
			if ($n>0) {$h[$n]=($h[$n]+$h[$n-1]*12)/13;}

			if ($h[$n] > $h_max) {$h_max=$h[$n];}
			if ($h[$n] < $h_min) {$h_min=$h[$n];}
#			printf STDOUT $line;

			$line=<INPUT>;
			$line =~ s/t//g;
			$line =~ s/i//g;
			$line =~ s/m//g;
			$line =~ s/e//g;
			$line =~ s/Z//g;
			$line =~ s/<//g;
			$line =~ s/>//g;
			$line =~ s/\///g;
			$line =~ s/\ //g;
			$line2 = $line; # Kopie für Datum
			$line =~ s/^.*T//g;
			$line =~ s/[\n\r]$//g; # remove newline at end of string
			if ( $n < 2 ) {$t_start = $line ;}
			$t_ziel = $line ;
			@values = split(/\:/, $line);
			$seconds[$n]=$values[0]*3600+$values[1]*60+$values[2];

			$time[$n]=$seconds[$n]-$seconds[0]; if ($time[$n]<0){$n=-1; $h_max=0; $h_min=8848;} # start all over

  			if ($deltas > 2000) {$n=-1; $h_max=0; $h_min=8848; } # start all over at big jumps

#    			printf STDOUT "%2.0f %2.0f %2.0f %6.0f  \n" , $values[0], $values[1], $values[2], $time[$n];

 			$n++;
		}
		if ($line =~ /\<\/trk\>/) {last;}
		if ($line =~ /\<\/rte\>/) {last;}
	}

	# Datum:
	$line2 =~ s/T.*//g;
	$line2 =~ s/[\n\r]$//g; # remove newline at end of string
	@values = split(/-/, $line2);
	$date="$values[2].$values[1].$values[0]";
	$filedate="$values[0]$values[1]$values[2]";

	printf STDOUT "Max. Height = %.0f m\n",$h_max ;
	printf STDOUT "Min. Height = %.0f m\n",$h_min ;
 	$h_diff_total=$h_max-$h_min;

	$maxcount=$n;
 	printf STDOUT "Data Points: %.0f \n",$maxcount ;
	$h_finish=int($h[$n-1]);
 	printf STDOUT "Height at End = %.0f m\n",$h_finish ;

	$h[0]=$h[1];
	$s[0]=0;

	$n=1;
	while ($n < $maxcount)
	{
		# Abstand:
		$deltas = 1000 * sqrt( (($lat[$n]-$lat[$n-1])*$pi*6371/180) * (($lat[$n]-$lat[$n-1])*$pi*6371/180) + (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) * (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) );
		# Zeitdiff:
		$deltat = $seconds[$n] - $seconds[$n-1];
		# Distanz(n):
		$s[$n] = $s[$n-1] + 1000 * sqrt( (($lat[$n]-$lat[$n-1])*$pi*6371/180) * (($lat[$n]-$lat[$n-1])*$pi*6371/180) + (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) * (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) );
		# Geschw.(n):
		$v[$n] = 3.6 * ($s[$n] - $s[$n-1]) / ($seconds[$n] - $seconds[$n-1]);
		# Glättung:
		if ($n>1) {$v[$n] = 3.6 * ($s[$n] - $s[$n-2]) / ($seconds[$n] - $seconds[$n-2]);}
		if ($n>2) {$v[$n] = 3.6 * ($s[$n] - $s[$n-3]) / ($seconds[$n] - $seconds[$n-3]);}
		if ($n>3) {$v[$n] = 3.6 * ($s[$n] - $s[$n-4]) / ($seconds[$n] - $seconds[$n-4]);}

		# summiere nur Daten mit mehr als 4 km/h
		if ( $deltas / $deltat * 3.6 > 4 && $deltas / $deltat * 3.6 < 90)
		{
			# Zähler:
			$punkte++;
			# Gesamtstrecke:
			$sum_s = $sum_s + $deltas;
			# Höhensumme:
			$sum_h = $sum_h + $h[$n];
			# Nettozeit:
			$sum_t = $sum_t + $deltat;
			# v_max?
			if ($v[$n]>$v_max) {$v_max=$v[$n];}
# 			if ($v_max>90) {$W=1300;}
			# sum_rise?
			if ($h[$n]>$h[$n-1]) {$sum_rise=$sum_rise+$h[$n]-$h[$n-1];}
			# sum_fall?
			if ($h[$n]<$h[$n-1]) {$sum_fall=$sum_fall+$h[$n-1]-$h[$n];}

			if ($h[$n-2]<$h[$n-1] && $h[$n]<$h[$n-1]) {$maximum=$n; if ($h[$maximum]-$h[$minimum]>$bergmin) {$anstieg++;} }
			if ($h[$n-2]>$h[$n-1] && $h[$n]>$h[$n-1]) {$minimum=$n; if ($h[$maximum]-$h[$minimum]>$bergmin) {$abfahrt++;} }
		}

# 		printf STDOUT "v_max=%3.1f km/h\n",$v_max ;
# 		printf STDOUT "v=%d km/h\n",$v[$n] ;
# 		printf STDOUT "n=%d ",$n ;
#  		printf STDOUT "s=%5.3f ",$s[$n] ;
# 		printf STDOUT "h=%5.3f \n",$h[$n] ;

		$n++;
	}

	if ($sum_t<1) {$sum_t=1;}
 	$h_med=$sum_h/$punkte ; # mittlere Höhe
 	$v_med=$sum_s/$sum_t ; # m/s
	$power_med=$cw/2*$rho*($v_med*1.1)**3;       # Leistung durch Luftwiderstand
	$power_med=$power_med + $roll*$W*$g*($v_med*1.1);       # Leistung durch Rollwiderstand
 	$v_med=$v_med*3.6 ; # km/h

 	$hours=int($sum_t/3600);
 	$minutes=int(($sum_t-$hours*3600)/60);
 	$secs=int($sum_t-$hours*3600-$minutes*60);

 	printf STDOUT "Distance = %.2f km\n",$sum_s/1000 ;
 	printf STDOUT "Net Time = %.1f h\n",$sum_t/3600 ;
 	printf STDOUT "Average Speed = %5.2f km/h\n",$v_med ;
 	printf STDOUT "Max. Speed = %.1f km/h\n",$v_max ;
 	printf STDOUT "Date: %s \n",$date ;
 	$h[1]=int($h[1]);
 	$sum_rise=int($sum_rise);
 	$h_max=int($h_max);
 	$s_max=int($sum_s);

	$h[0]=$h[1];
	$s[0]=$s[1];

	# check for existing file:
	if (-e "${filedate}_GPS.tour") { $filedate = "$filedate".'b';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'c';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'d';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'e';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'f';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'g';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'h';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'i';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'j';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'k';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'l';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'m';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'n';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'o';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'p';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'q';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'r';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'s';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'t';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'u';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'v';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'w';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'x';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'y';}
	if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'z';}

	# open output file:
	if (! open(OUTPUT,">${filedate}_GPS.tour") ) { print STDERR "Can't open output file ${filedate}_GPS.tour\n"; $bad++; next; }
	print "Generating ${filedate}_GPS.tour\n";

	printf OUTPUT ("HAC4Linux-Tour-File created by HAC4Linux (c) by Rick-Rainer Ludwig

#
#   no, created by gpx2tour.pl (c) by Jochen Puchalla
#
######### File Format Discription #####################################
# This file contains information in ascii format. All data belongs to #
# a section startet by the sections name in rectangular brackets [    #
# and ]. The sections are collections of items which represent the    #
# data stored in this file. An item is saved as the name, an equal    #
# sign and the data directly behind (whithout any space!).            #
# Comments are save with an # in front. Table lines start with an '!' #
# sign in front of the line and clumns are separated by tabs.         #
#######################################################################

[FILE]
Version=0.1.0

[INFORMATION]
Number=1
");
	printf OUTPUT ("Date=%s\n",$date);
	printf OUTPUT ("Time=%s.00\n",$t_start);
	printf OUTPUT ("Mode=46
RecTime=00:00:00.00
TimeDriven=");
	printf OUTPUT ("%02.0f:%02.0f:%05.2f\n",$hours,$minutes,$secs);
	printf OUTPUT ("Distance=%.0f\n",$sum_s);
	printf OUTPUT ("Title=vom GPS
Start=Start
Finish=Ziel

[NOTES]

[FRIENDS]

[PERSON]
LastName=Puchalla
FirstName=Jochen
DateOfBirth=21.01.1975
SportsClub=
Equipment=Garmin GPS
MaxPulse=200
RestPulse=60
Weight=82

[STATISTICS]
");
	printf OUTPUT ("Rosen=%.0f\n",$sum_rise);
	printf OUTPUT ("Fallen=%.0f\n",$sum_fall);
	printf OUTPUT ("Altitude=%.0f;%.0f;%.0f\n",$h_max,$h_med,$h_min);
	printf OUTPUT ("Climb=25.00;1.00;0.00
Sink=-100.00;-1.00;0.00
");
	printf OUTPUT ("CountClimb=%u\n",$anstieg);
	printf OUTPUT ("CountSink=%u\n",$abfahrt);
	printf OUTPUT ("Rise=10.00;1.00;0.00
Fall=-10.00;-1.00;0.00
Pulse=180;140;0
Speed=%2.2f;",$v_max);
	printf OUTPUT ("%.2f",$v_med);
	printf OUTPUT (";0.00
Temperature=00;00;00
Power=");
	printf OUTPUT ("%.2f;%.2f",$power_med*2.5,$power_med);
	printf OUTPUT (";0.00
Cadence=95;60;0
SkiSpeed=30.00;10.00;0.00

[SETTINGS]
DeviceShortName=
DateOfTransfer=00.00.00
DeltaTime=00:00:20.00
HomeAltitude=0
Weight=90
Distance1=111
HeightUp1=222
HeightDown1=333
TotalTime1=44:44:44.44

[POLAR-EXTENSIONS]
ActiveLimit=0
MaxVO2=0
StartDelay=0

[COACH-PARAMETER]
AverageHR=0
Flag=
IntervalAverageHR=0
IntervalTime=0
MaximumHR=0
ResultHR=0
ResultTime=0
TargetZone1=0;0;0;0;0;0;0;0;0
TargetZone2=0;0;0;0;0;0;0;0;0
TargetZone3=0;0;0;0;0;0;0;0;0

[TOUR-DATA]
#Pulse	Cadence	Temperature	Altitude	Marking	Gradient	Speed	Distance	ClimbSpeed	AverageSpeed	SkiSpeed	Power	Hour	Minute	Second
");
$n=$every; while ( $n < $maxcount )
{
	$hours=int($time[$n]/3600);
	$minutes=int(($time[$n]-$hours*3600)/60);
	$secs=int($time[$n]-$hours*3600-$minutes*60);
	$perc=($h[$n]-$h[$n-$every])/($s[$n]-$s[$n-$every])*100; # Durch Höhe ist auch Steigung geglättet
	$vmed=($s[$n])/($time[$n])*3.6;
	$power=$cw/2*$rho*($v[$n]/3.6)**3 + $roll*$W*$g*($v[$n]/3.6) ;#+ $W+$g*$mtrpermin/60;       # ca. Leistung
	$mtrpermin=($h[$n]-$h[$n-$every])/($time[$n]-$time[$n-$every])*60; # Durch Höhe ist auch Steiggeschw. geglättet
	printf OUTPUT ("!0	0	11	%.0f	0	%.2f	%.2f	%.0f	%.2f	%.2f	0.00	%.2f	%02.0f:%02.0f:%05.2f\n",$h[$n],$perc,$v[$n],$s[$n],$mtrpermin,$vmed,$power,$hours,$minutes,$secs);
	$n=$n+$every; # jeder 2te Punkt ist immer noch höher auflösend als bei Ciclosport alle 20 s
}

	printf OUTPUT ("
	[MARKING-DATA]
");

	close OUTPUT;
	close INPUT;

}

exit(0);
