#!/usr/bin/perl

# Modified from a script generated from http://openstreetmap.gryph.de/bigmap.cgi/
# permalink for this map: http://openstreetmap.gryph.de/bigmap.cgi?xmin=604&xmax=631&ymin=1216&ymax=1255&zoom=11&scale=256&baseurl=http%3A%2F%2Ftile.openstreetmap.org%2Fmapnik

#use strict;

use LWP;
use GD;
use Time::Local;


@oceantiles = (
"15/32112/20802",
"15/32100/20805",    
"15/32101/20806",
"15/32102/20804",        
"15/32104/20805",
"15/32105/20779",
"15/32105/20780",
"15/32105/20781",
"15/32105/20782",
"15/32106/20779",
"15/32106/20780",
"15/32106/20781",
"15/32106/20782",
"15/32106/20783",
"15/32106/20784",
"15/32106/20785",
"15/32106/20786",
"15/32106/20787",
"15/32106/20788",
"15/32106/20795",
"15/32107/20779",
"15/32107/20780",
"15/32107/20781",
"15/32107/20782",
"15/32107/20783",
"15/32107/20784",
"15/32107/20785",
"15/32107/20786",
"15/32107/20787",
"15/32107/20788",
"15/32107/20789",
"15/32107/20790",
"15/32107/20791",
"15/32107/20804",
"15/32108/20779",
"15/32108/20780",
"15/32108/20781",
"15/32108/20782",
"15/32108/20783",
"15/32108/20784",
"15/32108/20785",
"15/32108/20786",
"15/32108/20787",
"15/32108/20788",
"15/32108/20789",
"15/32108/20790",
"15/32108/20791",
"15/32108/20792",
"15/32108/20793",
"15/32108/20794",
"15/32108/20803",
"15/32109/20779",
"15/32109/20780",
"15/32109/20781",
"15/32109/20782",
"15/32109/20783",
"15/32109/20784",
"15/32109/20785",
"15/32109/20786",
"15/32109/20787",
"15/32109/20788",
"15/32109/20789",
"15/32109/20790",
"15/32109/20791",
"15/32109/20792",
"15/32109/20793",
"15/32109/20794",
"15/32109/20795",
"15/32109/20796",
"15/32109/20797",
"15/32109/20803",
"15/32110/20779",
"15/32110/20780",
"15/32110/20781",
"15/32110/20782",
"15/32110/20783",
"15/32110/20784",
"15/32110/20785",
"15/32110/20786",
"15/32110/20787",
"15/32110/20788",
"15/32110/20789",
"15/32110/20790",
"15/32110/20791",
"15/32110/20792",
"15/32110/20793",
"15/32110/20794",
"15/32110/20795",
"15/32110/20796",
"15/32110/20797",
"15/32110/20803",
"15/32111/20779",
"15/32111/20780",
"15/32111/20781",
"15/32111/20782",
"15/32111/20783",
"15/32111/20784",
"15/32111/20785",
"15/32111/20786",
"15/32111/20787",
"15/32111/20788",
"15/32111/20789",
"15/32111/20790",
"15/32111/20791",
"15/32111/20792",
"15/32111/20793",
"15/32111/20794",
"15/32111/20795",
"15/32111/20796",
"15/32111/20797",
"15/32111/20798",
"15/32111/20799",
"15/32111/20802",
"15/32111/20803",
"15/32112/20779",
"15/32112/20780",
"15/32112/20781",
"15/32112/20782",
"15/32112/20783",
"15/32112/20784",
"15/32112/20785",
"15/32112/20786",
"15/32112/20787",
"15/32112/20788",
"15/32112/20789",
"15/32112/20790",
"15/32112/20791",
"15/32112/20792",
"15/32112/20793",
"15/32112/20794",
"15/32112/20795",
"15/32112/20796",
"15/32112/20797",
"15/32112/20798",
"15/32112/20799");


