#!/usr/bin/perl

### get the name used to call this script...
$0 =~ /\/(\w+)$/;
$scriptName = $1;
### there can be an argument: the dvd or vcd chapter
$N = $ARGV[0];

$modLog = "/tmp/modprobe.log";
$modErr = "/tmp/modprobe.err";
$cdMntLog = "/tmp/cdMount.log";
$cdMntErr = "/tmp/cdMount.err";

open STDERR, ">> /tmp/movix.log";

$mp_pipe  = "/root/.mplayer/mp_pipe";

########################################
### Getting rid of the junk on the screen
###############
# we don't want kernel msgs on-screen...
`echo "3 4 1 7" > /proc/sys/kernel/printk`;
system "clear";

### This is needed because for some strange bug only the first two user boot args
### are actually exported as env variables
readRCFile();
loadBootParm();

$shut = $RC{'shut'};
$shut = $ENV{'SHUT'} if exists $ENV{'SHUT'};
$random = $RC{'random'};
$random = $ENV{'RANDOM'} if exists $ENV{'RANDOM'};
$loop = $RC{'loop'};
$loop = $ENV{'LOOP'} if exists $ENV{'LOOP'};
$loop = 1 unless $loop =~ /^\d+$/;
$eject = $RC{'eject'};
$eject = $ENV{'EJECT'} if exists $ENV{'EJECT'};
$reboot = $RC{'reboot'};
$reboot = $ENV{'REBOOT'} if exists $ENV{'REBOOT'};
$dma = $RC{'dma'};
$dma = $ENV{'DMA'} if exists $ENV{'DMA'};
$slow = $RC{'slow'};
$slow = $ENV{'SLOW'} if exists $ENV{'SLOW'};
$region = $RC{'region'};
$region = $ENV{'REGION'} if exists $ENV{'REGION'};
$dxr3 = $RC{'dxr3'};
$dxr3 = $ENV{'DXR3'} if exists $ENV{'DXR3'};

# Check if the subhelp was deactivated in the movixrc
$subhelp = exists $RC{'noSubhelp'} ?
                  $RC{'noSubhelp'} =~ /^[yY]/ ?
                    0 : 1 :
           1;

##########################################################
### Making sure no other movix.pl process is running...
#######
#my @ids;
#foreach (`ps auxw`){
##  print "$_\n";
#  push @ids, $1 if /^\w+\s+(\d+)\s+.+(movix.pl|mplayer)/;
#}
##print "ids = @ids\n";
##print "pr = $$";
#foreach (@ids){
#  `kill -9 $_` unless $_ == $$;
#>}

foreach (split " ", `ls /dev/cdroms/cdrom*`){
  /(\d+)$/;
  `mkdir -p /cdrom$1`;
  `mount -t supermount -o fs=iso9660:udf:vfat,dev=/dev/cdroms/cdrom$1,--,ro,norock,utf8 none /cdrom$1 >> $cdMntLog 2>> $cdMntErr`
    unless `grep cdrom$1 /etc/mtab` =~ /cdrom$i/;
}

########################################
### Mounting the right CD on /cdrom...
###############
$dvd_device = "";
$cdrom_device = "";
`rm -f /tmp/movix.list`;
cdDetect($scriptName,$N) unless $scriptName =~ /^play/;

system "echo \"The movie will start in a few seconds...\"";
#sleep(2) unless $scriptName eq "dvd";

########################################
### Building the mplayer options
###############

########################################
### Checking for an AGP card...
###############
open(PCI,"/proc/pci");
while(<PCI>){
    next unless /^\s*Bus  1/;
    $bus = "AGP";
    last;
}
close PCI;
$bus = "PCI" unless $bus eq "AGP";

########################################
### Identifying your video card
###############
open(PCI,"/proc/pci");
while(<PCI>){
    if( $bus eq "PCI" ){
	next unless /^\s*VGA compatible controller\:/;
	$videoCardLine = $_;
	last;
    } else {
	next unless /^\s*Bus  1/;
	$videoCardLine = <PCI>;
	last;
    }
}
close(PCI);
if( $videoCardLine !~ /^\s*VGA compatible controller\:/ ){
    print "I can't find any video card entry in your /proc/pci file, this is extremely odd!\n";
    print "Most likely the movie won't manage to start...\n";
}

#######################################
### Checking for a Dx3/H+ card...
###############
open(PCI,"/proc/pci");
while(<PCI>){
    next unless /^\s*Multimedia controller/;
    $videoCardLine = "DXR3/H+" if /REALmagic Hollywood Plus|dxr3/i and $dxr3 !~ /^n/i;
    last;
}
close PCI;

######
##  Just spotting "special" video cards for setting later special options
####
$videoCard = "NVidia"     if $videoCardLine =~ /geforce/i;
$videoCard = "3Dfx"       if $videoCardLine =~ /voodoo/i;
$videoCard = "Savage"     if $videoCardLine =~ /savage/i;
$videoCard = "Ati"        if $videoCardLine =~ /ATI Technologies/i;
$videoCard = "DXR3/H+"    if $videoCardLine eq "DXR3/H+";
$videoCard = "Matrox"     if $videoCardLine =~ /Matrox.+ G[245][05]0/i;
$videoCard = "CyberBlade" if $videoCardLine =~ /CyberBlade/i;

########################################
### Evaluating your CPU speed
###############
open(CPUINFO,"/proc/cpuinfo");
while(<CPUINFO>){
    if( /^cpu MHz\s*\:\s*(\d+)/ ){
	$mhz = $1;
    }
}
close CPUINFO;
###################
## We are going to compare this value with a fixed $MHZ value
## in order to enable sw accel. if the CPU is fast enough and
## the card is not natively accelerated by mplayer.
##################
### Thanks to Eivind Kjorstad for his nice suggestion about framefrop!
$fMHZ  = 290;  ## few MHZ
$vfMHZ = 200;  ## very few MHZ!

########################################
### Evaluating the best options for your video card
### The idea is:
### 1. default label     - try to get the best options trying to set
###                        fullscreen play when it seems reasonable
### 2. vesa & FB labels  - do not even try to resize the screen by hw or sw means.
###                        It is intended only as last hope for machines on which
###                        the default does not work.#
##############
## Apparently the "vesa" driver works much better *without* the "-fs" option
## so now are it makes more sense to add it when needed than taking it off!
#$options = "-quiet -fs ";
$options = "-quiet -framedrop ";
### -vop eq activates software brightness/contrast controls
$vop = "eq";

