#!/usr/bin/perl

#### add option args for movixrc opts

use strict;
use Cwd 'abs_path';
use vars qw(
	    %RC
	    $title
	    $isoOut
	    $bootLabel
	    @extra_mkisofs_options
	    $extra_mkisofs_options
	    @extra_mplayer_options
	    $extra_mplayer_options
	    @unwanted_mplayer_options
	    $unwanted_mplayer_options
	    $make_empty_iso
	    $css
	    $loop
	    $random
	    $shut
	    $reboot
	    $eject
	    $fontSet
	    $bgVideo
	    $language
	    $verbose
	    $version
	    $movixDir
	    $fontDir
	    $isoDir
	    $distro
	    $mkisofs_bin
	    $noSubs
	    $bootOptions
	    $stdOptions
	    $extraOptions
	    $hasQT
	    $hasASF
	    $hasWMV
	    $hasRP
	    $hasXANIM
	    $autoDelete
	    $help
	    $nodma
	    $noSubhelp
	    $dma
	    $keyboard
	    );

my $pwd = $ENV{"PWD"};
my $bin_dir  = $0 =~ /^\// ? $0 : abs_path($0);
$bin_dir     =~ s/\/?[^\/]*$//g;
$mkisofs_bin = "mkisofs";

##################################
###  Retrieving options from .mkmovixisorc
###  These are the default options for this script
###########################
my $mkmovixisorc = $ENV{"HOME"}."/.mkmovixisorc";
if( -e $mkmovixisorc ){
  open(RC,$mkmovixisorc);
  while(<RC>){
    next if /^\#/;
    next unless /^([^\=]+)\=(.*)$/;
    $RC{$1}=$2;
  }
  close(RC);
}
$isoOut    = $RC{'output-file'}   if exists $RC{'output-file'};
$bootLabel = $RC{'boot-label'}    if exists $RC{'boot-label'};
$fontSet   = $RC{'subtitleFonts'} if exists $RC{'subtitleFonts'};
$bgVideo   = $RC{'bgVideo'}       if exists $RC{'bgVideo'};
$language  = $RC{'language'}      if exists $RC{'language'};
$distro    = $RC{'distro'}        if exists $RC{'distro'};
$mkisofs_bin = $RC{'mkisofs_bin'} if exists $RC{'mkisofs_bin'};
$keyboard  = $RC{'keyboard'}      if exists $RC{'keyboard'};
$extra_mkisofs_options    = $RC{'extra-mkisofs-options'}    if exists $RC{'extra-mkisofs-options'};
$extra_mplayer_options    = $RC{'extra-mplayer-options'}    if exists $RC{'extra-mplayer-options'};
$unwanted_mplayer_options = $RC{'unwanted-mplayer-options'} if exists $RC{'unwanted-mplayer-options'};
$css    = "y" if $RC{'css'} eq "y";
$loop   = $RC{'loop'} if exists $RC{'loop'} and $RC{'loop'} =~ /^\d+$/;
$random = "y" if $RC{'random'} eq "y";
$shut =   "y" if $RC{'shut'}   eq "y";
$reboot = "y" if $RC{'reboot'} eq "y";
$eject  = "y" if $RC{'eject'}  eq "y";
$nodma  = "y" if $RC{'dma'}    eq "n";
$noSubhelp = "y" if $RC{'subhelp'}    eq "n";
$autoDelete  = 1 if $RC{'auto-delete'}  eq "y";

#######################
### Retrieve options from command line
#################################
use Getopt::Long;
use Pod::Usage;

GetOptions (
	    "title=s"             => \$title,
	    "output-file=s"       => \$isoOut,
	    "boot-label=s"        => \$bootLabel,
	    "extra-mkisofs-options=s"     => \@extra_mkisofs_options,
	    "extra-mplayer-options=s"     => \@extra_mplayer_options,
	    "unwanted-mplayer-options=s"  => \@unwanted_mplayer_options,
	    "make-empty-iso"      => \$make_empty_iso,
	    "css"                 => \$css,
	    "loop=i"              => \$loop,
	    "random"              => \$random,
	    "reboot"              => \$reboot,
	    "shut"                => \$shut, 
	    "eject"               => \$eject,
	    "auto-delete"         => \$autoDelete,
	    "movixDir=s"          => \$movixDir,
	    "distro=s"            => \$distro,
	    "mkisofs=s"           => \$mkisofs_bin,
	    "subtitleFonts=s"     => \$fontSet,
	    "bgVideo=s"           => \$bgVideo,
	    "language=s"          => \$language,
	    "keyboard=s"          => \$keyboard,
	    "hasQT"               => \$hasQT,
	    "hasWMV"              => \$hasWMV,
	    "hasASF"              => \$hasASF,
	    "hasRP"               => \$hasRP,
	    "hasXANIM"            => \$hasXANIM,
	    "verbose"             => \$verbose,
	    "nodma"               => \$nodma,
	    "nosubhelp"           => \$noSubhelp,
	    "movix-version"       => \$version,
	    'help|?'              => \$help
	    );

