#!/usr/bin/perl
# 
# Copyright (c) 2006 Nick Burch
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Generate the "whole of the UK" thumbnail from lots of files in scaled50

use List::Util qw[min max];
use Image::Magick;
use POSIX qw[ceil];
use strict;

my $tilesize = 125;

my $inscale = 50;
my $outscale = 125;

# Find these values by hand using the gimp or similar
#  lower easting,northing
my @bl_trims = qw( 77, 0 );
#  upper easting,northing
my @tr_trims = qw( 657, 1057 );

# which files to build it from
my @files = glob("scaled${inscale}/???/???.jpg");
my %tiles ;

my ($minx, $miny, $maxx, $maxy);

foreach my $f (@files) {
  if($f =~ /\/(\d+)\/(\d+)\./) {
     my ($x, $y) = ($1 +0, $2 +0);
     $tiles{$x} ||= {};
     $tiles{$x}{$y} = $f;
  }
}

# Ensure it starts at 0,0
# (Otherwise, deciding where you clicked on is too hard)
$maxx = max(keys %tiles) + 1;
$maxy = max(map { max(keys %{$tiles{$_}})} keys %tiles) + 1;

# Ensure it's always big enough for our trims not to confuse things
$maxx = max($maxx, ceil($tr_trims[0]/$inscale));
$maxy = max($maxy, ceil($tr_trims[1]/$inscale));

# Decide how big our intermediate, and final images will be
my $temp_x = $maxx * $tilesize;
my $temp_y = $maxy * $tilesize;

my $out_x = int($maxx * $tilesize * $inscale / $outscale); 
my $out_y = int($maxy * $tilesize * $inscale / $outscale);

my $trim_width = $tr_trims[0] - $bl_trims[0];
my $trim_height = $tr_trims[1] - $bl_trims[1];

print "There are $maxx images across, and $maxy images down\n";
print "The temp image will be $temp_x x $temp_y\n";
print "The joined image will be $out_x x $out_y\n";
print "The final image will be $trim_width x $trim_height\n\n";


# Render the larger image, where we just include all the scaled images
my $out = Image::Magick->new(size => $temp_x."x".$temp_y);
$out ->ReadImage('xc:white');

foreach my $x (0..($maxx)) {
	foreach my $y (0..($maxy)) {
		my $input = $tiles{$x}{$y};
		if(-f $input) {
			print "Including $input\n";
			my $image = Image::Magick->new;
            print $image->Read($input);

			# x goes from 0 to n
			my $this_x = $x * $tilesize;
			# y goes from 0 to n
			my $this_y = $temp_y - (($y+1) * $tilesize);
			print "   goes at $this_x , $this_y\n";

            print $out->Composite(image=>$image, x=>$this_x, y=>$this_y);
            undef $image;
        }
     }
}

# Now resize it
$out->Resize("${out_x}x${out_y}");
# And make it a bit darker, so it's easier to see
$out->Tint(fill=>"white", opacity=>65);

# Write this out as a temp file
$out->Set(quality=>100);
$out->Write("jpg:/tmp/thumbnail.jpg");


# Produce the large image - crop left, right and bottom
$out->Crop( x=>$bl_trims[0], y=>0,
            width=>($tr_trims[0] - $bl_trims[0]),
            height=>$out_y );
$out->Set(quality=>85);
$out->Write("jpg:thumbnail.jpg");
print "\nOutput thumbnail.jpg at ${trim_width}x${out_y}\n";


# Now do the smaller image - crop all 4
$out = Image::Magick->new;
$out->Read("/tmp/thumbnail.jpg");

# And trim the edges off it
$out->Crop( x=>$bl_trims[0], y=>($out_y - $tr_trims[1]),
            width=>($tr_trims[0] - $bl_trims[0]),
            height=>($tr_trims[1] - $bl_trims[1]) );

# And do half size
($trim_width,$trim_height) = (int($trim_width/2),int($trim_height/2));
$out->Resize("${trim_width}x${trim_height}");

# Finally, write it out
$out->Set(quality=>85);
$out->Write("jpg:thumbnailsmall.jpg");
undef $out;

print "\nOutput thumbnailsmall.jpg at ${trim_width}x${trim_height}\n";
print "($maxx,$maxy)\n";