## apparently there are cards that do not work if we explicitly use "-ao alsa9"!
#$aodriver = "alsa9";

# If the AUDIO variable is set to an integer, ALSA is explicitly selected and
# set to the selected hardware
if ($ENV{"AUDIO"} =~ /^\d+$/) {
	$aodriver = "alsa9:hw:" . $ENV{"AUDIO"} . ",0";
}

########################################
### In case use of the "vesa" driver is forced...
###############
if( $ENV{"LABEL"} eq "vesa" ){
  $vodriver   = "vesa";
  if( $videoCardLine =~ /Radeon|Mach64| Rage |G200|G400|G450|G550|CyberBlade/i and $ENV{"ACCEL"} !~ /sw|no/ ){
    $vodriver .= ":vidix";
    $options  .= "-fs -zoom ";
  } elsif( ( $mhz > $fMHZ and $ENV{"ACCEL"} ne "no" ) or $ENV{"ACCEL"} eq "sw" ) {
    $vop .= ",expand=800:600";
    $vop .= ",scale=800:-2";
  } else {
#    $options .= "-framedrop ";
    $options  .= "-fs -zoom ";
    $options =~ s/ -framedrop / -hardframedrop /
      if $mhz < $vfMHZ;
  }
  ########################################
  ### In case use of the "aa" driver is forced...
  ###############
} elsif( $ENV{"LABEL"} eq "aa" ){
  $vodriver   = "aa";
  $options   .= "-aabold -aadim -aadriver linux -aafloyd_steinberg -aadimmul 1.71 -aaboldmul 1.43 -aacontrast 30 -really-quiet ";
  system "setfont /usr/share/kbd/consolefonts/lat1-08.psfu.gz";
  #    if( $ENV{'FBRES'} =~ /^(\d+)x(\d+)$/ ){
  #      system "fbset -xres $1 -yres $2";
  #    }
  ########################################
  ### In case use of the sdl driver is forced...
  ###############
} elsif( $ENV{"LABEL"} eq "sdl" ){
  unless( -e "/dev/fb0" ){
    system "echo \"No FrameBuffer device has been detected, the sdl driver can't run without it :-(\"";
    system "echo \"Please reboot and select a different driver\"";
    reboot(5);
  }
  $vodriver = "sdl";
  $xSize    = getFBxSize();
  if( $mhz > $fMHZ ) {
    $vop .= ",scale=$xSize:-2";
    ## Can't understand why but there is A-V sync loss even though in my PC the same options work fine
    ## so until I'll find a solution it is good to add a framedrop to keep audio & video on sync
#    $options .= "-framedrop ";
  }
  system "ln -s /dev/misc/psaux /dev/mouse";
  ########################################
  ### In case use of the vesa generic FrameBuffer driver is forced...
  ###############
} elsif( $ENV{"LABEL"} eq "vesaFB" ) {
  $vodriver = "fbdev";
  $xSize    = getFBxSize();
  $ySize    = getFBySize();
  $options .= "-geometry 50%:50% ";
  if( $videoCardLine =~ /Radeon|Mach64| Rage |G200|G400|G450|G550|CyberBlade/i and $ENV{"ACCEL"} !~ /sw|no/ ){
    ### Warning: -fs w/fbdev driver crashes MPlayer if the video rez
    ### is bigger than the screen rez.
    ### But if we don't add "-fs" then the movie won't be resized anymore.
    ### Someone should fix this bug eventually...
    $vodriver .= ":vidix";
    $options .= "-fs ";
  } elsif( ( $mhz > $fMHZ and $ENV{"ACCEL"} ne "no" ) or $ENV{"ACCEL"} eq "sw" ) {
    $vop .= ",expand=$xSize:$ySize";
    $vop .= ",scale=$xSize:-2";
  } else {
#    $options .= "-framedrop ";
    $options =~ s/ -framedrop / -hardframedrop /
      if $mhz < $vfMHZ;
  }
  ########################################
  ### In case use of the FrameBuffer specific card driver is forced...
  ###############
} elsif( $ENV{"LABEL"} eq "FB" ) {
  unless( -e "/dev/fb0" ){
    system "echo \"No FrameBuffer device has been detected, the fbdev driver can't run without it :-(\"";
    system "echo \"Please reboot and select a different driver\"";
    system "echo \"(press F2 at the boot prompt for a complete list)\"";
    reboot(5);
  }
  $vodriver = "fbdev";
  $vodriver = "tdfxfb" if $videoCard eq "3Dfx";
  $xSize = 800;
  $ySize = 600;
  $options .= "-geometry 50%:50% ";
  if( $videoCardLine =~ /Radeon|Mach64| Rage |G200|G400|G450|G550|CyberBlade/i and $ENV{"ACCEL"} !~ /sw|no/ ){
    ### Warning: -fs w/fbdev driver crashes MPlayer if the video rez
    ### is bigger than the screen rez.
    ### But if we don't add "-fs" then the movie won't be resized anymore.
    ### Someone should fix this bug eventually...
    $vodriver .= ":vidix";
    $options .= "-fs ";
  } elsif( ( $mhz > $fMHZ and $ENV{"ACCEL"} ne "no" ) or $ENV{"ACCEL"} eq "sw" ) {
    $vop .= ",expand=$xSize:$ySize";
    $vop .= ",scale=$xSize:-2";
  } else {
#    $options .= "-framedrop ";
    $options =~ s/ -framedrop / -hardframedrop /
      if $mhz < $vfMHZ;
  }
  ## Setting the right parameters for the FB...
  ## btw, it's set to 16bpp since my radeon do not go higher than that :-)
  ## maybe a parameter may be introduce to allow users choose their own
  ## (or maybe a menu?)
  system "fbset -t 17762 152 32 27 1 64 3 -g $xSize $ySize $xSize $ySize 16 -hsync high -vsync high";
#  system "fbset -depth 32 -xres $xSize -yres $ySize";
#  system "fbset -depth 24 -xres 640 -yres 480";
  #######################################
  ###  In case we need to use TV-out
  ###  we may have to run a few utilities...
  ###  Thanks a lot to Balazs Barany and Nico Berndt for providing the commands
  ###  I'm using below!
  ################################
} elsif( $ENV{"LABEL"} eq "TV" ) {

  # Should the framebuffer be set to 32 colors later? 
  # This will later be set to false if necessary.
  $canChangeFB = true;

  if ($videoCard eq "Savage") {
    # Trying to select the appropriated region code.
    if ( defined $region ) {
      if ( $region =~ /ntsc-j/i ) {
        $region = "NTSCJ";
      } elsif ( $region =~ /ntsc/i ) {
        $region = "NTSC";
      } elsif ( $region =~ /pal/i ) {
        $region = "PAL";
      }
      system "s3switch tv $region >> /tmp/s3switch.log 2>> /tmp/s3switch.err";
    } else {
	  # Use the default region setting of the chip. Also, on some systems,
	  # s3switch segfaults if any of the REGIONs is set.
      system "s3switch tv >> /tmp/s3switch.log 2>> /tmp/s3switch.err";
    }
    $vodriver = "vesa";
    # picture may get too tall without -zoom (jopu)
    $options .= "-fs -zoom ";

  } elsif( $videoCard eq "NVidia" ) {

    my ( $xrez, $yrez ) = ( 768, 576 );

    ( $xrez, $yrez ) = ( 800, 600 )
      if defined $region and $region =~ /ntsc/i;

    # switch into the full TV resolution, this works for PAL
    system "fbset -t 20203 40 0 63 29 56 4 -g $xrez $yrez $xrez $yrez 32 -bcast true -a"
      if $region =~ /pal/i;

    my $nvtv = "nvtv -r $xrez,$yrez -s Large --set flicker:25 -t";
    $nvtv .= " -S $region" if  defined $region;
    system "$nvtv";

    $vodriver = "fbdev";
    $vop .= ",scale=$xrez:-2";

  } elsif ($videoCard eq "Matrox") {
    
    # This is model dependent. Feedback to balazs@tud.at
    if ($videoCardLine =~ /Matrox.+G[45]50/i ) {
      # G450, G550: info from http://www.bglug.ca/matrox_tvout/
      # set up the output
      system "modprobe matroxfb_crtc2";
      system "matroxset -f /dev/fb0 -m 5";
      system "matroxset -f /dev/fb1 -m 2";
      $fb = 'fb1';
      # switch to the full TV resolution (This is PAL. NTSC, anyone?)
      system "fbset -fb /dev/$fb -xres 768 -yres 576 -depth 32 -upper 44 -lower 4 -vslen 1";
    } elsif ($videoCardLine =~ /Matrox.+G400/i ) {
    # G400: info from http://www.netnode.de/howto/matrox-fb.html
      # loading modules takes time
      system "echo \"or more...\"";
      system "modprobe matroxfb_crtc2";
      system "modprobe -s mga_vid        >> $modLog 2>> $modErr";
      system "modprobe -s matroxfb_maven >> $modLog 2>> $modErr";
      system "modprobe -s i2c-matroxfb   >> $modLog 2>> $modErr";
      # set up the output
      system "matroxset -f /dev/fb1 -m 0";
      system "matroxset -f /dev/fb0 -m 3";
      $fb = 'fb1';
      $vodriver = 'mga';
      $options .= "-fs ";
      # switch into the full TV resolution, this works for PAL
      system "fbset -g 768 576 768 576 32 -t 20203 40 0 63 29 56 4 -bcast true";
      # change contrast and saturation of G400 TV-out by setting hardware registers
      # hue is reg 0x25, brightness is reg 0x0e
      system "matrox 0x1e 0xb0 > /dev/null 2> /dev/null";
      system "matrox 0x20 0xcc > /dev/null 2> /dev/null";
      system "matrox 0x22 0xcc > /dev/null 2> /dev/null";
    } elsif ($videoCardLine =~ /Matrox.+G200/i ) {
      # G200: info from http://marvel.sourceforge.net/
      # set up the output
      system "matroxset -f /dev/fb0 -m 3";
      $fb = 'fb0';
      # switch to the full TV resolution (this is PAL. NTSC, anyone?)
      system "fbset -g 768 576 768 576 32 -t 20203 40 0 63 29 56 4 -bcast true";
    }

    # Trying to select the appropriate region code,
    # "-o 1 1" is for PAL, "-o 1 2" for NTSC.
    if ( defined $region ) {
      if ( $region =~ /ntsc/i ) {
	# Needs testing, if someone has this plz contact Pascal Giard.
        $region = "2";
      } elsif ( $region =~ /pal/i ) {
        $region = "1";
      }
      system "matroxset -f /dev/$fb -o 1 $region";
    } else {
      system "matroxset -f /dev/$fb -o 1 1";
    }
    
    if ($videoCardLine !~ /Matrox.+G400/i ) {
      # The G400 can use mga, others can't, so they use the framebuffer
      
      # Output to the framebuffer where the TV is
      $vodriver = "fbdev";
      $options .= "-fb /dev/$fb ";
      
      # Expand to the framebuffer size so the video is in the middle
      $vop .= ",expand=768:576";
      
      if ( ( $mhz > $fMHZ and $ENV{"ACCEL"} ne "no" ) or $ENV{"ACCEL"} eq "sw" ) {
	# Scale to the PAL width and the appropriate height
	$vop .= ",scale=720:-2";
      }
    }
    
    # The framebuffer has been already set up, don't change it later
    $canChangeFB = 0;
  } elsif( $videoCard eq "Ati" ) {
    $vodriver = "vesa:vidix";
  } else {
    $vodriver = "vesa";
  }

  # vesa can't change the framebuffer, other drivers sometimes can.
  if ($vodriver eq "vesa") {
    $canChangeFB = 0;
  }

  ##################
  ###  and now for the default case...
  ##########################################
} else {
  #################
  ##  Matrox 200/400/450/550 can take advantage
  ##  of the special mga_vid driver!
  #################
  if ( $videoCard eq "Matrox" ){
    system "modprobe -s matroxfb_base  >> $modLog 2>> $modErr";
    system "modprobe -s mga_vid        >> $modLog 2>> $modErr";
#    system "modprobe -s i2c-matroxfb   >> $modLog 2>> $modErr"; # only for TVout!
#    system "modprobe -s matroxfb_maven >> $modLog 2>> $modErr"; # only for TVout!
    if( -e "/dev/mga_vid" and -e "/dev/fb0" ){
      $vodriver = "mga";
      $options .= "-fs ";
      ## Making sure the color depth is 32bpp...
      system "fbset -depth 32 -xres 800 -yres 600";
    } else {
      $vodriver = "vesa:vidix";
      $options .= "-zoom ";
    }
    #################
    ##  Trident CyberBlade cards
    #################
  } elsif ( $videoCard eq "CyberBlade" ) {
    system "modprobe -s fbgen";
    my $kernelVersion = `uname -r`;
    chop $kernelVersion;
    system "insmod /lib/modules/$kernelVersion/kernel/drivers/video/epiafb.o.gz";
    ### Taken from http://sourceforge.net/forum/forum.php?thread_id=756152&forum_id=221920
    system "fbset -t 17762 152 32 27 1 64 3 -g 800 600 800 600 24 -hsync high -vsync high -a";
    #################
    ##  3Dfx Voodoo cards have a special mplayer driver!
    #################
  } elsif ( $videoCard eq "3Dfx" ) {
    $vodriver   = "tdfxfb";
    system "modprobe -s tdfxfb >> $modLog 2>> $modErr";
    unless( -e "/dev/fb0" ){
      system "echo \"No FrameBuffer device has been detected, the fbdev driver can't run without it :-(\"";
      system "echo \"Please reboot and select a different driver\"";
      system "echo \"(press F2 at the boot prompt for a complete list)\"";
      reboot(5);
    }
    $xSize = 800;
    $ySize = 600;
    system "fbset -g $xSize $ySize $xSize $ySize 16";
    #################
    ##  DXR3/H+ cards have their special mplayer driver too!
    #################
  } elsif ( $videoCard eq "DXR3/H+" ) {
    system "modprobe -s i2c-core                                     >> $modLog 2>> $modErre";
    system "modprobe -s adv717x swap_redblue_pal=1 pixelport_16bit=0 >> $modLog 2>> $modErr";
    system "modprobe -s bt865                                        >> $modLog 2>> $modErr";
    system "modprobe -s em8300 bt865_ucode_timeout=1                 >> $modLog 2>> $modErr";
    system "em8300setup";
    $vodriver  = "dxr3:prebuf:sync:/dev/em8300_mv-0";
    $aodriver  = "oss:/dev/em8300_ma-0";
    $options  .= "-vc mpegpes ";
    #################
    ##  Unless you have a 3Dfx, a Matrox or a Dxr3/H+, you end up using the fbdev or vesa
    ##  driver depending on the CPU speed and video card model
    ##  with or without the "vidix" driver depending on the mplayer support for you card
    #################
  } else {
    if( -e "/dev/fb0" and ( $mhz > $fMHZ or $videoCardLine =~ /Radeon|Mach64| Rage |G200|G400|G450|G550|CyberBlade/i ) ){
      $vodriver = "fbdev";
      $xSize    = getFBxSize();
      $ySize    = getFBySize();
      $options .= "-geometry 50%:50% ";
      if( $videoCardLine =~ /Radeon|Mach64| Rage |G200|G400|G450|G550|CyberBlade/i and $ENV{"ACCEL"} !~ /sw|no/ ){
	### Warning: -fs w/fbdev driver crashes MPlayer if the video rez
	### is bigger than the screen rez.
	### But if we don't add "-fs" then the movie won't be resized anymore.
	### Someone should fix this bug eventually...
	$vodriver .= ":vidix";
	$options .= "-fs ";
      } elsif( ( $mhz > $fMHZ and $ENV{"ACCEL"} ne "no" ) or $ENV{"ACCEL"} eq "sw" ) {
	$vop .= ",expand=$xSize:$ySize";
	$vop .= ",scale=$xSize:-2";
      } else {
#	$options .= "-framedrop ";
	$options =~ s/ -framedrop / -hardframedrop /
	  if $mhz < $vfMHZ;
      }
      ### Unfortunately there are cards that do not support the vesaFB...
    } else {
      $vodriver = "vesa";
      if( $videoCardLine =~ /Radeon|Mach64| Rage |G200|G400|G450|G550|CyberBlade/i and $ENV{"ACCEL"} !~ /sw|no/ ){
	$vodriver .= ":vidix";
	$options  .= "-fs -zoom ";
      } elsif( ( $mhz > $fMHZ and $ENV{"ACCEL"} ne "no" ) or $ENV{"ACCEL"} eq "sw" ) {
	$vop .= ",expand=800:600";
	$vop .= ",scale=800:-2";
      } else {
#	$options .= "-framedrop ";
	$options =~ s/ \-framedrop / \-hardframedrop /
	  if $mhz < $vfMHZ;
	$options  .= "-fs -zoom ";
      }
    }
  }
}
###################
### Let the user override the automatic vo driver selection
###########
$vodriver = $ENV{"VO_DRIVER"} if defined $ENV{"VO_DRIVER"};

