#!/usr/bin/perl

# Copyright (C) 2010 Thorsten Kukuk
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# in Version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA  02110-1301, USA.


=head1 NAME

gpx2sms - GPX to short text converter

=head1 SYNOPSIS

gpx2sms [options] [<gpx-file> ...]

=head1 DESCRIPTION

gpx2sms creates a very short summary of a Cache including the
GC number, cache name, owner, difficulty, terrain, type, size,
owner, decoded hint (if shorter than 80 characters) and optional
attributes to be used as short message to be send to your
mobile phone.

=head1 OPTIONS

  -a             Add Attributes
  -d <distance>  Add distance <distance> to coordinates
  -s             Very short message
  -h|-?          Help

=cut

use strict;
use warnings;
use Pod::Usage;
use XML::Twig;
use GEO::Coords;

my $Version = '(geo-tools) 1.23';

#
# process command line arguments
#
use Getopt::Long;
my $attr = 0;
my $distance;
my $short = 0;
my $help = 0;
my $man = 0;
my $version = 0;
my $usage = 0;

my %html2utf8 = ('&amp;auml;' => "ä",
                 '&amp;Auml;' => "Ä",
                 '&amp;ouml;' => "ö",
                 '&amp;Ouml;' => "Ö",
                 '&amp;uuml;' => "ü",
                 '&amp;Uuml;' => "Ü",
                 '&amp;szlig;' => "ß",
                 '&amp;bdquo;' => "„",
                 '&amp;ldquo;' => "“",
                 '&amp;rdquo;' => "”",
                 '&amp;ndash;' => "–",
		 '&amp;nbsp;' => " ",
		 '&amp;' => "&"
                );
my $regex = qr/${ \(join'|', map quotemeta, keys %html2utf8)}/;

GetOptions('a|attr' => \$attr,
	   'd|distance=s' => \$distance,
	   's|short' => \$short,
	   'version' => \$version,
	   'man' => \$man,
	   'u|usage' => \$usage,
	   'help|h|?' => \$help) or pod2usage(2);
pod2usage(0) if $help;
pod2usage(-exitstatus => 0, -verbose => 2) if $man;
pod2usage(-exitstatus => 0, -verbose => 0) if $usage;

if ($version) {
  print "gpx2sms $Version\n";
  exit;
}

my @InputFiles;
if ($#ARGV >= 0) {
   @InputFiles = (@ARGV);
}
else {
  usage();
}

my $Parser =
  new XML::Twig(twig_handlers=>{'gpx/wpt/groundspeak:cache' => \&GetGCCache,
				'gpx/wpt/extensions/cache' => \&GetOCCache},
		keep_encoding => 1);

foreach my $InputFileName (@InputFiles) {
   $Parser->parsefile($InputFileName);
   $Parser->purge;
}

exit;

sub print_cache
{
  my ($ID, $Name, $Latitude, $Longitude, $Difficulty, $Terrain, $Type, $Size, $Owner, $Hint, $attrs) = @_;

  $Name =~ s/($regex)/$html2utf8{$1}/g;
  $Owner =~ s/($regex)/$html2utf8{$1}/g;

  print "$ID: $Name ($Difficulty/$Terrain)\n";
  if ($short) {
    GEO::Coords::print_mindec($Latitude, $Longitude, 1);
    print "$distance\n" if ($distance);
    print "$Type/$Size\n";
    print "$Owner\n";
  } else {
    print "Koord: ";
    GEO::Coords::print_mindec($Latitude, $Longitude, 1);
    print "Distance: $distance\n" if ($distance);
    print "Type: $Type\n";
    print "Size: $Size\n";
    print "Owner: $Owner\n";
  }
  if ($attr && $attrs) {
    my $i = 0;
    foreach my $attr ($attrs->children('groundspeak:attribute')) {
      my $Text = $attr->text;

      if ($i++ != 0) {
	print ", ";
      } else {
	if (!$short) {
	  print "Attributes: ";
	}
      }
      if ($attr->{'att'}->{'inc'}) {
	print "$Text";
      } else {
	print "!$Text";
      }
    }
    if ($i != 0) {
      print ".\n";
    }
  }
  if (length($Hint) > 0 && length($Hint) < 80) {
    print "Decoded Hint:\n";
    print "$Hint\n";
  }
}


sub GetGCCache
{
  my ($t, $cache) = @_;
  my $wpt = $cache->parent('wpt');
  my $attrs = $cache->first_child('groundspeak:attributes');
  my $ID = $wpt->first_child_text('name');
  my $Name = $cache->first_child_text('groundspeak:name');
  my $Latitude = $wpt->{'att'}->{'lat'};
  my $Longitude = $wpt->{'att'}->{'lon'};
  my $Difficulty = $cache->first_child_text('groundspeak:difficulty');
  my $Terrain = $cache->first_child_text('groundspeak:terrain');
  my $Type = $cache->first_child_text('groundspeak:type');
  my $Size = $cache->first_child_text('groundspeak:container');
  my $Owner = $cache->first_child_text('groundspeak:placed_by');
  my $Hint = $cache->first_child_text('groundspeak:encoded_hints');

  print_cache($ID, $Name, $Latitude, $Longitude, $Difficulty, $Terrain, $Type, $Size, $Owner, $Hint, $attrs);
}

sub GetOCCache
{
  my ($t, $cache) = @_;
  my $wpt = $cache->parent('wpt');
  my $ID = $wpt->first_child_text('name');
  my $Name = $cache->first_child_text('name');
  my $Latitude = $wpt->{'att'}->{'lat'};
  my $Longitude = $wpt->{'att'}->{'lon'};
  my $Difficulty = $cache->first_child_text('difficulty');
  my $Terrain = $cache->first_child_text('terrain');
  my $Type = $cache->first_child_text('type');
  my $Size = $cache->first_child_text('container');
  my $Owner = $cache->first_child_text('owner');
  my $Hint = $cache->first_child_text('encoded_hints');

  print_cache($ID, $Name, $Latitude, $Longitude, $Difficulty, $Terrain, $Type, $Size, $Owner, $Hint);
}
