#!/usr/bin/perl -w
#
# Copyright (C) 2003  Pascal Giard
#
# Author:             Pascal Giard <evilynux@yahoo.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

use strict;

use File::stat;
use Gnome2;
use Gtk2::GladeXML;
use POSIX qw(waitpid);
use Getopt::Long;
use Config::IniFiles;

use lib '/usr/local/lib/movixmaker-2';
use lib '/usr/lib/movixmaker-2';
use lib 'movixmaker-2';
use config;

use constant FALSE => 0;
use constant TRUE => !FALSE;

use vars qw($xml_root $child_pid
            $NAME
            $glade_dir $config_file $movixversion
            $diag_feedback $diag_properties
            $statusbar $mkisocmd $installed_emovix
            $destpath $srcpath $tmpfolder $help
            $destination $srcdir $current_path
            $opt_verbose $opt_debug $opt_lang $opt_kblayout
            $opt_qt $opt_asf $opt_wmv $opt_tmpdir $opt_fontset $opt_nodelete
            $opt_loop $opt_random $opt_reboot $opt_shut $opt_eject $opt_nodma
            $opt_bootlabel $opt_version
            @languages @kblayouts @fontsets $bootlabels
            @extra_mkisofs_options $extra_mkisofs_options
            @extra_mplayer_options $extra_mplayer_options
            @unwanted_mplayer_options $unwanted_mplayer_options
           );

$NAME="MoviXMaker-2";

$current_path = $0;
$current_path =~ s/movixmaker-2(\.pl)?$//;

if ($0 =~ /^\.\//) {
  $config_file = 'movixmaker-2.conf';
  $glade_dir= '.';
} else {
  $config_file = $config::sysconfdir . '/movixmaker-2.conf';
  $glade_dir = "$current_path../share/movixmaker-2/glade";
}

# Reading the Configuration File
read_config();

# Retrieve options from command line
GetOptions (
# 	    "title=s"             => \$title,
	    "tempDir=s"           => \$opt_tmpdir,
 	    "output-file=s"       => \$destpath,
 	    "boot-label=s"        => \$opt_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,
 	    "loop=i"              => \$opt_loop,
 	    "random!"             => \$opt_random,
 	    "reboot!"             => \$opt_reboot,
 	    "shut!"               => \$opt_shut,
 	    "eject!"              => \$opt_eject,
 	    "nodma!"              => \$opt_nodma,
 	    "nodelete!"           => \$opt_nodelete,
	    "movixDir=s"          => \$srcpath,
 	    "subtitleFonts=s"     => \$opt_fontset,
	    "language=s"          => \$opt_lang,
	    "keyboard=s"          => \$opt_kblayout,
	    "hasQT!"              => \$opt_qt,
	    "hasWMV!"             => \$opt_wmv,
	    "hasASF!"             => \$opt_asf,
	    "verbose!"            => \$opt_verbose,
	    "debug!"              => \$opt_debug,
# 	    "movix-version"       => \$version,
 	    "version"             => \$opt_version,
	    'help|?'              => \$help
	    );

if( defined $help ){
  help();
  exit;
} elsif( defined $opt_version ){
  print "MoviXMaker $config::version\n";
  exit;
}
#################################

prepare_interface();

$SIG{CHLD} = \&child_dead;
$SIG{__WARN__} = \&Carp::cluck;

main Gtk2;
exit;
### end main

sub child_dead {
  if ($child_pid) {
    waitpid ($child_pid, 0);
    $child_pid = 0;
  }
}

# Retrieve options from the configuration line
sub read_config {
  my $cfg = new Config::IniFiles( -file => "$config_file" );

  # Global options
  $opt_debug = $cfg->val('MoviXMaker','debug');
  $opt_verbose = $cfg->val('MoviXMaker','verbose');
  $opt_nodelete = $cfg->val('MoviXMaker','nodelete');

  ## *MoviX* options
  # video codecs
  $opt_asf = $cfg->val('MoviX','asf');
  $opt_qt = $cfg->val('MoviX','qt');
  $opt_wmv = $cfg->val('MoviX','wmv');
  # parameters
  $opt_bootlabel = $cfg->val('MoviX','bootlabel');
  $opt_lang = $cfg->val('MoviX','language');
  $opt_kblayout = $cfg->val('MoviX','kblayout');
  $opt_fontset = $cfg->val('MoviX','fontset');
  $opt_loop = $cfg->val('MoviX','loop');
  $opt_random = $cfg->val('MoviX','random');
  $opt_shut = $cfg->val('MoviX','shutdown');
  $opt_reboot = $cfg->val('MoviX','reboot');
  $opt_eject = $cfg->val('MoviX','eject');
  $opt_nodma = $cfg->val('MoviX','nodma');

  # Other options
  @extra_mkisofs_options = $cfg->val('Others','extra_mkisofs_options');
  @extra_mplayer_options = $cfg->val('Others','extra_mplayer_options');
  @unwanted_mplayer_options = $cfg->val('Others','unwanted_mplayer_options');
}