### If we're using 'fbdev' then we cannot change video format on the fly
if( $vodriver eq "fbdev" ){
  $menu = `cat /root/.mplayer/menu.conf`;
  $menu =~ s/<e name="(.+)" ok="set_menu aspect"\/>//;
  open MENU, "> /root/.mplayer/menu.conf";
  print MENU $menu;
  close MENU;
}

################
### Adding CD cache option and other optimizations, from a suggestion by Jose' Fandinho
#################
`free` =~ /Mem:\s+\d+\s+\d+\s+(\d+)/;
$cache = $1 > 12000 ? 8192 : 1024;
$options .= "-cache $cache -autoq 6 ";
$vop .= ",pp=lb:a";
# interesting settings appeared on the MPlayer ML
# on the other side, it seems video quality gets poorer with all this stuff!
#$vop .= ",pp=hb:128:20:a/vb:128:20:a/dr:a/al:a/lb:a";
################
### Other sparse options:
### -double is needed to avoid subtitles blinking
### -idx forces the reconstruction of the index for broken avi files
### -menu activates the nice mplayer menu feature
### -nooverlapsub turns off an annoying new mplayer subtitles feature
###  [hw ones are available only for a few drivers]
### -input file=$mp_pipe allows sending commands to a running mplayer
###  session 'cat'-ing them to the pipe
#################
$options .= "-idx -menu -nooverlapsub -input file=$mp_pipe ";
$options .= "-double "        unless $ENV{"LABEL"} eq "sdl";
## $options .= "-loop $loop "    if $loop =~ /^\d+$/;
$options .= "-shuffle "       if $random eq "y";
### This is needed to avoid vesa to die when trying to use vesa:vidix together
### with the mpeg12 filter - many thanks to A.V.Kuznetsov for this hint!
$options .= "-vc ffmpeg12, "      if $vodriver =~ /^vesa/;

