#!/usr/bin/perl

use strict;
package main;

use File::stat;
use File::Glob;
use File::Copy;
use File::Basename;
use File::Path;
use Cwd;

use constant OUTPUT => 1;
use constant DEBUG => 0;

my $isWindows = ( $^O eq "MSWin32" || $^O eq "cygwin" );

# Dummy variables (used in common.pm)
my $opt_verbose = 0;
my $shadow = 0;
my $outpath = $ENV{QPEDIR};

# Find the depot path
my $depotpath = undef;
open IN, "$outpath/src/config.pri" or die "Cannot open $outpath/src/config.pri\n";
while ( defined($_ = <IN>) ) {
    if ( /QTOPIA_DEPOT_PATH=(.*)/ ) {
	$depotpath = $1;
        if ( $depotpath eq '$$(QPEDIR)' ) {
            $depotpath = $outpath;
        }
	last;
    }
}
close IN;
if ( !defined($depotpath) ) {
    die "Can't find the depot path in $outpath/src/config.pri\n";
}

# Load some subs
open IN, "$depotpath/bin/common.pm" or die "Cannot open $depotpath/bin/common.pm\n";
eval join("", <IN>) or die "Error while evaluating common.pm: ".$@?$@:$!."\n";
close IN;

# Windows depot builds use the perl scripts directly rather than the compiled code
if ( $isWindows ) {
    check_script($0, "$depotpath/bin", $ARGV[0]);
}


my @SIZEDIRS = ();

# Turn "en_US ja" into a hash map with each language as a key (easy lookup later)
my %languages = ();
$_ = shift(@ARGV);
s/^\s+//;
s/\s+$//;
map { $languages{$_}++ } split;
# We MUST install en_US resources because they are used as a fallback
$languages{"en_US"}++;
# Handle non-underscored languages to (eg. 'en')
for my $lang ( keys %languages ) {
    if ( $lang =~ s/_.*// ) {
        $languages{$lang}++;
    }
}

while ($ARGV[0] =~ /^(\d+)(?:x(\d+))?$/ ) {
    push @SIZEDIRS, $1."x".($2||$1);
    shift @ARGV;
}

if ( scalar(@SIZEDIRS) == 0 ) {
    warn "Sizes should be specified as NUMBERxNUMBER or just NUMBER (same height and width).\n".
         "Separate sizes by whitespace.\n";
    usage();
}

my $picsSource = undef;
my $picsDest = shift(@ARGV) || usage();
$picsDest =~ s,\\,/,g;

if ( ! @ARGV ) {
    usage();
}

processFiles( @ARGV );

exit 0;


sub usage
{
    print "Usage:  ".script_name($0)." \"languages\" <size1> ... [sizen] <pics dest> <pics>\n";
    exit 2;
}

sub processFiles
{
    my @files = @_;
    foreach my $file ( @files ) {
	$file =~ s,\\,/,g;
	# Windows doesn't glob. Lets try this again with a glob.
	if ( $file =~ /\*/ ) {
	    processFiles(glob($file));
	    return;
	}
	DEBUG and print "processing file $file\n";
	( $picsSource ) = $file =~ /(.*)\/.*/;
        my $oldpwd = getcwd();
        chdir $picsSource;
        my $prevPicsSource = $picsSource;
        $picsSource = getcwd();
        chdir $oldpwd;
	DEBUG and print "picsSource = $picsSource\n";
	my $srcfile = $file;
        $srcfile =~ s,^\Q$prevPicsSource\E,$picsSource,;
	DEBUG and print "picsDest = $picsDest\n";
	my $dest = "$picsDest/$srcfile";
	DEBUG and print "dest = $dest\n";
	if ( $picsSource ) {
	    $dest =~ s,$picsSource/,,;
        }
	DEBUG and print "after munging dest = $dest\n";
	installpic($srcfile, $dest);
    }
}

sub installpic
{
    my ( $srcfile, $dest ) = @_;

    if ( ! -d $srcfile ) {
	DEBUG and print "installing picture $srcfile\n";
	if ( ! -d dirname($dest) ) {
	    OUTPUT and print "mkdir ".dirname($dest)."\n";
	    mkpath(dirname($dest));
	}
	if ( needCopy($srcfile, $dest) ) {
	    OUTPUT and print "install -c $srcfile $dest\n";
	    copy($srcfile, $dest);
	}
	return;
    }

    DEBUG and print "installing dir $srcfile\n";
    if ( ! -d $dest ) {
	mkpath($dest);
    }
    OUTPUT and print "copyallpics $srcfile $dest\n";
    copyallpics($srcfile, $dest);

}