### callbacks
sub on_exit_activate {
  Gtk2->main_quit;
}

# The user actually quit the application
sub on_MoviXMaker_destroy {
  Gtk2->main_quit;
}

sub gtk_widget_show {
  my ($w1, $w2) = @_;
  $w2->show ();
}

sub gtk_widget_hide {
  my ($w1, $w2) = @_;
  $w2->hide ();
}

sub about_activate {
  my $about_diag = Gnome2::About->new ($NAME, $config::version,
				       '(C) Pascal Giard, 2003',
				       'MoviXMaker is a Perl GTK+-2/Gnome2 interface to create customized [e]MoviX[2] ISO files.
It is available under the terms of the GPL.',
				       'Pascal Giard <evilynux@users.sf.net>');
  $about_diag->show ();
}

sub on_button_create_released {
  my $button = shift;

  $button->set_sensitive(FALSE);
  $destination->set_sensitive(FALSE);
  $srcdir->set_sensitive(FALSE);
  $statusbar->set_status("Proceeding...");

  prepare_iso();
}

# The verbose_mkisofs_output window gets closed by the user
sub on_fbbutton_released {
  $diag_feedback->hide();
  $statusbar->set_status("$NAME $config::version");
  reenable();
}

sub on_option_change {
  $xml_root->get_widget ("prop_apply_btn")->set_sensitive (TRUE);
}

### end callbacks

###############################
### Options and properties
###############

# Defines if we're using the installed eMoviX dir,
# if so, also update the srcpath.
sub using_installed_emovix {
  my $emovix_path = `echo -n \$(movix-conf 2>/dev/null)`;

  $srcpath = "$emovix_path/" unless (defined $srcpath);
  $installed_emovix = ($srcpath =~ /$emovix_path/) ? TRUE : FALSE;
  print "Using installed eMoviX = $installed_emovix\n" if ($opt_debug);
}

sub update_options {
  my @bootlabels = split(/\s/ , $bootlabels);
  $xml_root->get_widget ("combo_bootlabels")->set_popdown_strings(@bootlabels);
  $xml_root->get_widget ("combo_bootlabels")->set_value_in_list(TRUE, FALSE);
  $xml_root->get_widget ("entry_bootlabel")->set_text($opt_bootlabel);

  $xml_root->get_widget ("combo_languages")->set_popdown_strings(@languages);
  $xml_root->get_widget ("combo_languages")->set_value_in_list(FALSE, FALSE);
  $xml_root->get_widget ("entry_language")->set_text($opt_lang);

  $xml_root->get_widget ("combo_fontsets")->set_popdown_strings(@fontsets);
  $xml_root->get_widget ("combo_fontsets")->set_value_in_list(FALSE, FALSE);
  $xml_root->get_widget ("entry_fontset")->set_text($opt_fontset);

  $xml_root->get_widget ("combo_kblayouts")->set_popdown_strings(@kblayouts);
  $xml_root->get_widget ("combo_kblayouts")->set_value_in_list(TRUE, FALSE);
  $xml_root->get_widget ("entry_kblayout")->set_text($opt_kblayout);
}