## Now we can add our vop options
$options .= "-vop $vop ";

###################
### Let the user add mplayer options at will
### WARNING: eventually we shoud check somehow that no new vop option
### is added or it will override our ones!
###########
$options .= " $ENV{'MP_OPTIONS'} " if defined $ENV{'MP_OPTIONS'};

###################
### Let's finally modify the options according to the .movixrc file
###########
$options .= $RC{"extra-mplayer-options"}." " if exists $RC{"extra-mplayer-options"};
if( exists $RC{"unwanted-mplayer-options"} ){
  $RC{"unwanted-mplayer-options"} =~ s/\s+/ /g;
  $RC{"unwanted-mplayer-options"} =~ s/^\s+//;
  $RC{"unwanted-mplayer-options"} =~ s/\s+$//;
  @options = split " ", $RC{"unwanted-mplayer-options"};
  foreach $option (@options){
    $options =~ s/$option / /;
  }
}

#######################################3
####  Playing all files in /cdrom...
##############
$mplayer = "/usr/local/bin/mplayer";
$mDir    = "/cdrom/";
$log     = "/tmp/mplayer.log";
$err     = "/tmp/mplayer.err";

##################################################
### Playing the items in the list
##################################################
$mplayerArgs  = "-vo $vodriver ";
$mplayerArgs .= "-ao $aodriver " if $aodriver ne "";
$mplayerArgs .= "$options ";

