#!/usr/bin/perl -w

use strict;
use Cwd;
use File::Find;

my $noop;

if( @ARGV && $ARGV[0] eq "-n" ) {
    $noop= 1;
    shift @ARGV;
}

die "Usage: osmgettile.pl [ -n ] <base directory> <zoom> <x> <y>\n"
    if @ARGV != 4 || $ARGV[0] =~ /^--?h(?:elp)?$/i;

my ($basedir, $wantz, $wantx, $wanty)= @ARGV;


my ($tilefile, $metamul, $metamulerr);

sub setmetamul
{
    my $file= $_;

    return unless -f $file;
    if( !open( IN, "<$file" ) ) {
        $metamulerr= "Could not open $file for reading: $!\n";
        die;
    }
    local $/= 20;
    $_= <IN>;
    close IN;
    my ($magic, $ntiles)= unpack("a4L", $_);
    $metamulerr= "Magic mismatch in $file:  " . join(" ", map ord($_), split //, $magic) . "\n"
        unless $magic eq "META";
    $metamul= int(sqrt($ntiles));
    $metamulerr= "Tile count $ntiles in $file is not a square!\n"
        unless $ntiles == $metamul*$metamul;
    $tilefile= $File::Find::name;
    die;
}

eval { find( { wanted => \&setmetamul, no_chdir => 1 }, $basedir ); };

die $metamulerr if defined $metamulerr;

my $tiledir= substr($tilefile, length($basedir)+1);
$tiledir =~ s!/[^/]*$!!;

my $dirhash= $tiledir =~ tr!/!/! > 2;

my $metamask= $metamul - 1;

my $metaindex= ($wantx & $metamask) * $metamul + ($wanty & $metamask);
$wantx= $wantx & ~$metamask;
$wanty= $wanty & ~$metamask;

my $optstr= $tilefile =~ /(\.[^\.\/]+)\.meta$/i ? $1 : "";
my $wantpath= "$optstr.meta";

if( $dirhash ) {
    for (0..4) {
        $wantpath= "/" . (($wantx & 15) * 16 + ($wanty & 15)) . $wantpath;
        $wantx >>= 4;
        $wanty >>= 4;
    }
    $wantpath= $wantz . $wantpath;
}
else {
    $wantpath= "$wantz/$wantx/$wanty$wantpath";
}

$wantpath= "$basedir/$wantpath";

print "Meta multiplier is $metamul, dir hashing is ", ($dirhash? "on":"off"), ", option string is \`$optstr'\n";
print "Tile is nr. $metaindex in $wantpath\n";

exit if $noop;

my $data;

{
    open IN, "<$wantpath" or die "Could not open $wantpath for reading: $!";
    my $readsize= 20 + $metaindex * 8;
    local $/= \$readsize;
    $_= <IN>;
    $readsize= 8;
    $_= <IN>;
    my ($offset, $size)= unpack("L2", $_);
    $readsize= $offset - 20 - ($metaindex+1) * 8;
    $_= <IN>;
    $readsize= $size;
    $data= <IN>;
    close IN;
}

my $outname= "$wantz-$wantx-$wanty.png";
open OUT, ">$outname" or die "Could not create $outname: $!";
print OUT $data;
close OUT;

