#!/usr/bin/perl -w
use strict;

use CGI;
use CGI::Carp qw{fatalsToBrowser set_message};
BEGIN{ set_message("Sorry, an error has occurred. Can't help you"); }

use GD;

my ($img,$wdt,$hgt);

my $fontw=gdLargeFont->width;
my $fonth=gdLargeFont->height;

my @colours=('red','green','blue','yellow',
             'orange','purple','magenta','cyan');
my %coloursRGB = (
    'red'      => [255,0,0],
    'green'    => [0,255,0],
    'blue'     => [0,0,255],
    'yellow'   => [255,255,0],
    'magenta'  => [255,0,255],
    'cyan'     => [0,255,255],
    'purple'   => [128,0,128],
    'orange'   => [255,128,0],
);
my %colour;

sub colours {
	return @colours;
}

sub fill{
 my ($hashref)=@_;
 local $/="###\n";
 open(DATA,"data") or die("Oops... $!\n");
 while (<DATA>) {
  chomp;
  my ($id, $title, $year, $coords) = split "\n", $_, 4;
  my @coords = map {[split ","]} ($coords =~ /\[(.+?)\]/g);
  $hashref->{$id} = { title => $title, year => $year,
                      coords => \@coords};
 }
}

# Subroutine to draw the map:

sub draw_map {
 my ($books,$size,$labels)=@_;
 open_image($size);
 ($wdt, $hgt) = $img->getBounds();

 foreach my $book (keys %$books) {
  my $colname = $books->{$book}{colour};
  next unless exists $colour{$colname};

  my @old;
  foreach my $place (@{$books->{$book}{coords}}) {
# Draw line from previous point
   my @x = coords(@$place);
   draw_line(@old, @x, $colname) if @old;
# Put label
   my $label=$place->[2];
   if(defined $label and $labels==1){
    my ($label,$align)=split '_',$label;
    $align='l' unless defined $align;
    my ($xpos,$ypos)=labelpos(@x,$align,length($label));
    $img->string(gdLargeFont,$xpos,$ypos,$label,$colour{$colname});
   }
# Draw circle
   my $diam = $place->[3];
   if(defined $diam){
    $img->arc(@x, $diam,$diam, 0,360, $colour{dummy});
    $img->fillToBorder(@x, $colour{dummy}, $colour{$colname}) if $diam;
    $img->arc(@x, $diam,$diam, 0,360, $colour{$colname});
   }
   @old = @x;
  }
 }
 print $img->gif;
}

sub open_image{
 my ($size)=@_;
 if($size eq 'small'){
  open GIF, 'small.gif';
  $img = GD::Image->newFromGif(*GIF);
  close GIF;
 }
 elsif($size eq 'medium'){
  open GIF, 'medium.gif';
  $img = GD::Image->newFromGif(*GIF);
  close GIF;
 }
 elsif($size eq 'large'){
  open GIF, 'large.gif';
  $img = GD::Image->newFromGif(*GIF);
  close GIF;
 }
 else{
  open GIF, 'medium.gif';
  $img = GD::Image->newFromGif(*GIF);
  close GIF;
 }
 $colour{white} = $img->colorAllocate(255,255,255);
 $colour{dummy} = $img->colorAllocate(1,0,0);
 $colour{$_} = $img->colorAllocate(@{$coloursRGB{$_}})
  foreach keys %coloursRGB;
}

sub coords {
 my ($lat, $lon) = @_;
 return (($lon+180)/360*$wdt,(90-$lat)/180*$hgt);
}

sub draw_line {
 my ($x1, $y1, $x2, $y2, $colname) = @_;
 if($x1-$x2 > $wdt/2){
# Crossing 180 deg longitude in eastward direction
  $img->line($x1, $y1, $x2+$wdt, $y2, $colour{$colname});
  $img->line($x1-$wdt, $y1, $x2, $y2, $colour{$colname});
 }
 elsif($x1-$x2 < -$wdt/2){
# Crossing 180 deg longitude in westward direction
  $img->line($x1, $y1, $x2-$wdt, $y2, $colour{$colname});
  $img->line($x1+$wdt, $y1, $x2, $y2, $colour{$colname});
 }
 else{
  $img->line($x1, $y1, $x2, $y2, $colour{$colname});
 }
}

sub labelpos{
 my ($x,$y,$align,$l)=@_;
 my ($xpos,$ypos)=($x,$y);
 if($align=~/r/){
  $xpos+=$fontw/2;
  $ypos-=$fonth/2 unless $align=~/[tb]/;
 }
 if($align=~/l/){
  $xpos-=($l+0.5)*$fontw;
  $ypos-=$fonth/2 unless $align=~/[tb]/;
 }
 if($align=~/t/){
  $xpos-=$l*$fontw/2 unless $align=~/[rl]/;
  $ypos-=$fonth;
 }
 if($align=~/b/){
  $xpos-=$l*$fontw/2 unless $align=~/[rl]/;
 }
 unless($align=~/[lrtb]/){
  $xpos+=$fontw/2;
  $ypos-=$fonth/2;
 }
 return ($xpos,$ypos);
}

1;