if ( -e "/tmp/movix.music.avi" ) {
	$mplayerArgs .= "-menucp utf8 -bgvideo /tmp/movix.music.avi ";
}

######################################################
### Saving the options for the end of the playback
####################
$mplayerOptions = $mplayerArgs;

##################################################
### Creating the MPlayer play options depending
### whether we are trying to play an eMoviX CD
### or a ACD/VCD/DVD/MCD
###################
$mplayerArgs .= mplayerPlayOption($scriptName);

# Check if we need/can show the subhelp
if ( -e '/tmp/subhelp.show') {
  if (! $mplayerArgs !~ / -sub /) {
  # No other sub file is given

    # Add the help sub
    $mplayerArgs .= ' -sub /root/.mplayer/helpsub.sub -subcp utf8 ';
    
    # Remember that the help sub was already shown
    `touch /tmp/subhelp.shown`;
    `rm /tmp/subhelp.show`;
  }

}

# if we just wanted to get a playlist, we're done
exit if $scriptName =~ /list/;

### we want a log except for the "aa" case, because in
### that case only the movie is shown as STDOUT of mplayer!!!
$mplayerArgs .= " >> $log" unless $ENV{"LABEL"} eq "aa" or $scriptName eq "mcd";
$mplayerArgs .= " 2>> $err";
system "echo \"Running $mplayer $mplayerArgs\" >> $log";
#################
## this is to avoid a blanking cursor that appears with some card under the vesa vo driver
###########################
system "setterm -cursor off" unless $ENV{"LABEL"} eq "aa";

# Time to turn off the bootsplash
system "echo verbose > /proc/splash";

#############
### Finally we can run mplayer!
##########################################

SWITCH: {
  playcd($scriptN), exit          if $scriptName eq "playcd";
  playcd($1), exit                if $scriptName =~ /^playcd(\d+)$/;
  playacd($scriptN), exit         if $scriptName eq "playacd";
  playacd($1), exit               if $scriptName =~ /^playacd(\d+)$/;
  playvcd($1), exit               if $scriptName =~ /^playvcd(\d*)$/;
  playdvd($1), exit               if $scriptName =~ /^playdvd(\d*)$/;
}

my $i = $loop;
while( $loop == 0 or $i-- > 0 ){
  `echo "off" > /proc/splash`
    if -e "/dev/fb/0" and `cat /proc/fb` =~ /VESA/;
  system "clear ; $mplayer $mplayerArgs; echo \$? > /tmp/mplayer.exitcode";
  `echo "on" > /proc/splash`
    if -e "/dev/fb/0" and `cat /proc/fb` =~ /VESA/;
}

### Eject the CD if asked to
#$getridof = $eject eq "y" ? "eject" : "umount";
`ls -l /cdrom` =~ /cdrom(\d)/;
$cdDev = "/dev/cdroms/cdrom$1";
$cdDev = $1 if $mplayerArgs =~ /(?:-dvd-device|-cdrom-device) ([\S]+) /;

system "echo \"$getridof $cdDev\" >> $cdMntLog 2>> $cdMntErr";
system "eject $cdDev" if $eject =~ /y/i;

clearInfoSub();

if( $shut eq "y" ){
    system "echo \"The system will shut down in 5 seconds!\"";
    for( my $i=0; $i < 5; $i++ ){
	sleep(1);
	system "echo -n \".\"";
    }
    system "poweroff";
} elsif( $reboot eq "y" ) {
    system "echo \"The system will reboot in 5 seconds!\"";
    for( my $i=0; $i < 5; $i++ ){
	sleep(1);
	system "echo -n \".\"";
    }
    system "brc";
} else {
  # 166 is the "halt" exit code of mplayer
  while(`cat /tmp/mplayer.exitcode` !~ /166/ ){
    `clear`;
    `echo "off" > /proc/splash`
      if -e "/dev/fb/0" and `cat /proc/fb` =~ /VESA/;
    
    # With AsciiArt output, we can't really use the menu
    last if $ENV{"LABEL"} eq "aa"; 
    
    # Start the menu again
    `$mplayer $mplayerOptions -menu-disp /tmp/movix.music.avi -loop 0 \\
			  >> $log 2>> $err ; \\
	 echo \$? > /tmp/mplayer.exitcode`;
    
    `echo "on" > /proc/splash`
      if -e "/dev/fb/0" and `cat /proc/fb` =~ /VESA/;
  }
  ##############
  ## turning the cursor back on
  ############
  system "setterm -cursor on";

  print "\n\nEnd of the show...\n";
  print "\nHave a nice day :-)\n";
}