sub set_options {
  #######
  ## MoviXMaker options
  #######

  # Debug mode.
  $xml_root->get_widget ("cb_debug")->set_active($opt_debug);

  # Verbose mkisofs output.
  $xml_root->get_widget ("cb_verbose")->set_active($opt_verbose);

  # Donnot delete tmp directory
  $xml_root->get_widget ("cb_nodelete")->set_active($opt_nodelete);

  # Temporary directory.
  if (defined $opt_tmpdir && $opt_tmpdir ) {
    $opt_tmpdir =~ s/\.$//;
    $opt_tmpdir =~ s/([^\/])$/$1\// ;
  } else {
    $opt_tmpdir = "/tmp/";
  }
  $xml_root->get_widget ("tmpdir_entry")->set_text($opt_tmpdir);

  #######
  ## mkisofs options
  #######
  if (@extra_mkisofs_options > 0) {
    $extra_mkisofs_options =
      join(' ',split(/,/,join(',',@extra_mkisofs_options)));
    $xml_root->get_widget ("entry_extra_mkisofs_options")->
	set_text($extra_mkisofs_options);
  }
  #######
  ## mplayer options
  #######
  if (@extra_mplayer_options > 0) {
    $extra_mplayer_options = 
      join(' ',split(/,/,join(',',@extra_mplayer_options)));
    $xml_root->get_widget ("entry_extra_mplayer_options")->
	set_text($extra_mplayer_options);
  }

  if (@unwanted_mplayer_options > 0) {
    $unwanted_mplayer_options = 
      join(' ',split(/,/,join(',',@unwanted_mplayer_options)));
    $xml_root->get_widget ("entry_unwanted_mplayer_options")->
			       set_text($unwanted_mplayer_options);
  }
  #######
  ## [e]MoviX[] Options
  #######
  my $dest_file = $xml_root->get_widget ("destdir_entry");
  if ( defined $destpath ) {
    my $pwd = `pwd`;
    $destpath =~ s/^\.[^\.]?\//$pwd\//; # if relative path, making it
                                        # absolute
    $destpath =~ s/\n//;              # removing trailing CR if present
    $destpath =~ s/\.$//;             # removing trailing dot if present
    if ( $destpath =~ /([^\.][^i][^s][^o])$/ ) {
      $destpath =~ s/(\w)$/$1\//;
      $destpath =~ s/(.+)$/$1movix\.iso/; # $destpath has to point
                                          # to a file.
    }
    $dest_file->set_text($destpath);
  } else {
    $dest_file->set_text($opt_tmpdir . "movix.iso");
  }

  if ( defined $srcpath ) {
    my $orig = `echo -n \$(pwd)`;

    chdir $srcpath;
    $srcpath = `echo -n \$(pwd)`;
    chdir $orig;

    $srcpath =~ s/([^\/])$/$1\// ; # Add a trailing /
    $xml_root->get_widget ("srcdir_entry")->set_text($srcpath);

    using_installed_emovix();
  } else {
    using_installed_emovix();
    if (defined $srcpath) {
      $xml_root->get_widget ("srcdir_entry")->set_text($srcpath);
    }
  }

  # Default language.
  if (defined $opt_lang) {
    $xml_root->get_widget ("entry_language")->set_text($opt_lang);
  }
  # Default keyboard layout.
  if (defined $opt_kblayout && $opt_kblayout) {
    $xml_root->get_widget ("entry_kblayout")->
	set_text($opt_kblayout);
  }

  # Default fontset.
  if (defined $opt_fontset && $opt_fontset) {
    $xml_root->get_widget ("entry_fontset")->
	set_text($opt_fontset);
  }

  # Default boot label.
  if (defined $opt_bootlabel && $opt_bootlabel) {
    $xml_root->get_widget ("entry_bootlabel")->
	set_text($opt_bootlabel);
  }

  # Include Quicktime codecs ?
  $xml_root->get_widget ("cb_qt")->set_active($opt_qt);

  # Include ASF codecs ?
  $xml_root->get_widget ("cb_asf")->set_active($opt_asf);

  # Include WMV codecs ?
  $xml_root->get_widget ("cb_wmv")->set_active($opt_wmv);

  # Play movies in random order
  $xml_root->get_widget ("cb_random")->set_active($opt_random);

  # Power off PC after playing all CD files
  $xml_root->get_widget ("cb_shut")->set_active($opt_shut);

  # Reboot PC after playing all CD files
  $xml_root->get_widget ("cb_reboot")->set_active($opt_reboot);

  # Eject the CD
  $xml_root->get_widget ("cb_eject")->set_active($opt_eject);

  # Disable DMA
  $xml_root->get_widget ("cb_nodma")->set_active($opt_nodma);

  # Loop N times the playlist
  if (defined $opt_loop && $opt_loop) {
    $xml_root->get_widget ("entry_loop")->set_text($opt_loop);
  }

  # Renders the apply button insensitive
  $xml_root->get_widget ("prop_apply_btn")->set_sensitive(FALSE);
}

