#!/usr/bin/perl -w

# ----------------------------------------------------------------------
# uv.pl - Hilfsskript für die Auswertung einer OpenOffice.org Calc-Datei
# über den Lernfortschritt unregelmäßiger Verben. (Version 2)
# Siehe http://es.andreas-klingler.de/?p=1089
#
# GPL 2010/2011 Andreas Marc Klingler <post@andreas-klingler.de>
# ----------------------------------------------------------------------


use ODF::lpOD;
use Time::Local;

%::cfg = (
			'MaximalesAlterInTagen'		=> 14,
			'EintraegeAbZeile'			=> 5,
			'Vorlagentabellenname'		=> 'Vorlage'
		);

# Infoseite bei fehlender Parameterübergabe anzeigen.
unless (defined($ARGV[0]) && defined($ARGV[1])) {
	&Infoseite();
	exit;
}

# Raus, falls auf die Quelldatei nicht zugegriffen werden kann.
die "Die angegebene Datei existiert nicht oder konnte nicht geöffnet werden."
	unless (-e $ARGV[0]);

# Vokabeldatei öffnen
$uvdok = odf_document->get($ARGV[0]);


if ($ARGV[1] eq '0') {

	# Daten berechnen, aufsteigend sortieren
	# nach der 2. Spalte und iterativ ausgeben.
	foreach((sort { $a->[1] <=> $b->[1] } &Gesamtuebersicht())) {
		print sprintf("%.0f" , $_->[1]) . "% | " . $_->[0] . "\n";
	}

} elsif ($ARGV[1] eq '1') {

	if (defined($ARGV[2])) {
		if ($ARGV[2] =~ /^([0-9])+$/) {
			$cfg{'MaximalesAlterInTagen'} = $ARGV[2];
		} else {
			print "Warnung: Parameter n ist ungültig und wird ignoriert. " .
				"(n = " . $cfg{'MaximalesAlterInTagen'} . ")\n";
		}
	}
	
	foreach(&laengerAlsNTageNichtWiederholt($cfg{'MaximalesAlterInTagen'})) {
		print "$_\n";
	}
}


# ----------------------------------------------------------------
# Gibt eine Infoseite über die Benutzung dieses Skripts auf der
# Standardausgabe aus.
#
# Parameter:
#  (Keine)
#
# Rückgabe:
#  (Keine)
#
# Seiteneffekte:
#   Ausgabe der Infoseite auf der Standardausgabe.
# ----------------------------------------------------------------
sub Infoseite {
print <<EDA;
----------------------------------------------------------------------
uv.pl - Hilfsskript für die Auswertung einer OpenOffice.org Calc-Datei
über den Lernfortschritt unregelmäßiger Verben. (Version 2)
Siehe http://es.andreas-klingler.de/?p=1089

GPL 2010/2011 Andreas Marc Klingler <post\@andreas-klingler.de>
----------------------------------------------------------------------

Benutzung: "perl uv.pl <Datei> <Parameter> [<Subparameter>]"
           mit <Parameter> als

 0:     Zeigt alle Vokabeln mit ihrem durchschnittlichen Prozentwert
        an.

 1 [n]: Zeigt alle Vokabeln an, deren letzte Wiederholung
        mehr als n Tage zurückliegt. Wird der Subparameter n nicht
        angegeben, hat er den Wert 14.
      
        Beispiel: "perl uv.pl uv.ods 0 21" gibt alle Vokabeln aus, die seit
        mehr als 21 Tagen nicht wiederholt wurden.

EDA
}

# ----------------------------------------------------------------
# Gibt die Durchschnittsprozentsätze aller UV zurück
#
# Parameter:
#  $_[0]	Tabellenname = Vokabelname
#
# Rückgabe:
#  Array des Typs (UV, Prozentwert)
#
# Seiteneffekte:
#   (Keine)
# ----------------------------------------------------------------
sub Gesamtuebersicht {

	my @r = ();

	my $i = 0;
	while (defined($tab = $uvdok->get_body->get_table_by_position($i))) {
		$i++;

		next if ($tab->get_name eq $cfg{'Vorlagentabellenname'});

		# Berechne den Durchschnittsprozentsatz für diesen Wert.
		local @tmp = ();
		push(@tmp, $tab->get_name);
		push(@tmp, &Durchschnittsprozentsatz($tab->get_name));
		push(@r, \@tmp);
	}
	
	return @r;
}

# ----------------------------------------------------------------
# Berechnt den Durchschnittswert aus allen Prozentwerten eines UV,
# wie gut dieses in den einzelnen Wiederholungen gekonnt wurde.
#
# Parameter:
#  $_[0]	Tabellenname = Vokabelname
#
# Rückgabe:
#  int, Prozentwert
#
# Seiteneffekte:
#   (Keine)
# ----------------------------------------------------------------
sub Durchschnittsprozentsatz {

	# Gewünschte Tabelle holen.
	my $tab = $uvdok->get_body->get_table_by_name($_[0]);

	# Ab der fünften Zeile stehen die Einträge.
	my $i = $cfg{'EintraegeAbZeile'};
	my $summe = 0;
	
	# Alle Zeilen durchgehen, bis das Ende der Einträge erreicht ist.
	while (defined($tab->get_cell_value("B" . $i))) {
		$summe += $tab->get_cell_value("B" . $i);
		$i++;
	}
	$i = $i - $cfg{'EintraegeAbZeile'};

	return $summe * 100 / ($i * 100);
}

# ----------------------------------------------------------------
# Parameter:
#  $_[0]	n (Maximales Alter)
#
# Rückgabe:
#  Datenfeld mit allen Vokabelnamen = Tabellennamen, die seit
#  über $cfg{'MaximalesAlterInTagen'} Tagen nicht wiederholt wurden.
#
# Seiteneffekte:
#   (Keine)
# ----------------------------------------------------------------
sub laengerAlsNTageNichtWiederholt {
	
	my @r = ();

	# Sekunden berechnen der Tage, die die letzte Wiederholung
	#	 maximal zurückliegen soll.	
	# Diese Anzahl Sekunden vom aktuellen Datum abziehen.
	my $Referenzzeit = timelocal(0,0,0,(localtime)[3,4,5]) -
		$_[0] * 24 * 60 * 60;

	my $i = 0;
	while (defined($tab = $uvdok->get_body->get_table_by_position($i))) {
		$i++;
	
		# Ein Eintrag ist "zu alt", wenn er älter ist als dieses
		# berechnete Datum.
		if (&letzteWiederholung($tab) < $Referenzzeit) {
			push(@r, $tab->get_name);
		}
	}
	
	return @r;
}
# ----------------------------------------------------------------


# ----------------------------------------------------------------
# Parameter:
#  $_[0]	Tabellenhandle
#
# Rückgabe:
#  Epochensekunde des Tages der letzten Wiederholung. 
#
# Seiteneffekte:
#   (Keine)
# ----------------------------------------------------------------
sub letzteWiederholung {

	# Ab der fünften Zeile stehen die Einträge.
	my $i = $cfg{'EintraegeAbZeile'};

	# Alle Zeilen durchgehen, bis das Ende der Einträge erreicht ist.
	while (defined($_[0]->get_cell_value("A" . $i))) {
		$i++;
	}
	$i--;

	# $i enthält die Zeilennummer des letzten Datums.
	# Aufsplitten in Array.
	my @d = split(/-/, $_[0]->get_cell_value("A" . $i));
	
	# Datum in Epochensekunden umwandeln und zurückgeben
	return timelocal(0,0,0,$d[2],$d[1]-1,$d[0]-1900);
}
# ----------------------------------------------------------------