$extra_mkisofs_options = join(' ',split(/,/,join(',',@extra_mkisofs_options))) if @extra_mkisofs_options > 0;
$extra_mplayer_options = join(' ',split(/,/,join(',',@extra_mplayer_options))) if @extra_mplayer_options > 0;
$unwanted_mplayer_options = join(' ',split(/,/,join(',',@unwanted_mplayer_options))) if @unwanted_mplayer_options > 0;

$fontSet  = "FreeSerifBoldItalic" unless defined $fontSet;

if( ! defined $movixDir ){
	$movixDir = -e "$bin_dir/movix-conf" ? `$bin_dir/movix-conf` : `movix-conf`;
    chop $movixDir;
}

#$bgVideo  = "$movixDir/movix/movix.music.avi" unless defined $bgVideo;

if( defined $help ){
  help();
  exit;
}

if( defined $version ){
  system "movix-version";
  exit;
}

if( defined $isoOut ){
  $isoOut = $pwd."/".$isoOut if $isoOut !~ /^\//;
} else {
  print "\nYou _must_ provide an output file!\n";
  help();
  exit;
}

if( @ARGV == 0 and ! defined $make_empty_iso ){
  print "\nYou _must_ provide at least one input file!\n";
  help();
  exit;
}

if( defined $title ) {
  my @chars = split '', $title;
  if( @chars > 32 ){
    print "\nTitle length cannot be longer than 32 characters!\n";
    exit;
  }
} else {
  my $version = `$bin_dir/movix-version`;
  chop $version;
  $title    = "eMoviX $version CD";
}

### collect all known languages available for the boot messages
my $knownLanguages = `ls \"$movixDir/translations/\"`;
$knownLanguages =~ s/\n/ /g;
chop $knownLanguages;
$knownLanguages = " $knownLanguages ";

### collect all known kbd layouts avaialble 
my $knownKeymaps = `ls \"$movixDir/keyboard-i18n/\"`;
$knownKeymaps =~ s/\n/ /g;
chop $knownKeymaps;
$knownKeymaps = " $knownKeymaps ";

# Check if the given lang is available
$language = "en" unless defined $language;
unless( $knownLanguages =~ / $language / ){
    print "Label $language does not correspond to any language supported by eMoviX :-(\nIf you would like to provide translations for it post a message on the movix forums at http://movix.sf.net/ !\n\n";
    help();
    exit;
}

if( defined $keyboard ){
  unless( $knownKeymaps =~ / $keyboard / ){
    print "Keyboard layout $keyboard does not correspond to any layouts supported by eMoviX :-(\nIf you would like to provide a keyboard layout, read keyboard-i18n/README in the eMoviX distribution! :-)\n\n";
    help();
    exit;
  }
} else {
  $keyboard = ( $knownKeymaps =~ / $language / ) ? $language : "us";
  $keyboard =~ s/^en$/us/;
}

################################
### Building the temporary dir and linking there
### all audio/video/auxiliary files
################################
my $date = `date +%s`;
chop $date;
my $tmpDir = "/tmp/movix-$date";
mkdir  "$tmpDir";
chdir  "$tmpDir";
mkdir  "eMoviX";
mkdir  "eMoviX/boot";
mkdir  "eMoviX/boot/kernel";
mkdir  "eMoviX/movix";
mkdir  "eMoviX/mplayer";
mkdir  "eMoviX/help";
foreach ( split "\n", `$bin_dir/movix-files` ){
  `ln -s "$movixDir/movix/$_" eMoviX/movix`;
}
mkdir "eMoviX/remotes";
`ln -s "$movixDir/remotes/$_" eMoviX/remotes` 
  foreach (split "\n", `ls "$movixDir/remotes"`);
#system "ln -s \"$movixDir\"/movix/* movix";