###################################################
#########################################
########################
sub loadBootParm {
  my @pairs = split " ", `cat /proc/cmdline`;
  foreach my $pair (@pairs) {
    next unless $pair =~ /^([^\=]+)\=(.+)$/;
    $ENV{$1} = $2;
  }
}

sub readRCFile {
  return unless -e "/root/.movixrc";
  open RC, "/root/.movixrc";
  while(<RC>){
    next if /^\#/ or /^\s*$/;
    next unless /^([^=]+)=(.+)$/;
    $RC{$1}=$2;
  }
  close RC;
}

sub reboot {
    my $sec = shift;
    $sec = 5 unless $sec =~ /^\d+$/;
    system "echo \"The system will reboot in $sec seconds!\"";
    for( my $i=0; $i < $sec; $i++ ){
	sleep(1);
	system "echo -n \".\"";
    }
    system "brc";
}

sub getFBxSize {
    my $xSize;
    open FBINFO, "fbset |";
    while(<FBINFO>){
#        print "$_";
        if( /^mode\s+\"(\d+)x\d+/ ){
            $xSize = $1;
            last;
        }
    }
    close FBINFO;
    return $xSize;
}

sub getFBySize {
    my $ySize;
    open FBINFO, "fbset |";
    while(<FBINFO>){
#        print "$_";
        if( /^mode\s+\"\d+x(\d+)/ ){
            $ySize = $1;
            last;
        }
    }
    close FBINFO;
    return $ySize;
}

sub cdDetect {
  my $sn = shift;
  my $N  = shift;

  print "Looking for your cd...\n";
  foreach my $cdDev (split " ", `ls /dev/cdroms/cdrom*`){
    if( $sn eq "dvd" ){
      my $n = $N > 0 ? $N : 1;
      $id = `mplayer -identify -dvd-device $cdDev dvd://$n 2> /dev/null`;
      if($id =~ /DVD successfully opened/){
	print "DVD found in $cdDev!\n";
	$dvd_device = $cdDev;
	last;
      }
    } elsif( $sn eq "vcd" ) {
      $id = `mplayer -identify -cdrom-device $cdDev vcd://$N 2> /dev/null`;
      if($id =~ /MPEG-PS file format detected/){
	print "VCD found in $cdDev!\n";
	$cdrom_device = $cdDev;
	last;
      }
    } elsif( $sn eq "acd" ) {
      $id = `mplayer -identify -cdrom-device $cdDev cdda:// 2> /dev/null`;
      if($id =~ /Found Audio CD/){
	print "AudioCD found in $cdDev!\n";
	$cdrom_device = $cdDev;
	last;
      }
    } else {

      $cdDev =~ /cdrom(\d+)$/;
      $i = $1;
      next if defined $N and $N != $i;

      system "rm -f /cdrom ; ln -s /cdrom$i /cdrom";
      #      $cdrom = "/cdrom$i";
      $movixCheckFile = "/cdrom$i/eMoviX/boot/movix.lss";
      #      system "cd /; umount /cdrom" if `grep cdrom /etc/mtab`;
      #system "mount $cdDev /cdrom -t iso9660 >> $cdMntLog 2>> $cdMntErr";
      if( -e $movixCheckFile and $sn ne "mcd" ){
	print "Found eMoviX cd on $cdDev!\n";
	### Setting hw parameters of the CD device:
	### dma on, read-ahead set to 8 sectors (4k), irq unmasking on, mode set to udma2
	system "hdparm -d1 -a8 -u1 -X34 $cdDev >> $cdMntLog 2>> $cdMntErr"
	  unless $dma =~ /^[nN]/;
	### Decreasing the CD-ROMs speed to reduce the noise unless negated at boot time
	system "eject -x 12 $cdDev" unless $slow =~ /^[nN]/;
	### Copy the right set of fonts from the MoviX cd...
	print "Setting up your fonts...\n";
	`rm -f /tmp/subfont.ttf /tmp/font/* /root/.mplayer/subfont.ttf /root/.mplayer/font`;
	if( -e "/cdrom/eMoviX/font" ){
	  `cp -a /cdrom/eMoviX/font/ /tmp/`;
	  `ln -s /tmp/font/  /root/.mplayer/`;
	} else {
#	  `cp -a /cdrom/eMoviX/mplayer/subfont.ttf /tmp/`;
	    foreach (`ls /cdrom/eMoviX/mplayer/*ttf`){
		chop;
		`cp -a $_ /tmp/subfont.ttf`;
		last;
	    }
	  `ln -s /tmp/subfont.ttf /root/.mplayer/`;
	}
	if( `ls /usr/local/mplayer/share/mplayer/font/*.gz 2>/dev/null` ){
	  # unpack fonts if they are gzipped
	  system "for gz in /usr/local/mplayer/share/mplayer/font/*.gz; do
	              chmod 644 \$gz
	              gunzip \$gz 2>/dev/null
	          done";
	}

		#Search for audio files and create subtitles for them
		getAudioFiles("/cdrom/");		

	last;
      } else {
	# No Movix system found - look for media files in the root dir of the CD
	my @files;
	foreach (("[aA][vV][iI]","[mM][oO][vV]","[mM][pP][gG]","[mM][pP][eE][gG]","[aA][sS][fF]","[wW][mM][vV]","[mM][pP]3","[oO][gG][gG]")){
	  push @files, `find /cdrom/ -name \"*.$_\"`;
	  last if @files > 0;
	}
	# No media files on the CD - unmount it
	if (@files == 0) {
	  #system "umount /cdrom >> $cdMntLog 2>> $cdMntErr";
	} else {
	  print "Found media files on $cdDev!\n";
	  `eject -x 12 $cdDev` unless $slow =~ /^[nN]/;

		#Search for audio files and create subtitles for them
		getAudioFiles("/cdrom/");		

	  last;
	}
      }
    }
  }
  closedir(CD);
  if( !-e $movixCheckFile and @files == 0 and $dvd_device eq "" and $cdrom-device eq "" ){
    print "Could not find your eMoviX-CD/ACD/VCD/DVD!\nMaybe you are using a USB cd or something stranger:\nunfortunately MoviX until now supports only IDE or SCSI drives, but of course it would be very nice if you'd write a patch and send it to the author that would happily add it to next release :-)\n";
  }
}