#OK there *has* to be an easier way of doing this
@months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
@weekDays = qw(Sun Mon Tue Wed Thu Fri Sat Sun);
($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime();
$year = 1900 + $yearOffset;
$theTime = "$hour:$minute:$second, $weekDays[$dayOfWeek] $months[$month] $dayOfMonth, $year";

print STDERR "Running BigMapMod at ", $theTime, "\n";

#defaults
$labelfilename = "label.gif";
$tileurl = "http://tile.openstreetmap.org/";

#get command line args
foreach $argnum (0 .. $#ARGV) {
    $labelfilename=$ARGV[$argnum+1] if ($ARGV[$argnum] eq "--labelfile");
    $tileurl      =$ARGV[$argnum+1] if ($ARGV[$argnum] eq "--tileurl");
}

$sleepevery = 8; #Sleep every 8 tiles
$zoom = 15;

$tileleft = 32078;
$tiletop = 20779;

$tileright = 32112;
$tilebottom = 20806;

$tilesacross = $tileright - $tileleft + 1; 
$tilesdown = $tilebottom - $tiletop + 1;

$totaltiles  = $tilesacross * $tilesdown;

$imgwidth = $tilesacross * 256;
$imgheight = $tilesdown * 256;

print STDERR "Total tiles: " . $totaltiles . "\n";
print STDERR "Image size : " . $imgwidth . "x" .  $imgheight . "\n";
sleep(3); 



#prepare big image
my $img = GD::Image->new($imgwidth, $imgheight, 1);
my $white = $img->colorAllocate(248,248,248);
my $ocean = $img->colorAllocate(181,208,208);
$img->filledRectangle(0,0,$imgwidth,$imgheight,$ocean);

#prepare HTTP user agent
my $ua = LWP::UserAgent->new();
$ua->agent("BigMapMod_harrywood");
$ua->env_proxy;

print STDERR "Commencing tile fetch & stitch. tileurl='", $tileurl, "'\n";

$count = 0;
for (my $x=0;$x<$tilesacross;$x++)
{
    for (my $y=0;$y<$tilesdown;$y++)
    {
       
        $xt = $x + $tileleft;
        $yt = $y + $tiletop;
        
        $tilecoords = $zoom . "/" . $xt . "/" . $yt;
        $url = $tileurl. $tilecoords . ".png";
        
        
        
        if ( grep { $_ eq $tilecoords} @oceantiles ) {
           #print STDERR $count . " Skipping ocean tile " .  $url . "\n";
           
        } else {

           $count++;
           
           if ($count % $sleepevery ==0) {
               #print STDERR "sleeping\n";
               sleep(3); 
           }
        
           $url = sprintf("%s%d/%d/%d.png",$tileurl, $zoom, $xt,$yt);
           $localfile = sprintf("./tiles/tile_%d_%d_%d.png", $zoom, $xt,$yt);
           
           my $resp = $ua->mirror( $url, $localfile ); #fetch the tile to a local file if the local file is old
           
           if (!$resp->is_success) {
              if ($resp->code==304) {
                  #not modified error. That's ok
              } else {
                 die $resp->status_line
              }
           }
 
           open(PNG, $localfile) || die;
           my $tile = newFromPng GD::Image(PNG) || die "failed to create GD image for ". $localfile;
           
           #Old direct request logic
           #$tilesize = length($resp->content);
           #my $tile = GD::Image->new($resp->content);
           
           $tilesize = -s $localfile;

           #print STDERR $count . " Got " .  $url . " local file:". $localfile . " size:" . $tilesize . "\n";
           
           next if ($tile->width == 1);
           
           #figure out if it's an empty ocean tile despite above checks
           if ($tilesize==103) {
              #tile is empty. find the colour
              $colindex = $tile->getPixel(128,128);
              ($r,$g,$b) = $tile->rgb($colindex);
              if ($b==208) {
                 print STDERR $count . " Fetched an empty ocean tile: " .  $url . " (blue level:" . $b . ")\n";
              }
           }
           
           $img->copy($tile, $x*256,$y*256,0,0,256,256); #place the tile image within the big image
        } #endif
        
    }
    
}

print STDERR "Done building map. " . $count . " tiles fetched\n";

print STDERR "Adding lable from file '", $labelfilename , "'\n";

open(GIF, $labelfilename) || die;
my $labelimg = newFromGif GD::Image(GIF) || die;
$img->copy($labelimg, 10,10,0,0,651,100);
close GIF;

print STDERR "Done. Printing png to STDOUT\n";

binmode STDOUT;
print $img->png();