### dealing with codecs
#`rm -f movix/win32`;
my @codecs = split "\n", `ls "$movixDir"/codecs/ 2> /dev/null`;
if( @codecs > 0 ){
  `mkdir -p eMoviX/codecs/`;
  `ln -s "$movixDir"/codecs/* eMoviX/codecs`;
  `rm -f eMoviX/codecs/qt*`    unless defined $hasQT;
  `rm -f eMoviX/codecs/win32*` unless defined $hasASF or defined $hasWMV;
  `rm -f eMoviX/codecs/rp*`    unless defined $hasRP;
  `rm -f eMoviX/codecs/xanim*` unless defined $hasXANIM;
}

### dealing with libdvdcss - you'll need this if you want to play encrypted DVDs
`ln -s "$movixDir"/movix/libdvdcss* eMoviX/mplayer` if defined $css;
#system "rm -f movix/libdvdcss*"   unless defined $css;

#mkdir  "eMoviX";
#mkdir  "eMoviX/kernel";
system "ln -s \"$movixDir\"/isolinux/{iso.sort,movix.*} eMoviX/boot";

# If the option --distro was given, another initrd file should be linked
my $distfile = '';
my $warned = 0;
if (defined $distro) {
  foreach $distfile ("initrd.gz", "isolinux.cfg", "kernel/vmlinuz") {
    
    if ( -e "$movixDir/isolinux/$distfile.$distro" ) {
    # the file of the selected distribution is there
      system "ln -s \"$movixDir\"/isolinux/$distfile.$distro eMoviX/boot/$distfile";
    } else {
    # not here - use the one without the prefix
      if ($warned == 0) {
        print "Warning: the files necessary for --distro=$distro are missing.\nDefault ones will be used.\n";
        $warned = 1;
      }

      system "ln -s \"$movixDir\"/isolinux/$distfile eMoviX/boot/$distfile";
    }
    
  }
} else {
# use the normal distro files
  foreach $distfile ("initrd.gz", "isolinux.cfg", "kernel/vmlinuz") {
    system "ln -s \"$movixDir\"/isolinux/$distfile eMoviX/boot/$distfile";
  }
}

# Link the isolinux boot-keymap to the selected keyboard layout
system "ln -s \"$movixDir\"/keyboard-i18n/$keyboard/bootkey.map eMoviX/boot/bootkey.map";

#system "rm -f isolinux/isolinux.bin";
system "cp \"$movixDir\"/isolinux/isolinux.bin eMoviX/boot/isolinux.bin";
if( defined $bootLabel ){
  die "boot label $bootLabel is unknown :-(\n"
    unless $bootLabel =~ /^vesa|vesaFB(\d*)?|FB|aa(\d*)?|sdl$/;
  my $isolinuxcfg = "default $bootLabel\n";
  open CFG, "eMoviX/boot/isolinux.cfg";
  <CFG>;
  while(<CFG>){
    $isolinuxcfg .= $_;
  }
  close CFG;
  system "rm -f eMoviX/boot/isolinux.cfg";
  open CFG, "> eMoviX/boot/isolinux.cfg";
  print CFG $isolinuxcfg;
  close CFG;
}

### next instruction will disappear once the old txt messages will be
### removed from the src/isolinux dir
#system "rm -f isolinux/*txt";
system "ln -sf \"$movixDir\"/translations/$language/*txt eMoviX/boot";
system "ln -sf \"$movixDir\"/translations/$language/*.sh eMoviX/help";
system "ln -sf \"$movixDir\"/translations/$language/*.msg eMoviX/boot";

system "ln -sf \"$movixDir\"/translations/$language/*.man eMoviX/help";
system "ln -sf \"$movixDir\"/translations/$language/*.sub eMoviX/help";

### localisation of mplayer menu
system "ln -sf \"$movixDir\"/translations/$language/menu.conf eMoviX/mplayer/menu.conf";

foreach my $file (@ARGV){
    $file = $pwd."/".$file if $file !~ /^\//;
    if( -d $file ){
        system "ln -s $file/* .";
    } elsif( -e $file ) {
        system "ln -s \"$file\" .";
    } else {
        die "The file $file does not exist! Please check and retry.\n";
    }
}