sub get_options {

  ## MoviXMaker options
  #######
  # Debug mode.
  $opt_debug =
    $xml_root->get_widget ("cb_debug")->get_active || 0;

  # Verbose mkisofs output.
  $opt_verbose = $xml_root->get_widget ("cb_verbose")->get_active || 0;

  # Donnot delete tmp dir.
  $opt_nodelete = $xml_root->get_widget ("cb_nodelete")->get_active || 0;

  # Temporary directory.
  $opt_tmpdir = $xml_root->get_widget ("fileentry_tmpdir")->get_full_path(0);
  $opt_tmpdir =~ s/([^\/])$/$1\// ;

  #######
  ## mkisofs options
  #######
  $extra_mkisofs_options =
    $xml_root->get_widget ("entry_extra_mkisofs_options")->get_text;
  #######
  ## mplayer options
  #######
  $extra_mplayer_options =
    $xml_root->get_widget ("entry_extra_mplayer_options")->get_text;
  $unwanted_mplayer_options =
    $xml_root->get_widget ("entry_unwanted_mplayer_options")->get_text;
  #######
  ## [e]MoviX[] Options
  #######
  # Default language.
  $opt_lang = $xml_root->get_widget ("entry_language")->get_text;

  # Default keyboard layout.
  $opt_kblayout = $xml_root->get_widget ("entry_kblayout")->get_text;

  # Default fontset.
  $opt_fontset = $xml_root->get_widget ("entry_fontset")->get_text;

  # Default bootlabel.
  $opt_bootlabel = $xml_root->get_widget ("entry_bootlabel")->get_text;

  # Include Quicktime codecs ?
  $opt_qt = $xml_root->get_widget ("cb_qt")->get_active || 0;

  # Include ASF codecs ?
  $opt_asf = $xml_root->get_widget ("cb_asf")->get_active || 0;

  # Include WMV codecs ?
  $opt_wmv = $xml_root->get_widget ("cb_wmv")->get_active || 0;

  # Play movies in random order
  $opt_random = $xml_root->get_widget ("cb_random")->get_active || 0;

  # Power off PC after playing all CD files
  $opt_shut = $xml_root->get_widget ("cb_shut")->get_active || 0;

  # Reboot PC after playing all CD files
  $opt_reboot = $xml_root->get_widget ("cb_reboot")->get_active || 0;

  # Eject the CD
  $opt_eject = $xml_root->get_widget ("cb_eject")->get_active || 0;

  # Disable DMA
  $opt_nodma = $xml_root->get_widget ("cb_nodma")->get_active || 0;

  # Loop the playlist N times.
  $opt_loop = $xml_root->get_widget ("entry_loop")->get_text;

  $xml_root->get_widget ("prop_apply_btn")->set_sensitive(FALSE);

  if ($opt_debug) {
    print STDERR <<EOL
OPT_DEBUG = $opt_debug
OPT_VERBOSE = $opt_verbose
OPT_NODELETE = $opt_nodelete
EXTRA_MKISOFS_OPTIONS = "$extra_mkisofs_options"
EXTRA_MPLAYER_OPTIONS = "$extra_mplayer_options"
UNWANTED_MPLAYER_OPTIONS = "$unwanted_mplayer_options"
OPT_TMPDIR = "$opt_tmpdir"
OPT_LANG = "$opt_lang"
OPT_KBLAYOUT = "$opt_kblayout"
OPT_FONTSET = "$opt_fontset"
OPT_BOOTLABEL = "$opt_bootlabel"
OPT_QT = $opt_qt
OPT_ASF = $opt_asf
OPT_WMV = $opt_wmv
OPT_LOOP = $opt_loop
OPT_RANDOM = $opt_random
OPT_SHUT = $opt_shut
OPT_REBOOT = $opt_reboot
OPT_EJECT = $opt_eject
OPT_NODMA = $opt_nodma
EOL
  }
}
########################

#################
## Display XWindow
########
sub prepare_interface {
  Gtk2->init;
  Gnome2::Program->init ($NAME, $config::version, 'libgnomeui');

  $xml_root = new Gtk2::GladeXML ($glade_dir."/MoviXMaker-2.glade");
  $xml_root->signal_autoconnect_from_package ('main');

  my $main_win = $xml_root->get_widget ("MoviXMaker");
  $main_win->set_title ("$NAME $config::version");

  $statusbar = $xml_root->get_widget ("statusbar");
  $destination = $xml_root->get_widget ("fileentry_dest");
  $srcdir = $xml_root->get_widget ("fileentry_src");

  # Feedback Dialog
  $diag_feedback = $xml_root->get_widget ("diag_feedback");
  # Properties Dialog
  $diag_properties = $xml_root->get_widget ("diag_properties");
  $diag_properties->set_transient_for ($main_win); # diag_properties ber alles

  #######################
  # Options specified at command line
  # are taken into account here
  ########
  set_options;
  get_options();
  #########################

  $statusbar->set_status("Welcome!");
}

sub reenable {
  $xml_root->get_widget ("button_create")->set_sensitive(TRUE);
  $destination->set_sensitive(TRUE);
  $srcdir->set_sensitive(TRUE);
}

# Display error dialog
sub error {
  my ($err_msg) = @_;
  $statusbar->set_status("An error has occured!");
  print STDERR "ERROR : $err_msg\n" if ($opt_debug);

  my $diag_error =
  	new Gtk2::MessageDialog ($xml_root->get_widget ('MoviXMaker'),
  				 'modal', 'error', 'ok', $err_msg);
  $diag_error->set_title("Error creating disc image");
  $diag_error->signal_connect (response => sub {$_[0]->destroy});
  reenable;
  $diag_error->show_all;
}

# Display warning dialog
sub warning {
  my ($err_msg) = @_;
  print STDERR "WARNING : $err_msg\n" if ($opt_debug);

  my $diag_warning =
  	new Gtk2::MessageDialog ($xml_root->get_widget ('MoviXMaker'),
  				 'modal', 'warning', 'ok', $err_msg);
  $diag_warning->signal_connect (response => sub {$_[0]->destroy});
  $diag_warning->show_all;
}