sub mplayerPlayOption {
  my $sn = shift;
  my @audioTracks;
  my %audioTracks;
  my $at;
  my @subsTracks;
  my %subsTracks;
  my $st;
  my $title;

  if( $sn eq "dvd" ){
    my $dvd_opts = "-dvd-device $dvd_device ";
    ### if no track no has been given, play the longest track
    if( ! ($N > 0 ) ){ 
      @tracks = split "\n", `lsdvd $dvd_device 2> /dev/null`;
      $N = 0;
      $l1 = 0;
      foreach (@tracks){
	/Title\: 0?(\d+), Length\: (\d+)\:(\d+)\:(\d+)/;
	$l2 = $2*3600+$3*60+$4;
	if( $l2 > $l1 ){
	  $N = $1;
	  $l1 = $l2;
	}
      }
    }
    
    foreach my $line (split "\n", `lsdvd -a -s -t $N $dvd_device 2> /dev/null` ){
      $line =~ s/^\s*//;
      $title = $1 if $line =~ /^Disc Title\: (.+)$/;
      push @audioTracks, $line if $line =~ /^Audio/;
      push @subsTracks,  $line if $line =~ /^Subti/;
    }      

    print "\nDisc Title: $title" unless $title =~ /^\s*$/;

    unless (@audioTracks == 1){
      print "\nThere are multiple audio tracks on this DVD:\n\n";
      foreach (@audioTracks){
	/Audio\: 0?(\d+), Language\: (\w+) /;
	$audioTracks{$1} = $2;
	print "$_\n";
      }
      print "\nSelect the one you want and press ENTER: ";
      $at = <STDIN>;
      chop $at;
    }
    $dvd_opts .= "-alang $audioTracks{$at} " if defined $audioTracks{$at};

    unless (@subsTracks == 0){
      print "\nYou can choose among the following subtitles sets:\n\n";
      foreach (@subsTracks){
	/Subtitle\: 0?(\d+), Language\: (\w+) /;
	print "$_\n";
	$subsTracks{$1} = $2;
      }
      print "\nSelect the subtitles you want and press ENTER (0 = no subtitles): ";
      $st = <STDIN>;
      chop $st;
    }
    $dvd_opts .= "-slang $subsTracks{$st} " if defined $subsTracks{$st};

    `eject -x 12 $dvd_device` unless $slow =~ /^[nN]/;
    
    $dvd_opts .= " dvd://$N ";
    return $dvd_opts;
  } elsif ($sn eq "vcd" ){
    `eject -x 12 $cdrom_device` unless $slow =~ /^[nN]/;
    return "-cdrom-device $cdrom_device vcd://$N ";
  } elsif ($sn eq "acd" ){
    `eject -x 12 $cdrom_device` unless $slow =~ /^[nN]/;
    return "-cdrom-device $cdrom_device cdda:// ";
  } elsif ($sn eq "mcd" ){
    # mp3 cd patch from Jochen Puchalla <mail@puchalla-online.de>
    system "find $mDir -name '*.mp3' > /tmp/playlist";
    system "find $mDir -name '*.MP3' >> /tmp/playlist";
    system "find $mDir -name '*.ogg' >> /tmp/playlist";
    system "find $mDir -name '*.OGG' >> /tmp/playlist";
    system "find $mDir -name '*.wav' >> /tmp/playlist";
    system "find $mDir -name '*.WAV' >> /tmp/playlist";
    system "sort /tmp/playlist > /tmp/movix.list";
    return "-playlist /tmp/movix.list ";
  } else {
    ##################################################
    ### Creating the list of all files to play
    ### in case no default list [i.e. named movix.*] is found
    ##################
    $playlist = undef;
    if( defined $ENV{"LIST"} and -e "$mDir$ENV{LIST}" ){
      $playlist = $mDir.$ENV{"LIST"};
    } elsif( -e "$mDir/movix.asx" ){
      $playlist = "$mDir/movix.asx";
    } elsif ( -e "$mDir/movix.txt" ) {
      $playlist = "$mDir/movix.txt";
    } elsif ( -e "$mDir/movix.list" ) {
      $playlist = "$mDir/movix.list";
    } elsif ( -e "$mDir/movix.m3u" ) {
      $playlist = "$mDir/movix.m3u";
    }
    if( ! defined $playlist ) {

      my @files;
      foreach (("[aA][vV][iI]","[mM][pP][gG]","[mM][oO][vV]","[mM][pP][eE][gG]","[aA][sS][fF]","[wW][mM][vV]","[mM][pP]3","[oO][gG][gG]","[oO][gG][mM]")){
        push @files, split "\n", `find /cdrom/ -name \"*.$_\"`;
      }
      my $list = "";
      foreach (sort @files){
        if (! /movix.music.avi/) {
          $list .= "$_\n";
	        #unless /movix.music.avi/;
        }
      }
      $playlist = "/tmp/movix.list";
      `echo \"$list\" > $playlist`;
    }

	# Look for file extensions in the root of the CD-ROM. If there is only one,
	# we can show the subhelp because there won't be any sub files there.
    my @rootfiles;
    push @rootfiles, split "\n", `find /cdrom/ -type f -maxdepth 1 \\
                                    \| perl -pwe 's/^.*(\\.[^.]+)/\$1/' \\
                                    \| sort \\
									\| uniq `;
    my $filecount = scalar(@rootfiles);

    # but we don't want to count playlists! (if any)
    foreach (@rootfiles) {
	$filecount-- if /movix\.(asx|txt|list|m3u)$/;
    }

    # Check if the short subhelp was already shown, the first file is a movie
    # file, there is only one file extension and we are allowed to show the subhelp
    if (! -e '/tmp/subhelp.shown' &&
      $filecount == 1 &&
      $subhelp == 1 &&
      $loop == 1 &&
      `head -1 $playlist` =~ /\.(avi|mpe?g|ogm|wmv|asf|mov)$/i ) {
      `touch /tmp/subhelp.show`;
    }
	
    return "-playlist $playlist ";
  }
}

