#!/usr/bin/env perl

use POSIX;
use locale;
#use Data::Dumper;
use Getopt::Long;
use Locale::TextDomain 'net.suteren.POI.ttn2device';
use Pod::Usage;
use Config::General;
use File::Basename;
use File::Copy;
use Geo::Ov2;

our $VERSION = '0.09';

=head1 NAME

{progname} - recategorizes POIs by config, writes poi.dat and add area structurre to ov2 files.

=head1 SYNOPSIS

{progname} [--configfile=filename|-c filename] [sourceDir [destDir]]

{progname} --help|-h


=head1 DESCRIPTION

{progname} can merge ov2 files from srcDir into destDir and write poi.dat against definition in config file.
configfile has to be in "./", "./etc/", "../etc/", "/etc/", "/etc/POI/", "/etc/POIs/", "/etc/local/POI/" or "/usr/local/etc/POI/" and has to be named "catgroup.conf", "catgroup.cfg", "catgroup_rc" or "catgroup".
Or it can by directly specified on command line.

=head2 Syntax of config file

	<_DEFAULT_>
		srcDir=/home/public/POI/data
		destDir=/home/public/POI/todevice
	</_DEFAULT_>

	<category Parkoviste_pujcovny.ov2>
		id=9930
		filename=Rent Car Parking.ov2
	</category>

	<category GeoCaching.ov2>
		filename=CZ-Geocaching-multi.ov2
		filename=CZ-Geocaching-mystery.ov2
		filename=CZ-Geocaching-traditional.ov2
		filename=CZ-Geocaching-virtual.ov2
		filename=CZ-Geocaching-webcam.ov2
		icon=/somepath/somefile.bmp
	</category>



=head1 OPTIONS

=over

=item --help|-h

Display this help message.

=item --quiet|-q

Suppress output messages. If used more than once, output will be more quiet.

=item --verbose|-v

Display extra runtime informations.

=item --configfile=path_and_filename|-a path_and_filename

Using of specified config file.

=back

config: {configfile}

=head1 SEE ALSO

L<Pod::Usage>, L<pod2usage(1)>, L<Geo::Ov2>

=head1 BUGS

=head1 TODO

Do some checking for correct syntax and feedback to user.

=over

=item
Translation of help message is dependent on pod2usage implementation. If help message is not displayed in expected language, you can check net.suteren.POI.ttn2device for corresponding message

=back

=cut


my $helptext;
my $debug = 0;

sub printhelp {
	pipe Reader, Writer;
	pod2usage( -exitval => NOEXIT, -output => \*Writer );
	close Writer;
	$message = "";
	while ( <Reader> ) {
		$message .=  __$_;
	}
	close Reader;
	open X, ">x.hlp";
	print X $message;
	close X;
	print __x($message, progname => basename( $0 ), configfile => $configfile );
}

my $help;
my $verbose;
my $quiet;
my @quiet;
my $extraquiet;
$configfile;
$bufflen = 64*8*1024;
@configfiles = ( "ov2ssentry.conf", "ov2ssentry.cfg", "ov2ssentry_rc", "ov2ssentry" );
@configdirs = ( "./", "./etc/", "../etc/", "/etc/", "/etc/POI/", "/etc/POIs/", "/etc/local/POI/", "/usr/local/etc/POI/" );

outer:
foreach $i ( @configdirs ) {
	foreach $j ( @configfiles ) {
		if ( -f "$i$j" && -r "$i$j" ) {
			$configfile = "$i$j";
			last outer;
		}
	}
}


unless ( GetOptions ( "help" => \$help, "configfile=s" => \$configfile, verbose => \$verbose, quiet => \@quiet ) ) {
	&printhelp();
	die __"Bad options.";
}

$quiet = 1 if @quiet > 0;
$extraquiet = 1 if @quiet > 1;

printf STDERR  "config: %s\n", $configfile if $verbose;

if ( $help ) {
	&printhelp();
	exit 0;
}

my $srcDir = shift;
my $destDir = shift;