sub create_iso {
  # Create temp dir and update the global variable
  $tmpfolder = create_tmp_folder();

  my $fbtext = $xml_root->get_widget ("fbtext");
  my $fbtextbuffer;

  # Verbose mkisofs in dialog if enabled
  if ($opt_verbose) {
    $fbtextbuffer = $fbtext->get_buffer;
    $fbtextbuffer->delete($fbtextbuffer->get_iter_at_offset(0),
			  $fbtextbuffer->get_iter_at_offset(-1));
    $diag_feedback->show_all();
  }

  $statusbar->set_status("Calling mkisofs...");

  ############## TAKEN FROM mkmovixiso ###########
  ##################
  ### Standard booting options, from SysLinux docs
  ### and from slackware installation CD README
  ###############
  my $bootOptions = "-no-emul-boot -boot-load-size 4 -boot-info-table ".
    "-b isolinux/isolinux.bin -c isolinux/isolinux.boot ".
      "-sort isolinux/iso.sort";
  ###############
  ### Standard mkisofs options: -v=>verbose, -r=>rock-ridge,
  ####                          -J=>Joliet,  -f=>follow symbolic links
  ##############
  my $stdOptions = "-v -r -J -f";
  #########################################

  $child_pid = open(CMDEXEC,"cd $tmpfolder ; mkisofs -o $destpath $stdOptions ".
		    "-V '$movixversion' $extra_mkisofs_options $bootOptions ".
		    "-A '$movixversion' . 2>&1 |");
  print STDERR "CHILD_PID : $child_pid\n" if ($opt_debug);

  my $progress = $xml_root->get_widget ("progressbar");
  my $diag_progress = $xml_root->get_widget ("diag_progress");

  $progress->set_fraction(0);
  $diag_progress->show;

  my $output; # current line
  my $coutput; # complete output

  while (<CMDEXEC>)
    {
      if ( $_ =~ /([0-9]{1,2}).*done.*(estimate)/i ) {
	my $value = $1;
	print STDERR "WRITING PROGRESS : $value %\n" if ($opt_debug);
	$progress->set_fraction($value/100);
      } elsif ( $_ =~ /(writing|scanning)/i ) {
	$diag_progress->set_title($1);
	$statusbar->set_status($1);
      } elsif ( $_ =~ /mkisofs:\sWarning:\s(.*)/ ) {
	print STDERR "WARNING : $1\n"  if($opt_debug);
      ######
      # Detecting mkisofs errors and rejecting Warnings
      } elsif ( $_ =~ /mkisofs:(.*)/ ) {
	$diag_progress->hide;
	error($1);
      }

      $output = $_;
      $coutput .= $_;

      if ($opt_verbose) {
	my $iter = $fbtextbuffer->get_iter_at_offset(-1); # -1 = end of buffer
	$fbtextbuffer->insert($iter, $output);
      }

      while (Gtk2->events_pending) {
	Gtk2->main_iteration();
      }
    }
  ######
  # Detecting if it created the disc image
  if ( $coutput =~ /extents\swritten\s\(([0-9]+\sMb)\)/ ) {
    $diag_progress->hide;
    my $disc_image_size = $1;
    print STDERR "WROTE : $disc_image_size\n" if ($opt_debug);
    $statusbar->set_status("Disc image created! ($disc_image_size)");
    reenable();
  ######
  # Special treatment for mkisofs --help
  } elsif ( $coutput =~ /Usage:\s(.*)/ ) {
    $coutput =~ s/^.*Warning.*\n//; # We don't want the warnings to be displayed
    $diag_progress->hide;
    $fbtextbuffer->delete($fbtextbuffer->get_iter_at_offset(0),
			  $fbtextbuffer->get_iter_at_offset(-1));
    $fbtextbuffer->insert($fbtextbuffer->get_iter_at_offset(0), $coutput);
    $diag_feedback->show_all();
    reenable();
  }
  ######
  # Deleting the temporary directory
  system "rm -rf '$tmpfolder'" if ( -e $tmpfolder && !$opt_nodelete);
}

# Detects the version of movix contained in the specified directory.
sub get_movix_version {
  return unless (defined $srcpath);

  using_installed_emovix();

  if ($installed_emovix) {
    $movixversion = "eMoviX-" . `echo -n \$(movix-version 2>/dev/null)`;
    $statusbar->set_status("Detected $movixversion.");
    print STDERR "FOUND : $movixversion\n" if ($opt_debug);
    return;
  }

  $statusbar->set_status("Attempting to detect MoviX version...");

  $movixversion = "";

  my $versionFile;

  if ( -e $srcpath."/NEWS" ) {
    $versionFile = $srcpath."/NEWS";
  } else {
    $versionFile = $srcpath."/ChangeLog";
  }

  if ( open CF, $versionFile ) {
    my $version = "";
    while (<CF>) {
      $version = $_;
      last if ($version =~ m/\*\se?MoviX/);
    }
    close CF;

    if ( $version =~ /(e?MoviX2?[-\s]([0-9]\.){2}[0-9]((pre|rc)[0-9]{1,2})?(cvs[0-9]{8})?)/ ) {
      $movixversion = $1;
      $statusbar->set_status("Detected $movixversion.");
      print STDERR "FOUND : $movixversion\n" if ($opt_debug);
    } else {
      $statusbar->set_status("Not a valid *MoviX* directory.");
    }
  } else {
    $statusbar->set_status("Not a valid *MoviX* directory.");
    return;
  }
}

