#!/usr/bin/perl -w

use File::Copy qw/copy move/;
use Digest::file qw/digest_file_hex/;

$moveinsteadofcopy = 0;
$noreplace = 0;
$skipvoidtiles = 0;
$verblev = 2;

@voidtilesizes = ( 334, 854 );
@voidtilehashes = (
                    '1cf52aed67c3ebf045f2fd2996ada35545517129e673dba00ef97c7d18275f144aa67b012556ec8a840fca158f6976e7cf30fcae030acd493e26e28fdff10ca3',
                    '1feba96da5f6fa6049d7b40dc72295058eabb7e771040dedc8a69527046aa34fdaaf98e676ed8d02e95770dc635b5d4bf292fdd19be3c381847d3883995d3f3f',
                    '609e45a0c39d961302ed560d9d8bffd798fdbcc912c3875c06ba1faa1fab83cce8d97f257d572138898d2d99fb5a7af80801080bb7be9688e029fce4a9c56f5f'
                  );

# Par. 0: Level on which this gets printed
# Par. 1: Text
sub printlev($$) {
  if ($verblev >= $_[0]) {
    print($_[1]);
  }
}

sub showhelpandexit() {
  print("Syntax: $0 sourcedirectoy destinationdirectory\n");
  exit(1);
}

sub handlexdir($$$) {
  my $z = $_[2];
  my $srcdir = $_[0];
  my $dstdir = $_[1];
  my $dh;
  unless (opendir($dh, $srcdir)) {
    print(STDERR "failed to read sourcedirectoy '$srcdir' for zoomlevel $z.\n");
    exit(1);
  }
  unless (-d $dstdir) {
    printlev(2, "MKDIR 'dstdir'\n");
    unless (mkdir($dstdir)) {
      print(STDERR "Destination directory '$dstdir' for zoomlevel $z does not exist and could not be created: $!\n");
      return;
    }
  }
  while (my $de = readdir($dh)) {
    if ($de =~ m/^(\d+)\.png$/) { # just a number dot png => handle this.
      my $ynr = $1;
      my $correctedynr = ((2 ** $z) - 1) - $ynr;
      my $srcname = $srcdir . '/' . $de;
      my $dstname = sprintf("%s/%d.png", $dstdir, $correctedynr);
      if ($noreplace) {
        if (-e $dstname) {
          printlev(2, "SKIP '$srcname' ('$dstname' already exists)\n");
          next;
        }
      }
      if ($skipvoidtiles) {
        my $fsize = -s $srcname;
        if ($fsize ~~ @voidtilesizes) { # One of the relevant filesizes, no
          # point in even computing the hash otherwise.
          my $sha512 = digest_file_hex($srcname, "SHA-512");
          printlev(3, "HASH $srcname -> $sha512\n");
          if ($sha512 ~~ @voidtilehashes) { # OK, one of the void hashes -> skip
            printlev(2, "SKIP '$srcname' (it has the hash of a void file)\n");
            next;
          }
        }
      }
      if ($moveinsteadofcopy) {
        printlev(2, "MOVE '$srcname' '$dstname'\n");
        move($srcname, $dstname);
      } else {
        printlev(2, "COPY '$srcname' '$dstname'\n");
        copy($srcname, $dstname);
      }
    }
  }
  closedir($dh);
}

sub handlezoomdir($$$) {
  my $z = $_[2];
  my $srcdir = $_[0] . '/' . $z;
  my $dstdir = $_[1] . '/' . $z;
  unless (-d $srcdir) {
    printlev(1, "sourcedirectoy '$srcdir' for zoomlevel $z does not exist, skipping.\n");
    return;
  }
  my $dh;
  unless (opendir($dh, $srcdir)) {
    print(STDERR "failed to read sourcedirectoy '$srcdir' for zoomlevel $z.\n");
    exit(1);
  }
  unless (-d $dstdir) {
    printlev(2, "MKDIR '$dstdir'\n");
    unless (mkdir($dstdir)) {
      print(STDERR "Destination directory '$dstdir' for zoomlevel $z does not exist and could not be created: $!\n");
      exit(1);
    }
  }
  while (my $de = readdir($dh)) {
    if ($de =~ m/^\d+$/) { # just a number -> handle this directory.
      handlexdir($srcdir . '/' . $de, $dstdir . '/' . $de, $z);
    }
  }
  closedir($dh);
}

my $srcdir = undef;
my $dstdir = undef;
foreach $a (@ARGV) {
  if ($a eq '--move') {
    $moveinsteadofcopy = 1;
  } elsif ($a eq '--noreplace') {
    $noreplace = 1;
  } elsif ($a eq '--skipvoidtiles') {
    $skipvoidtiles = 1;
  } elsif ($a eq '--help') {
    showhelpandexit();
  } elsif ($a eq '-q') {
    $verblev--;
  } elsif ($a eq '-v') {
    $verblev++;
  } else { # This will be interpreted as a directory name
    if (!defined($srcdir)) {
      $srcdir = $a;
    } elsif (!defined($dstdir)) {
      $dstdir = $a;
    } else { # More than 2 directory names? That is wrong.
      showhelpandexit();
    }
  }
}
unless (-d $srcdir) {
  print(STDERR "Source directory '$srcdir' does not seem to exist or is not a directory?\n");
  exit(1);
}
unless (-d $dstdir) {
  unless (mkdir($dstdir)) {
    print(STDERR "Destination directory '$dstdir' does not exist and could not be created: $!\n");
    exit(1);
  }
}
for (my $z = 0; $z < 30; $z++) {
  handlezoomdir($srcdir, $dstdir, $z);
}
