#!/usr/bin/perl

use strict;
use warnings;

if( @ARGV == 0 ) {
	die "No input specified\n";
}

sub plot($$) {
	my ($filename, $log) = @_;

	my $basename = $filename; $basename =~ s/\.dat$//;
	
	open my $gpcmd, ">", "$basename.gnuplot"
		or die "Couldn't open \"$basename.gnuplot\"";

	print $gpcmd 	"set terminal png transparent size 640,400 ".
			"xffffff x000000 x404040 ". # bg, borders, axes
			"x87abff xffab87 x66cdaa xcdb5cd ". # plots
			"xadd8e6 x0000ff xdda0dd x9500d3\n". # plots
			"set lmargin 10\n".
			"set rmargin 10\n".
			"set xlabel 'Time [s]'\n".
			"set xdata time\n".
			"set timefmt '%s'\n".
			"set format x '%1Mm%02Ss'\n".
			"";

	if( $log->{speed} ) {
		print $gpcmd	"set title 'Speed during flight'\n".
				"set output '$basename.rpm.png'\n".
				"set ylabel 'Rotor speed [rpm]'\n".
				"set key off\n".
				"set grid ytics\n".
				"plot '$filename' using 1:(\$8/4/150*13) with linespoints\n";
		# TODO: maybe zoom around y=2200?
	}
	if( $log->{temperature} ) {
		print $gpcmd	"set title 'ESC temperature during flight'\n".
				"set output '$basename.temp.png'\n".
				"set ylabel 'Temperature [ºC]'\n".
				"plot '$filename' using 1:(\$7-32)*5/9 with linespoints\n";
	}
	if( $log->{powerout} ) {
		print $gpcmd	"set title 'Power Output during flight'\n".
				"set output '$basename.powerout.png'\n".
				"set ylabel 'Power output [%]'\n".
				"set yrange [0:100]\n".
				"plot '$filename' using 1:3 with linespoints\n";
	}
	if( $log->{throttle} ) {
		print $gpcmd	"set title 'Throttle input during flight'\n".
				"set output '$basename.throttle.png'\n".
				"set xlabel 'Time [s]'\n".
				"set ylabel 'Throttle Input [ms]'\n".
				"set yrange [0.9:2.1]\n".
				"set key off\n".
				"plot '$filename' using 1:2 with linespoints\n";
	}
	if( $log->{current} ) {
		print $gpcmd	"set title 'Current during flight'\n".
				"set output '$basename.current.png'\n".
				"set ylabel 'Current [A]'\n".
				"set yrange [0:*]\n".
				"set ytics nomirror\n".
				"set y2label 'Charge [mAh]'\n".
				"set y2range [0:*]\n".
				"set y2tics autofreq\n".
				"set key left top\n".
				"plot '$filename' using 1:6 with linespoints title 'Current', ".
				"     '$filename' using 1:(\$9/3.6) with lines title 'Charge' axis x1y2\n";
	}
	if( $log->{voltage} and $log->{ripple} ) {
		print $gpcmd	"set title 'Battery voltage during flight'\n".
				"set output '$basename.battery.png'\n".
				"set ylabel 'Battery Voltage [V]'\n".
				"set yrange [9:12.6]\n".
				"set y2label 'Battery Ripple [V]'\n".
				"set y2range [0:3.6]\n".
				"set ytics nomirror\n".
				"set y2tics autofreq\n".
				"set key right top\n".
				"plot '$filename' using 1:4 with linespoints title 'Voltage', ".
				"     '$filename' using 1:5 with linespoints title 'Ripple' axis x1y2\n";
	
	}

	close $gpcmd;

	system("gnuplot \"$basename.gnuplot\"");
	unlink "$basename.gnuplot";
}

sub parse_file($) {
	my ($filename) = @_;

	my $outfile = $filename;
	$outfile =~ s/\.csv//;

	open my $file, "<", $filename or die "Couldn't open \"$filename\"";
	print "Parsing \"$filename\" into \"$outfile.*\"\n";

	my $state = "FILE HEADER";
	my $session = 0;
	my $sessionfile;

	my $sample_time;
	my $sample;
	my %session_data;
	my %log;
	while(<$file>) {
		if( $state eq "FILE HEADER" ) {
			print "  $1\n" if m/^# Note - (.*)$/;
			print "Saved: $1\n" if m/^ Graph Data - \d+ Sessions - Saved (.*)$/;
			$state = "SESSION HEADER", redo if m/^# Start Of Session/;

		} elsif( $state eq "SESSION HEADER" ) {
			if( m/^# Start Of Session - Sample Time: ([\d.]+)/ ) {
				$sample = 0;
				$sample_time = $1;
				%session_data = ();
				$session++;
				open $sessionfile, ">", "$outfile.$session.dat"
					or die "Couldn't open \"$outfile.$session.dat\" for writing";
				print "Session $session, sample time $sample_time seconds\n";
			}
			$state = "LOG SELECTION" if m/^Throttle[ ,]+Power-Out[ ,]+Voltage[ ,]+Ripple[ ,]+Current[ ,]+Temperature[ ,]+Speed/;
		
		} elsif( $state eq "LOG SELECTION" ) {
			die("Expecting True/False line at line $.\n")
				unless /^(True|False)[ ,]+(True|False)[ ,]+(True|False)[ ,]+(True|False)[ ,]+(True|False)[ ,]+(True|False)[ ,]+(True|False)/;
			%log = (throttle=> ($1 eq "True"),
				powerout=> ($2 eq "True"),
				voltage=>  ($3 eq "True"),
				ripple=>   ($4 eq "True"),
				current=>  ($5 eq "True"),
				temperature=>($6 eq "True"),
				speed=>    ($7 eq "True"));
			print "[Logged]: " . join(', ', map { $log{$_} ? "[$_]" : $_ } sort keys %log) . "\n";
			$state = "DATA";

		} elsif( $state eq "DATA" ) {
			if(/^#/) {
				close $sessionfile;
				plot("$outfile.$session.dat", \%log);
				unlink "$outfile.$session.dat";
				$state = "SESSION HEADER";
				redo;
			}
			die "Unexpected line format"
				unless m/^([\d.]+)[ ,]+([\d.]+)[ ,]+([\d.]+)[ ,]+([\d.]+)[ ,]+([\d.]+)[ ,]+([\d.]+)[ ,]+([\d.]+)/;

			$session_data{"current_time"} += $5 * $sample_time;
			print $sessionfile ($sample*$sample_time)."\t$1\t$2\t$3\t$4\t$5\t$6\t$7\t".
				$session_data{"current_time"}."\n";
			$sample++;
			
		}
	}
	plot("$outfile.$session.dat", \%log);
	unlink "$outfile.$session.dat";
}

foreach my $file (@ARGV) {
	parse_file($file);
}