# Tries to detect the available languages
sub get_languages {
  my $dir = "${srcpath}boot-messages";
  opendir (LP, $dir);
  my @files = grep { /^[a-z]{2,3}$/ && -d "$dir/$_" } readdir(LP);
  closedir LP;

  @files = qw(en) unless (@files);

  return @files;
}

# Detects the available keyboard layouts
sub get_kblayouts {
  my $dir = "${srcpath}keyboard-i18n";
  opendir (LP, $dir);
  my @files = grep { /^[a-z]{2,3}$/ && -d "$dir/$_" } readdir(LP);
  closedir LP;

  @files = qw(us) unless (@files);

  return @files;
}

# Detects the available fontsets
sub get_fontsets {
  my $dir = "${srcpath}mplayer-fonts";
  opendir (LP, $dir);
  my @files = grep { /^[a-z]{2,}$/ && -d "$dir/$_" } readdir(LP);
  closedir LP;

  @files = qw(latin) unless (@files);

  return @files;
}

# Detects the available bootlabels
sub get_bootlabels {
  my $list;
  my $src = $installed_emovix ? "" : "src/";

  open FILE, $srcpath."${src}isolinux/isolinux.cfg" or die $!;
  while ( <FILE> ) {
    chomp;
    $list .= "$1 " if ($_ =~ /^label\s([a-zA-Z0-9]+)$/);
  }
  close (FILE);
  return $list;
}

sub validate_language {
  my $choosen_lang;
  foreach my $lang (@languages) {
    $choosen_lang = $opt_lang if ($lang =~ /$opt_lang/);
  }
  return "en" unless $choosen_lang;
}

sub validate_kblayout {
  my $choosen_kblayout;
  foreach my $kblayout (@kblayouts) {
    $choosen_kblayout = $opt_kblayout if ($kblayout =~ /$opt_kblayout/);
  }
  return "us" unless $choosen_kblayout;
}

sub validate_fontset {
  my $choosen_fontset;
  foreach my $fontset (@fontsets) {
    $choosen_fontset = $opt_fontset if ($fontset =~ /$opt_fontset/);
  }
  return "latin" unless $choosen_fontset;
}

sub validate_bootlabel {
  my $choosen_bootlabel;
  my $default = $1                       # eMoviX's default boot
    if ($movixversion =~ /e?(MoviX2?)/); # label is MoviX
  $choosen_bootlabel = $opt_bootlabel if $bootlabels =~ /\W$opt_bootlabel\W/;
  return $default unless $choosen_bootlabel;
}

sub get_movix_options {
  @languages = get_languages;
  @kblayouts = get_kblayouts;
  @fontsets = get_fontsets;
  $bootlabels = get_bootlabels();
  $opt_lang = validate_language();
  $opt_kblayout = validate_kblayout();
  $opt_fontset = validate_fontset();
  $opt_bootlabel = validate_bootlabel();

  if ($opt_debug) {
    print STDERR "FOUND LANGUAGE(S) : ";
    foreach my $file (@languages) {
      print STDERR "$file ";
    }
    print STDERR ".\n";
    print STDERR "FOUND KBLAYOUT(S) : ";
    foreach my $file (@kblayouts) {
      print STDERR "$file ";
    }
    print STDERR ".\n";
    print STDERR "FOUND FONTSET(S) : ";
    foreach my $file (@fontsets) {
      print STDERR "$file ";
    }
    print STDERR ".\n";
    print STDERR
      "FOUND BOOTLABELS : " . $bootlabels . ".\n".
	"EFFECTIVE LANG : " . $opt_lang . ".\n".
	  "EFFECTIVE KBLAYOUT : " . $opt_kblayout . ".\n".
	    "EFFECTIVE FONTSET : " . $opt_fontset . ".\n".
	      "EFFECTIVE BOOTLABEL : " . $opt_bootlabel . ".\n";
  }
}

sub prepare_iso {
  $destpath = $destination->get_full_path(0);
  $srcpath = $srcdir->get_full_path(0);
  $srcpath =~ s/([^\/])$/$1\// ; # Add a trailing /

  print "Preparing ISO using movixDir: " . $srcpath . "\n"
      if ($opt_debug);

  get_movix_version();

  if (!$srcpath || !$destpath)
    {
      $statusbar->set_status("Specify a dir and destination file!");
      reenable();
    }
  else
    {
      if (!$movixversion){
	$statusbar->set_status("That's not a [e]MoviX[] dir!");
	reenable();
      } else {
	# Now that we know that it's a valid *MoviX* path, let's detect
	# what's available.
	get_movix_options();

	# Update the interface with avail. options
	update_options();

	# Did the user toggled the "Do not customize disc image" checkbox ?
	if ($xml_root->get_widget ("cb_nocustomize")->get_active)
	  {
	    # Directly creating the image, no customization
	    create_iso() if (defined $srcpath);
	  }
	else
	  {
	    # Let's choose the options
	    $xml_root->get_widget ("diag_customize")->show()
	      if (defined $srcpath);
	  }
      }
    }
}

