#!/usr/bin/perl
#             __________               __   ___.
#   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
#   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
#   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
#   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
#                     \/            \/     \/    \/            \/
# $Id$
#

$ROOT="..";

if($ARGV[0] eq "-r") {
    $ROOT=$ARGV[1];
    shift @ARGV;
    shift @ARGV;    
}

my $verbose;
if($ARGV[0] eq "-v") {
    $verbose =1;
    shift @ARGV;
}

my $firmdir="$ROOT/firmware";

my $wpslist=$ARGV[0];

my $target = $ARGV[1];
my $cppdef = $target;
my @depthlist = ( 16, 8, 4, 2, 1 );

if(!$wpslist) {
    print "Usage: wpsbuilds.pl <WPSLIST> <target>\n",
    "Run this script in the root of the target build, and it will put all the\n",
    "stuff in .rockbox/wps/\n";
    exit;
}

sub getlcdsizes {
    my ($remote) = @_;

    open(GCC, ">gcctemp");
    if($remote) {
        # Get the remote LCD screen size
    print GCC <<STOP
\#include "config.h"
#ifdef HAVE_REMOTE_LCD
Height: LCD_REMOTE_HEIGHT
Width: LCD_REMOTE_WIDTH
Depth: LCD_REMOTE_DEPTH
#endif
STOP
;
    }
    else {
    print GCC <<STOP
\#include "config.h"
#ifdef HAVE_LCD_BITMAP
Height: LCD_HEIGHT
Width: LCD_WIDTH
Depth: LCD_DEPTH
#endif
STOP
;
}
    close(gcc);

    my $c="cat gcctemp | gcc $cppdef -I. -I$firmdir/export -E -P -";

    #print "CMD $c\n";

    open(GETSIZE, "$c|");

    my ($height, $width);
    while(<GETSIZE>) {
        if($_ =~ /^Height: (\d*)/) {
            $height = $1;
        }
        elsif($_ =~ /^Width: (\d*)/) {
            $width = $1;
        }
        elsif($_ =~ /^Depth: (\d*)/) {
            $depth = $1;
        }
        if($height && $width && $depth) {
            last;
        }
    }
    close(GETSIZE);
    unlink("gcctemp");

    return ($height, $width, $depth);
}

sub mkdirs {        
    my $wpsdir = $wps;
    $wpsdir =~ s/\.(r|)wps//;
    mkdir ".rockbox/wps", 0777;
    mkdir ".rockbox/themes", 0777;

    if( -d ".rockbox/wps/$wpsdir") {
        #print STDERR "wpsbuild warning: directory wps/$wpsdir already exists!\n";
    }
    else
    {
       mkdir ".rockbox/wps/$wpsdir", 0777;
    }
}