$fontDir = "eMoviX/font";
if( -e "$movixDir/mplayer-fonts/$fontSet/font.desc" ){
  system "mkdir -p $fontDir";
  system "ln -s \"$movixDir\"/mplayer-fonts/$fontSet/* $fontDir";
} else {
#  print "\"$movixDir\"/mplayer-fonts/$fontSet/font.desc"."\n";
#  print "pippo\n" if -e "/usr/local/share/emovix";
#  print "pippo->\n" if -e "$movixDir";
#  $movixDir = "/usr/a b";
#  print "<-pippo\n" if -e "$movixDir";
#  print "pippo\n" if -e "$movixDir/mplayer-fonts/$fontSet/font.desc";
#  die "che ci fo qui?";
  #system "mkdir -p eMoviX";
#  system "ln -s \"$movixDir\"/mplayer-fonts/$fontSet\.ttf eMoviX/mplayer/subfont.ttf";
  system "ln -s \"$movixDir\"/mplayer-fonts/$fontSet\.ttf eMoviX/mplayer/";
}

if ( $bgVideo =~ /^none$/ ) {
  #print "Not including a background video.";
  system "rm eMoviX/movix/movix.music.avi";
} elsif ( $bgVideo eq '' ) {
# No special background video given, use the one already determined by movix-files
  # do nothing
} else {
# A filename was given

  if ( -e $bgVideo ) {
  # Absolute path to an existing file
    system "rm eMoviX/movix/movix.music.avi; \
            ln -s '$bgVideo' eMoviX/movix/movix.music.avi";

  } elsif ( -e "$pwd/$bgVideo" ){
  # The video is in the current directory, or a relative path was given
    system "rm eMoviX/movix/movix.music.avi; \
            ln -s '$pwd/$bgVideo' eMoviX/movix/movix.music.avi";

  } elsif ( -e "$movixDir/backgrounds/$bgVideo" ){
  # Perhaps in $movixDir/backgrounds/?
    system "rm eMoviX/movix/movix.music.avi; \
            ln -s '$movixDir/backgrounds/$bgVideo' eMoviX/movix/movix.music.avi";
  } else {
  # Sorry
    die "Background video $bgVideo couldn't be found!\n";
  }
}

# Link the selected shell keymap
system "ln -s \"$movixDir\"/keyboard-i18n/$keyboard/shellkey.map eMoviX/boot/shellkey.map";

open MOVIXRC, "> eMoviX/movix/movixrc";
print MOVIXRC "extra-mplayer-options=$extra_mplayer_options\n" if defined $extra_mplayer_options;
print MOVIXRC "unwanted-mplayer-options=$unwanted_mplayer_options\n" if defined $unwanted_mplayer_options;
print MOVIXRC "loop=$loop\n" if defined $loop;
print MOVIXRC "shut=y\n"     if defined $shut;
print MOVIXRC "reboot=y\n"   if defined $reboot;
print MOVIXRC "random=y\n"   if defined $random;
print MOVIXRC "eject=y\n"    if defined $eject;
print MOVIXRC "dma=n\n"      if defined $nodma;
print MOVIXRC "noSubhelp=y\n" if defined $noSubhelp;
close MOVIXRC;

print "\n";
if( $verbose == 1 ){
    print "Your movix directory seems to be in: \"$movixDir\"\n";
    print "MoviX temporary directory is:        $tmpDir\n";
}

##############
### Standard booting options, from SysLinux docs
### and from slackware installation CD README
###############
$bootOptions = "-no-emul-boot -boot-load-size 4 -boot-info-table -b eMoviX/boot/isolinux.bin -c eMoviX/boot/isolinux.boot -sort eMoviX/boot/iso.sort";

##############
### Standard mkisofs options: -v=>verbose, -r=>rock-ridge,
####                          -J=>Joliet,  -f=>follow symbolic links
##############
$stdOptions  = "-v -r -J -f ";
#
### -joliet-long is supported only by mkisofs 2.x.x binaries!
#
$stdOptions .= "-joliet-long " if `mkisofs --version` =~ /^mkisofs 2/;

#######
### User's extra options (if any)
#########
if( defined $extra_mkisofs_options ) {
    $extraOptions .= $extra_mkisofs_options;
}

my $mkiso  = "$mkisofs_bin -o \"$isoOut\" $stdOptions -V \"$title\" $extraOptions $bootOptions .";
if( $verbose == 1 ){
    print "Starting mkisofs...\n$mkiso\n";
} else {
    $mkiso .= "> /dev/null 2> /dev/null";
}
system "$mkiso";