sub installicons {
    my ( $srcdir, $dest, $width, $height ) = @_;
    return unless ( -d $srcdir );
    mkpath($dest) unless ( -d $dest );

    chdir($srcdir);
    opendir(ICONDIR, "$srcdir") or die "Could not open icon dir $srcdir: $!";
    my @allicondirs = grep /^\d+x\d+$/, readdir ICONDIR;
    closedir ICONDIR;

    # try to pick icons closest to the dest size.
    my %iconfiles;
    foreach my $icondir ( @allicondirs ) {
	# should be either one twice the size, or the next biggest from the size given.
	# for now, just the next biggest form the size given.
	if ( -d $icondir ) {
	    opendir(ICONDIR, "$icondir") or die "Could not open icon dir $srcdir/$icondir: $!";
	    my @maybeicons = readdir ICONDIR;
	    closedir ICONDIR;
	    my ( $nwidth, $nheight ) = ( $icondir =~ /(\d+)x(\d+)/ );

            my @allicons;
	    foreach my $icon ( @maybeicons ) {
                # We install files here as well as files in i18n/<lang>
                if ( -f "$icondir/$icon" ) {
                    push(@allicons, $icon);
                } elsif ( -d "$icondir/$icon" && "$icondir/$icon" =~ m{/i18n$} ) {
                    for my $lang ( keys %languages ) {
                        if ( -d "$icondir/$icon/$lang" ) {
                            mkpath("$dest/$icon/$lang");
                            for my $file ( glob("$icondir/$icon/$lang/*") ) {
                                if ( -f $file ) {
                                    # strip this bit off
                                    $file =~ s/^\Q$icondir\E\///;
                                    push(@allicons, $file);
                                }
                            }
                        }
                    }
                }
            }
	    foreach my $icon ( @allicons ) {
		if (defined($iconfiles{$icon})) {
		    my ( $cwidth, $cheight ) = ( $iconfiles{$icon} =~ /(\d+)x(\d+)/ );
		    if ($cheight < $height && $cwidth < $width) {
			# if it's bigger, use it
			if ($nheight > $cheight && $nwidth > $cwidth) {
			    DEBUG and print "choose $icondir over $iconfiles{$icon} for $icon.  (bigger)\n";
			    $iconfiles{$icon} = $icondir;
			}
		    } else {
			# current is larger or equal to match.
			# if it's smaller, but still bigger than the target height, use it
			if ($nheight < $cheight && $nwidth < $cwidth 
			    && $nheight >= $height && $nwidth >= $width) {
			    
			    DEBUG and print "choose $icondir over $iconfiles{$icon} for $icon.  (closer)\n";
			    $iconfiles{$icon} = $icondir;
			}
		    }
		} else {
		    $iconfiles{$icon} = $icondir;
		}
	    }
	}
    }

    foreach my $file ( keys %iconfiles ) {
	my $from = "$srcdir/$iconfiles{$file}/$file";
	my $to = "$dest/".basename_incl_i18n($from);
	if ($to ne $from && -f $from && ! -f $to) {
	    if (needCopy($from, $to) ) {
		OUTPUT and print "Generate $to from $from\n";
		system "$ENV{QPEDIR}/bin/pngscale -width $width -height $height" .
			   " \"$from\" \"$to\"";
	    }
	}
    }
}

sub copyallpics
{
    # Handles "icons" directories specially.

    my ( $srcfile, $dest ) = @_;
    if ( -f $srcfile ) {
	if ( needCopy($srcfile, $dest) ) {
	    DEBUG and print "copy $srcfile $dest\n";
	    copy($srcfile, $dest);
	}
    } else {
	if ( ! -d $dest ) {
	    DEBUG and print "mkpath $dest\n";
	    mkpath($dest);
	}
	if ( $dest =~ m{/icons$} ) {
	    foreach my $size ( @SIZEDIRS ) {
		my ( $width, $height ) = ( $size =~ /(\d+)x(\d+)/ );
		DEBUG and print "installicons $srcfile $dest ($size)\n";
		installicons($srcfile, "$dest/$size", $width, $height);
	    }
	} else {
	    DEBUG and print "glob($srcfile/*)\n";
	    my @maybe_tocp = glob("$srcfile/*");
            my @tocp = ();
            if ( $dest =~ m{/i18n$} ) {
                # Only install i18n files for the selected languages
                foreach my $file ( @maybe_tocp ) {
                    if ( exists($languages{basename($file)}) ) {
                        push(@tocp, $file);
                    }
                }
            } else {
                @tocp = @maybe_tocp;
            }
	    foreach my $file ( @tocp ) {
                my $picdest = "$dest/".basename($file);
                DEBUG and print "installpic $file $picdest\n";
                    installpic($file, $picdest);
	    }
	}
    }
}

sub basename_incl_i18n
{
    my ( $file ) = @_;
    if ( $file =~ m{/i18n/} ) {
        $file =~ s{^.*/(i18n/)}{$1};
    } else {
        $file = basename($file);
    }
    return $file;
}

