#!/usr/bin/env perl
use strict;
# use CGI;
use DBI;
use Geo::IP;

# my ($page);

# Database connection.
my ($dsn)       = "DBI:mysql:database=eprintstats;host=localhost";
my ($user_name) = "eprintstatspriv";
my ($password)  = "AuldGrizzel";
my ( $connect, $query, %types, %unmapped, $stat, $row, $num_rows, $vtype );

# Geolocation database.
my ($gi);
my ($gidb) = '/usr/local/share/GeoIP/GeoLiteCity.dat';

# Miscellaneous variable.
my ( %cities, %IPs );
my ($num_entries) = -1;
my ($num_hits)    = 0;
my ( $ip,  $count, $location );
my ( $lat, $long,  $city, $key ) = ( 0, 0, '', '' );

# $page = new CGI;
# print $page->header( -type => "text/xml", -Pragma => 'no-cache' );
$num_entries = -1;#$page->param('top');

$gi = Geo::IP->open( $gidb, GEOIP_STANDARD )
  or die "Unable to open GeoIP database $gidb\n";

$connect = DBI->connect( $dsn, $user_name, $password, { RaiseError => 1 } );

$types{'download'}    = $types{'abstract'}    = 0;
$unmapped{'download'} = $unmapped{'abstract'} = 0;
$query = "SELECT ip, view_type, COUNT(*) AS count
	 FROM view
	 GROUP BY ip, view_type
	 ORDER BY count DESC" . ( ( $num_entries > 0 ) ? " LIMIT $num_entries" : '' );

$stat = $connect->prepare($query);
$stat->execute();
$num_rows = $stat->rows;

if ( $num_rows > 0 )
{
	$num_entries = $num_rows if ( $num_entries < 1 );

	while ( $row = $stat->fetchrow_hashref() )
	{
		$ip    = $row->{'ip'};
		$count = $row->{'count'};
		$vtype = $row->{'view_type'};

		$IPs{$ip} = 1;

		$location = $gi->record_by_addr($ip);

		if ( defined($location) )
		{
			$lat  = $location->latitude;
			$long = $location->longitude;
			$city = (
					  ( $location->city eq '' )
					  ? 'Unknown'
					  : $location->city
			);
			$key  = $city . " ($lat, $long)";

			if ( !defined( $cities{$key} ) )
			{
				$cities{$key}{'name'}     = $city;
				$cities{$key}{'lat'}      = $lat;
				$cities{$key}{'long'}     = $long;
				$cities{$key}{'abstract'} = 0;
				$cities{$key}{'download'} = 0;
			}
			$cities{$key}{$vtype} += $count;
			$types{$vtype}        += $count;
		}
		else
		{
			$unmapped{$vtype} += $count;
		}
	}

	# Need to wait until we have all the counts before writing the data out.
	print '<?xml version="1.0"?>' . "\n";
	print '<kml xmlns="http://earth.google.com/kml/2.0">' . "\n";
	print "<Document>\n<description>lotsa points</description>\n<name>Hits</name>\n";

	foreach $city ( keys %cities )
	{
		my ($maxcolor) = $cities{$city}{'download'} + $cities{$city}{'abstract'};
		my ($red)      = round($cities{$city}{'download'} / $maxcolor * 255);
		my ($blue)     = round($cities{$city}{'abstract'} / $maxcolor * 255);
		print '<Placemark>
		  <description><![CDATA[<span style="color:red;">'
		  . $cities{$city}{'download'}
		  . ' downloads</span>, <span style="color:blue;">'
		  . $cities{$city}{'abstract'}
		  . ' abstracts</span>]]>
		  </description>
		  <name>'
		  . $cities{$city}{'name'}
		  . '</name>
		  <Style>
		  <IconStyle>
          <color>'
		  . sprintf( 'c0%02x00%02x', $blue, $red )
          . '</color>
          <Icon>
          <href>root://icons/palette-4.png</href>
		  <x>96</x>
		  <y>128</y>
		  <w>32</w>
		  <h>32</h>
		  </Icon>
		  </IconStyle>
		  </Style>
		  <LookAt>
		  <longitude>'
		  . $cities{$city}{'long'}
		  . '</longitude>
		  <latitude>'
		  . $cities{$city}{'lat'}
		  . '</latitude>
		  <range>540.68</range>
		  <tilt>0</tilt>
		  <heading>3</heading>
		  </LookAt>
		  <Point>
		  <coordinates>'
		  . $cities{$city}{'long'} . ','
		  . $cities{$city}{'lat'}
		  . ',0</coordinates>
		  </Point>
		  </Placemark>' . "\n";
	}

	print "</Document>\n</kml>\n";
}

$stat->finish();
$connect->disconnect();

sub round
{
	my ($n) = shift;
	return int( $n + 0.5 * ( $n <=> 0 ) );
}