$conf = new Config::General( -ConfigFile => $configfile, -InterPolateVars => 1);
my %conf = $conf->getall();
$srcDir = $conf{_DEFAULT_}{srcDir} unless $srcDir;
$destDir = $conf{_DEFAULT_}{destDir} unless $destDir;

$srcDir = "$srcDir/" if substr ( $srcDir, length ( $srcDir ) - 1 ) ne "/";
$destDir = "$destDir/" if substr ( $destDir, length ( $destDir ) - 1 ) ne "/";

my %conf_categories = %{$conf{category}};

my %poidat;
my @sources;
my $cntr=0;

foreach $category ( keys %conf_categories ){
	printf STDERR N__"cat: %s\n", $category unless $quiet;
	my %category = %{$conf_categories{$category}};
	my $regexp = $conf_categories{$category}{regexp}{pattern};
	$regexp = $conf{_DEFAULT_}{regexp}{pattern} unless $regexp;
	my $speedorder = $conf_categories{$category}{regexp}{speedorder};
	$speedorder = $conf{_DEFAULT_}{regexp}{speedorder} unless $speedorder;
	my $idorder = $conf_categories{$category}{regexp}{idorder};
	$idorder = $conf{_DEFAULT_}{regexp}{idorder} unless $typeorder;
	my $typeorder = $conf_categories{$category}{regexp}{typeorder};
	$typeorder = $conf{_DEFAULT_}{regexp}{typeorder} unless $typeorder;
	my $types = $conf_categories{$category}{regexp}{types};
	my $types = $conf{_DEFAULT_}{regexp}{types};
	my %types = %$types;
	chomp $category;
	chomp $regexp;
	chomp $speedorder;
	chomp $typeorder;


	my $fdto = "$destDir/$category";
	my @files = @{$conf_categories{$category}{filename}};
	@files = ( $conf_categories{$category}{filename} ) unless @files;
	my $ts=0;
	my @pois;
	foreach my $file (@files) {
		chomp $file;
		printf STDERR N__"src: %s", $file unless $quiet;
		my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("$srcDir/$file");
		$ts = $mtime if $mtime > $ts;
		my $fdfrom = "$srcDir/$file";
		my $ov2from = Geo::Ov2->new( "<$fdfrom" );
		unless ( $ov2from ) {
			next;
			printf STDERR N__"ERR: unable to read %s\n", $fdfrom unless $extraquiet;
		}
		my $poisfrom = $ov2from->poireadall();
		my @poisfrom = @$poisfrom;
		foreach $i ( @poisfrom ) {
			my %poi = %$i;
			my $longitude = $poi{longitude} / 100000;
			my $latitude = $poi{latitude} / 100000;
			my $description = $poi{description};
			$description =~ m/$regexp/;
			my @result = ( $1, $2, $3, $4, $5, $6, $7, $8, $9 );
			my $limit = $result[$speedorder - 1];
			my $id = $result[$idorder - 1];
			$id =~ s/^\s*//g;
			$id =~ s/\s*$//g;
			$id =~ s/\000*//g;
			$id = undef; # Nowadays GPS Speed Sentry supports only numeric ID - co setting to $cntr value
			$id = $cntr++ unless $id;
			my $type = $result[$typeorder - 1];
			#printf "D: %s\n", $description unless $types{$type};
			$type = $types{$type};
			$type = $category unless $type;
			printf "%f,%f,\"%s:%d@%d\"\r\n", $longitude, $latitude, $type, $id, $limit;
		}
		push @sources, $file;
		push @pois, @poisfrom;
		$ov2from->close();
		printf STDERR N__" (%d)\n", $#poisfrom unless $quiet;
	}
	printf STDERR __n("written: %d record\n", "written: %d records\n"), $#pois if $verbose;
	utime $ts, $ts, "$destDir/$category";

	my $iconfile = $conf_categories{$category}{icon};
	$catname = fileparse( $category, ".ov2" );
	$iconfile = "$srcDir/$catname.bmp" unless $iconfile;
	my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat("$iconfile");
	copy("$iconfile","$destDir/$catname.bmp");
	utime $atime, $mtime, "$destDir/$catname.bmp";
}

my $ts=0;