sub copywps {
    # we assume that we copy the WPS files from the same dir the WPSLIST
    # file is located in
    my $dir;
    my @filelist;
    my $file;

    if($wpslist =~ /(.*)WPSLIST/) {
        $dir = $1;
#        system("cp $dir/$wps .rockbox/wps/");
        # print "$req_t_wps $req_g_wps\n";

        if (-e "$dir/$req_t_wps" ) {
          system("cp $dir/$req_t_wps .rockbox/wps/$wps");

        } elsif (-e "$dir/$req_g_wps") {
           system("cp $dir/$req_g_wps .rockbox/wps/$wps");

           open(WPSFILE, "$dir/$req_g_wps");
           while (<WPSFILE>) {
              $filelist[$#filelist + 1] = $1 if (/\|([^|]*?.bmp)\|/);
           }
           close(WPSFILE);

           if (-e "$dir/$wps_prefix/$req_g") {
              foreach $file (@filelist) {
                  system("cp $dir/$wps_prefix/$req_g/$file .rockbox/wps/$wps_prefix/");
              }
           } 
           elsif (-e "$dir/$wps_prefix") {
              foreach $file (@filelist) {
                  system("cp $dir/$wps_prefix/$file .rockbox/wps/$wps_prefix/");
              }
           } 
           else {
               print STDERR "beep, no dir to copy WPS from!\n";
           }
         
       } else {
           print STDERR "Skipping $wps - no matching resolution.\n";
       }
    } else {
        print STDERR "No source directory!\n";
    }
}

sub buildcfg {
    my $cfg = $wps;
    my @out;

    $cfg =~ s/\.(r|)wps/.cfg/;

    push @out, <<MOO
\#
\# $cfg generated by wpsbuild.pl
\# $wps is made by $author
\#
wps: /.rockbox/wps/$wps
MOO
;
    if($font) {
        push @out, "font: /.rockbox/fonts/$font\n";
    }
    if($statusbar) {
        push @out, "statusbar: $statusbar\n";
    }
    if($rwps && $has_remote ) {
        push @out, "rwps: /.rockbox/wps/$rwps\n";
    }

    if(-f ".rockbox/wps/$cfg") {
        print STDERR "wpsbuild warning: wps/$cfg already exists!\n";
    }
    else {
        open(CFG, ">.rockbox/themes/$cfg");
        print CFG @out;
        close(CFG);
    }
}

# Get the LCD sizes first
my ($main_height, $main_width, $main_depth) = getlcdsizes();
my ($remote_height, $remote_width, $remote_depth) = getlcdsizes(1);

#print "LCD: ${main_height}x${main_width}x${main_depth}\n";
$has_remote = true if ($remote_height && $remote_width && remote_depth);

open(WPS, "<$wpslist");
while(<WPS>) {
    my $l = $_;
    if($l =~ /^ *\#/) {
        # skip comment
        next;
    }
    if($l =~ /^ *<(r|)wps>/i) {
        $isrwps = $1;
        $within = 1;
        # undef is a unary operator (!)
        undef $wps;
        undef $wps_prefix;
        undef $rwps;
        undef $width; 
        undef $height;
        undef $font;
        undef $statusbar;
        undef $author;
        undef $req_g_wps;
        undef $req_t_wps;
        next;
    }
    if($within) {
        if($l =~ /^ *<\/${isrwps}wps>/i) {
            # Get the required width and height
            my ($rheight, $rwidth, $rdepth);
            if($isrwps) {
                ($rheight, $rwidth, $rdepth) = 
                         ($remote_height, $remote_width, $remote_depth);
            }
            else {
                ($rheight, $rwidth, $rdepth) = 
                         ($main_height, $main_width, $main_depth);
            }

            if(!$rheight || !$rwidth) {
                #printf STDERR "wpsbuild notice: No %sLCD size, skipping $wps\n",
                $isrwps?"remote ":"";
                $within = 0;
                next;
            }
            $wpslist =~ /(.*)WPSLIST/;
            my $wpsdir = $1;
        # If this WPS installable on this platform, one of the following
        # two files will be present
        foreach $d (@depthlist) {
                next if ($d > $rdepth); 

                $req_g = $rwidth . "x" . $rheight . "x" . $d;

                $req_g_wps = $wps_prefix . "." . $req_g . ".wps";
                last if (-e "$wpsdir/$req_g_wps"); 

                if ($isrwps) {
                    $req_g = $req_g . "." . $main_width . "x" . $main_height . "x" . "$main_depth";

                    $req_g_wps = $wps_prefix . "." . $req_g . ".wps";
                    last if (-e "$wpsdir/$req_g_wps"); 
                }
            } 
            $req_t_wps = $wps_prefix . ".txt" . ".wps";

            #print "LCD: $wps wants $height x $width\n";
            #print "LCD: is $rheight x $rwidth\n";

            #print "gwps: $wpsdir/$req_g_wps" . "\n";
            if (-e "$wpsdir/$req_g_wps" || -e "$wpsdir/$req_t_wps" ) { 
                #
                # The target model has an LCD that is suitable for this
                # WPS
                #
                #print "Size requirement is fine!\n";
                mkdirs() if (-e "$wpsdir/$req_g_wps");
                if(!$isrwps) {
                    # We only make .cfg files for <wps> sections:
                    buildcfg();
                }
                copywps();
            }
            else {
                #print "(${wps_prefix}-${rwidth}x${rheight}x$rdepth) "; 
                print "Skip $wps due to size restraints\n";
            }
            $within = 0;
        }
        elsif($l =~ /^Name: (.*)/i) {
            # Note that in the case this is within <rwps>, $wps will contain the
            # name of the rwps. Use $isrwps to figure out what type it is.
            $wps = $wps_prefix = $1;
            $wps_prefix =~ s/\.(r|)wps//;
            # print $wps_prefix . "\n";
        }
        elsif($l =~ /^RWPS: (.*)/i) {
            $rwps = $1;
        }
        elsif($l =~ /^RWPS\.${main_width}x${main_height}x$main_depth: (.*)/i) {
            $rwps = $1;
        }
        elsif($l =~ /^Author: (.*)/i) {
            $author = $1;
        }
        elsif($l =~ /^Width: (.*)/i) {
            $width = $1;
        }
        elsif($l =~ /^Height: (.*)/i) {
            $height = $1;
        }
        elsif($l =~ /^Font: (.*)/i) {
            $font = $1;
        }
        elsif($l =~ /^Font\.${main_width}x${main_height}x$main_depth: (.*)/i) {
            $font = $1;
        }
        elsif($l =~ /^Statusbar: (.*)/i) {
            $statusbar = $1;
        }
    }
}

close(WPS);