# Create subtitles for audio files
sub createInfoSub {
  my $file = shift;
#  chop $file;
  $file =~ /\/([^\/]+)\.(mp3|ogg|wav)$/i;
  #print STDERR "++++++++++  file = $file, r = $1\n";
  open INFO, "> /root/.mplayer/sub/$1.sub";
  print INFO "[SUBTITLE]\n00:00:00.00,10:00:00.00\n";
  print INFO "File: $file [br] [br]";

  my $getInfoCmd = mediaInfoProg($file);
  my $i=0;
  foreach ( split "\n", `$getInfoCmd` ){
  	# BUG in mplayer: only 8 lines can be shown, mplayer will crash if there are
	# more. Therefore, the "Playback length" line of ogginfo is commented out.
    print INFO "Title: $3"."[br]"           and $i++ if /^\s+([Tt]itle(: |=)(.+))$/;
    print INFO "Artist: $3"."[br]"          and $i++ if /^\s+([Aa]rtist(: |=)(.+))$/;
    print INFO "Album: $3"."[br]"           and $i++ if /^\s+([Aa]lbum(: |=)(.+))$/;
    print INFO "Date: $3"."[br]"            and $i++ if /^\s+((Year: |date=)(.+))$/;
    print INFO "Genre: $3"."[br]"           and $i++ if /^\s+([Gg]enre(: |=)(.+))$/;
#    print INFO "Playback length: $3"."[br]" and $i++ if /^\s+(Playback length(: |=)(.+))$/;
  }
  print INFO " [br]" if $i > 0;
  close INFO;
}

# Delete auto-created subtitles
sub clearInfoSub {
  `rm -f /root/.mplayer/sub/*.sub`;
}

# Decides on the right command for getting info on media files
sub mediaInfoProg {
	my $file = shift;
	
	if ( $file =~ /\.ogg$/i ) {
		return("/usr/bin/ogginfo \"$file\"");
	} else {
		return("/usr/bin/mplayer -identify \"$file\" 2>/dev/null");
	}
}

# Stolen from movix 0.8.1pre3 movix.pl - go over the list of files and
# create info files for them
sub getAudioFiles {
  my $partition = shift;
  #print STDERR "partition = $partition\n";
  my @list;
  my $mntPoint = $partition;

  push @list, `find \"$mntPoint\" -name \"*.[mM][pP]3\"`;
  push @list, `find \"$mntPoint\" -name \"*.[oO][gG][gG]\"`;
  push @list, `find \"$mntPoint\" -name \"*.[wW][aA][vV]\"`;

  foreach (@list){
    s/^\s*//;
    chop;
    createInfoSub($_);
  }
  return sort @list;
}

sub getAudioVideoFiles {
  my $partition    = shift;
  my $random       = shift;
  my $notrecursive = shift;
#  print STDERR "partition = $partition\n";
  my @list;
  my $mntPoint = $partition;
  if( $partition =~ /^\/dev\/cdroms\/cdrom(\d+)$/ ){
    $mntPoint = "/cdrom$1/";
#    $mntPoint = "/cdrom/";
#    system "mount $partition /cdrom/";
    `eject -x 12 $partition` unless $slow =~ /^[nN]/;
  }

  my $find;
  ### next line is there only to let the system automount the CD
  `ls $mntPoint > /dev/null 2>&1` if $mntPoint =~ /^\/cdrom/;
  foreach ("avi","mpg","mpeg","mov","asf","wmv","wav","mp3","mp4","ogg","ogm","m2v","vob") {
    $find = "find";
    $find .= " \"$mntPoint\" -iname \"*.$_\"";
    $find .= " | sort";
    push @list, `$find`;
    ### sample old instruction
    #push @list, `find \"$mntPoint\" -iname \"*.avi\"`;
  }

  foreach (@list){
    s/^\s*//;
    chop;
    createInfoSub($_) if /.(mp3|ogg)$/;
  }

  return sort @list;
}

sub writePlaylist {
  my ($fileName,@list) = @_;
  open PLAYLIST, "> $fileName" or die "can't open $fileName :-(\n";
  foreach (@list){
    print PLAYLIST "$_\n";
  }
  close PLAYLIST;
}

sub playcd {
  my $N = shift;
  $N = 0 unless $N =~ /^\d+$/;
  writePlaylist($playlist,getAudioVideoFiles("/dev/cdroms/cdrom$N"))
      unless $playlist =~ /^\/cdrom/;
  `echo "off" > /proc/splash` if -e "/dev/fb/0" and `cat /proc/fb` =~ /VESA/;
  `echo 'loadlist $playlist' > $mp_pipe`;
  `echo 'set_menu null' > $mp_pipe`;
  `eject -x 12 /dev/cdroms/cdrom$N` unless $slow =~ /^[nN]/;
}

sub playacd {
  my $N = shift;
  $N = 0 unless $N =~ /^\d+$/;
  `echo "off" > /proc/splash` if -e "/dev/fb/0" and `cat /proc/fb` =~ /VESA/;
  `ln -sf /dev/cdroms/cdrom$N /dev/cdrom`;
  `echo 'play_cdda' > $mp_pipe`;
  `eject -x 12 /dev/cdroms/cdrom$N` unless $slow =~ /^[nN]/;
  `echo 'set_menu null' > $mp_pipe`;
}

sub playvcd {
  my $N = shift;
  $N = 0 unless $N =~ /^\d+$/;
  `ln -sf /dev/cdroms/cdrom$N /dev/cdrom`;
  `echo "off" > /proc/splash` if -e "/dev/fb/0" and `cat /proc/fb` =~ /VESA/;
#  `ln -sf /dev/cdroms/cdrom$N /dev/cdrom`;
  `echo 'play_vcd' > $mp_pipe`;
  `eject -x 12 /dev/cdroms/cdrom$N` unless $slow =~ /^[nN]/;
  `echo 'set_menu null' > $mp_pipe`;
}

sub playdvd {
  my $N = shift;
  $N = 0 unless $N =~ /^\d+$/;
  `ln -sf /dev/cdroms/cdrom$N /dev/dvd`;
  `echo "off" > /proc/splash` if -e "/dev/fb/0" and `cat /proc/fb` =~ /VESA/;
#  `ln -sf /dev/cdroms/cdrom$N /dev/dvd`;
  `echo 'play_dvd' > $mp_pipe`;
  `eject -x 12 /dev/cdroms/cdrom$N` unless $slow =~ /^[nN]/;
  `echo 'set_menu null' > $mp_pipe`;
}