# Creates the directory that will be used to create the ISO disc image
sub create_tmp_folder {
  my $date = `date +%s`;
  chop $date;
  my $src = $installed_emovix ? "" : "src/";
  my $origDir = `echo -n \$(pwd)`;
  my $tmpDir = "${opt_tmpdir}movix-$date";
  mkdir  "$tmpDir";

  if ( -e $tmpDir ) {
    chdir  "$tmpDir";
    mkdir  "movix";
    system "ln -s ${srcpath}${src}movix/* movix";

    if ( -e "${srcpath}${src}/movix/win32" ) {
      system "rm -f movix/win32";
      mkdir  "movix/win32";
      system "ln -s ${srcpath}${src}movix/win32/* movix/win32/";
      system "rm -f movix/win32/divxa32.acm"
	unless defined $opt_asf or defined $opt_wmv;
      system "rm -f movix/win32/wmv8ds32.ax"
	unless defined $opt_asf or defined $opt_wmv;
      system "rm -f movix/win32/[Qq]*" unless defined $opt_qt;
    }

    mkdir  "isolinux";
    system "ln -s ${srcpath}${src}isolinux/* isolinux";

    if ( -e "${srcpath}${src}mplayer" )
      {
	mkdir  "mplayer";
	system "ln -s ${srcpath}${src}mplayer/* mplayer";
      }

    if ( -e $srcpath . "keyboard-i18n/" . $opt_kblayout ) {
      # Link the isolinux boot-keymap to the selected keyboard layout
      system "ln -s ${srcpath}keyboard-i18n/${opt_kblayout}/bootkey.map ".
	"isolinux/bootkey.map";
      # Link the selected shell keymap
      system "ln -s ${srcpath}keyboard-i18n/${opt_kblayout}/shellkey.map ".
	"movix/shellkey.map";
    }

    # Usefull because the user might not be able to write to the original
    # isolinux.bin
    system "rm -f isolinux/isolinux.bin";
    system "cp ${srcpath}${src}isolinux/isolinux.bin isolinux/isolinux.bin";

    if ( -e $srcpath . "boot-messages/" . $opt_lang ) {
      system "rm -f isolinux/*txt";
      system "ln -s ${srcpath}boot-messages/${opt_lang}/*txt isolinux";
    }

    if ( -e $srcpath . "mplayer-fonts" ) {
      my $fontDir = "mplayer/font";
      system "mkdir -p $fontDir";
      system "ln -s ${srcpath}mplayer-fonts/$opt_fontset/* $fontDir"
	if ( -e $srcpath . "mplayer-fonts/" . $opt_fontset );
      system "ln -s ${srcpath}mplayer-fonts/*.ttf $fontDir/.";
    }

    if ( defined $opt_bootlabel ) {
      my $isolinuxcfg = "default $opt_bootlabel\n";
      open CFG, "isolinux/isolinux.cfg";
      <CFG>;
      while (<CFG>) {
	$isolinuxcfg .= $_;
      }
      close CFG;
      system "rm -f isolinux/isolinux.cfg";
      open CFG, "> isolinux/isolinux.cfg";
      print CFG $isolinuxcfg;
      close CFG;
    }

    open BOOTRC, "> movix/bootrc";
    print BOOTRC "EXTRA-MPLAYER-OPTIONS=$extra_mplayer_options\n"
      if (defined $extra_mplayer_options && $extra_mplayer_options);
    print BOOTRC "UNWANTED-MPLAYER-OPTIONS=$unwanted_mplayer_options\n"
      if (defined $unwanted_mplayer_options && $unwanted_mplayer_options);
    print BOOTRC "LOOP=$opt_loop\n" if ($opt_loop != 0);
    print BOOTRC "SHUT=y\n"     if ($opt_shut != 0);
    print BOOTRC "REBOOT=y\n"   if ($opt_reboot != 0);
    print BOOTRC "RANDOM=y\n"   if ($opt_random != 0);
    print BOOTRC "EJECT=y\n"    if ($opt_eject != 0);
    print BOOTRC "DMA=n\n"      if ($opt_nodma != 0);
    close BOOTRC;

    chdir  "$origDir";
    return $tmpDir;
  } else {
    my $badpath = $1 if ( $tmpDir =~ /(.*\/).*$/ );
    error("$badpath does not exist!");
  }
}