print "Your iso image is now in \"$isoOut\":\n";
print `ls -l \"$isoOut\"`;
if ( $autoDelete == 1 ) {
    system "rm -rf '$tmpDir'";
    print "The temporary directory '$tmpDir' was deleted.\n\n";
} else {
    print "You can safely delete the temporary directory $tmpDir\n\n";
}

##########################################################
####  Eventually this should be replaced by pod docs
######################

sub help {
    print
"Usage: mkmovixiso [options] file1 ... fileN dir1 ... dirN
Note: All options may be be abbreviated to uniqueness and
      a single dash is sufficient
Options:

 Generic:

   --title=<title>         Title of the iso image
   --output-file=<file>    Name [with full path!] of the output iso image
   --boot-label=<label>    Make MoviX boot by default with your favorite label
   --subtitleFonts=<lang>  Specify which font set will be included in the iso image.

Available font sets:
 - MPlayer standard font sets
   ";

    my @fonts = split "\n", `ls $movixDir/mplayer-fonts/`;
    my @stFonts;
    my @ttFonts;
    foreach (@fonts){
      push @stFonts, $_ if -d "$movixDir/mplayer-fonts/$_";
      push @ttFonts, $_ if /.ttf$/i;
    }
    for( my $i=0; $i < @stFonts; $i++ ){
      print "$stFonts[$i]";
      print " (default)" if $fontSet eq $stFonts[$i];
      print ", " unless $i == @stFonts - 1;
    }
    print "

 - True type font sets:
   ";

    for( my $i=0; $i < @ttFonts; $i++ ){
      $ttFonts[$i] =~ s/.ttf$//i;
      print "$ttFonts[$i]";
      print " (default)" if $fontSet eq $ttFonts[$i];
      print ", " unless $i == @ttFonts - 1;
    }

print "

   --distro=<distribution> Specify the distribution to use (only if you are 
                             using the full eMoviX package)

Available distributions in the full eMoviX package: mini, normal, full
    
 mini:   just the drivers necessary for video and audio playback
 normal: mini + LIRC remote support + character set conversion + aa, SDL output
 full:   normal + DXR output

   --language=<lang>       Specify the language of the CD boot messages

Available Languages:
en - English (default),  it - Italian,     es - Spanish,      nl - Dutch,
hu - Hungarian,          de - German,      fr - French,       pt - Portuguese,
pl - Polish,             jp - Japanese,    sar - Sardinian,   esp - Esperanto

   --keyboard=<lang>       Specify the keyboard layout to use

Available keyboard layouts:
us - US English (default), de - German     es - Spanish,      fr - French,
hu - Hungarian,            it - Italian,   nl - Dutch,        pt - Portuguese,
be - Belgian

   --movixDir=<dir>        Where the movix data dir is (no need to specify it if
                           you didn't move it from its default install location)
   --mkisofs=<mkisofs exe> Full path of mkisofs, in case it's not in the \$PATH
   --bgVideo=file.avi      A video file to be used as background for audio file playback
                           ('none' for not including the video file)
 - Available backgrounds:
";

    my @bkg = split "\n", `ls $movixDir/backgrounds/`;
    foreach(@bkg){
      print "$_\n";
    }

print "
   --css                   Include the dvdcss library (see README for more info)
   --loop=<k>              Make MPlayer play k times your files before stopping [0=infinity]
   --random                Make MPlayer play your files in random order
   --eject                 Make MoviX eject the CD once it finished playing
   --reboot                Make MoviX reboot the PC once it finished playing
   --shut                  Make MoviX shut the PC off once it finished playing
   --hasQT                 Include DLL files required to play QuickTime files
   --hasASF                Include DLL files required to play .asf files
   --hasWMV                Include DLL files required to play .wmv files
   --hasRP                 Include DLL files required to play RealPlayer files
   --hasXANIM              Include DLL files extracted from the xanim project
   --nodma                 Do not enable fast mode for CD-ROM devices by default
   --nosubhelp             Do not show the short subtitle help in movie files
   --auto-delete           Automatically remove the temporary directory
   --extra-mkisofs-options=\"opt1 opt2 ...\"
                           Extra options for mkisofs
   --extra-mplayer-options=\"opt1 opt2 ...\"
                           Extra options for mplayer
   --unwanted-mplayer-options=\"opt1 opt2 ...\"
                           MPlayer options you want to be sure MPlayer will not use
   --movix-version         Print the version number and exit
   --verbose               Be verbose
   --help                  This help

";
}
