#!/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=38076&xmax=38093&ymin=33836&ymax=33865&zoom=16&scale=256&baseurl=http%3A%2F%2Ftile.openstreetmap.org%2F!z%2F!x%2F!y.png

#use strict;

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


@oceantiles = (
"16/38093/33864",
"16/38093/33865");


#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/";
$tileurl = "http://a.tile.openstreetmap.fr/hot/";

#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 = 17;

$tileleft = 76152;
$tiletop = 67672;

#$tileright = 76155;
#$tilebottom = 67675;

$tileright = 76187;
$tilebottom = 67731;

$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();