######## TAKEN FROM mkmovixiso ############
####  Command line help
######################
sub help {
    print
"Usage: movixmaker-2[.pl] [options]
Note: All options that may be abbreviated to uniqueness
      can use a single dash.
Options:

 Generic:

   --verbose               Verbose mkisofs output
   --debug                 Debug mode (kind of movixmaker verbose)
   --version               Displays MoviXMaker's version and exits
   --nodelete              Don't delete temporary directory
   --output-file=<file>    Name [with full path!] of the output iso image
   --tmpDir=<path>         Directory that will contain the temporary files

 *MoviX*:
   --boot-label=<label>    Make MoviX boot by default with your favorite label
   --language=<lang>       Specify the language of the CD boot messages
   --keyboard=<lang>       Specify the keyboard layout to use
   --movixDir=<dir>        Location of the *movix* directory
   --loop=<k>              Make MPlayer play k times your files before stopping
                           [0=infinity]
   --random                Make MPlayer play your files in random order
   --nodma                 Make MoviX run with DMA turned off
                           (fixes old-HDs issues)
   --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
   --extra-mkisofs-options=\"opt1 opt2 ...\"
                           Extra options for mkisofs
   --extra-mplayer-options=\"opt1 opt2 ...\"
                           Extra options for MPlayer
   --unwanted-mplayer-options=\"opt1 opt2 ...\"
                           Options you want to be sure MPlayer will not use
   --help                  This help
   --subtitleFonts=lang    Specify which font set will be included in iso image.\n";
}

# Man pages for MoviXMaker-2
=pod

=head1 NAME

MoviXMaker-2 - Easily create customized eMoviX/MoviX/MoviX2 disc images

=head1 SYNOPSIS

    movixmaker-2[.pl] [--version|--help] [--verbose] [--debug]
                  [--nodelete] [--language=Language]
                  [--subtitleFonts=FontSet]
                  [--keyboard=KbLayout] [--movix=MovixSrcDir]
                  [-o=OutputFile] [-t=TempDir] [-b=BootLabel]
                  [--loop=NbrOfLoops] [--random] [--nodma]
                  [--eject] [--reboot] [--shut]
                  [--hasQT] [--hasWMV] [--hasASF]
                  [--extra-mkisofs-options="opt1 opt2 ..."]
                  [--extra-mplayer-options="opt1 opt2 ..."]
                  [--unwanted-mplayer-options="opt1 opt2 ..."]

=head1 DESCRIPTION

I<MoviXMaker> is a simple Perl GTK+-2/Gnome2/GladeXML interface to create
customized eMoviX/MoviX/MoviX ISO files.

It includes disc image customization possibilities such as :
 - language, keyboard layout, subtitle fontset, boot label
   selection when available (e.g. eMoviX has those).
 - you can specify [e]MoviX[] parameters such as :
   loop, random, shut, reboot, eject, dma, extra_mplayer_options and
   unwanted_mplayer_options.

=head1 OPTIONS

All options that may be abbreviated to uniqueness can use a single dash.

=head2 --version

=over

Displays MoviXMaker-2's version and exits.

=back

=head2 --help

=over

Display help messages [similar to this help] then exits.

=back

=head2 --verbose

=over

Verbose mkisofs output.

=back

=head2 --debug

=over

Debug mode (kind of movixmaker-2 verbose).

=back

=head2 --nodelete

=over

Don't delete temporary directory.

=back

=head2 --language=I<Language>

=over

Specify the language of the CD boot messages.

=back

=head2 --subtitleFonts=I<FontSet>

=over

Specify which font set will be included in iso image.

=back

=head2 -k I<KbLayout>, --keyboard=I<KbLayout>

=over

Specify the keyboard layout to use.

=back

=head2 -m I<MovixSrcDir>, --movixDir=I<MovixSrcDir>

=over

Location of the *MoviX* directory.

=back

=head2 -o I<OutputFile>, --output-file=I<OutputFile>

=over

Name [with full path!] of the output iso image.

=back

=head2 -t I<TempDir>, --tmpDir=I<TempDir>

=over

Directory that will contain the temporary files.

=back

=head2 -b I<BootLabel>, --boot-label=I<BootLabel>

=over

Make *MoviX* boot with your favorite label (new default boot label).

=back

=head2 --loop=I<NbrOfLoops>

=over

Don't delete temporary directory.

=back

=head2 --random

=over

Don't delete temporary directory.

=back

=head2 --nodma

=over

Make *MoviX* run with DMA turned off (fixes old-HDs issues).

=back

=head2 --eject

=over

Make *MoviX* eject the CD once it finished playing.

=back

=head2 --reboot

=over

Make *MoviX* reboot the PC once it finished playing.

=back

=head2 --shut

=over

Make *MoviX* poweroff the PC once it finished playing.

=back

=head2 --hasQT, --hasWMV, --hasASF

=over

Include dll files required to play quicktime, window media video or ASF
files.

=back

=head2 --extra-mkisofs-options="opt1 opt2 ..."

=over

Extra options for mkisofs.

=back

=head2 --extra-mplayer-options="opt1 opt2 ..."

=over

Extra options for MPlayer.

=back

=head2 --unwanted-mplayer-options="opt1 opt2 ..."

=over

Options you want to be sure MPlayer will not use.

=back

=head1 AUTHOR

Pascal Giard, E<lt>evilynux@yahoo.comE<gt>

=head1 COPYRIGHT

Copyright (C) 2003 Pascal Giard E<lt>evilynux@yahoo.comE<gt>

This package is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

=head1 SEE ALSO

L<Gnome2(3)>, L<Gtk2(3)>, L<Getopt::Long(3)>, L<Config::IniFiles(3)>

=cut

########################
