# 
# This class is a base class for themes 
# for the jobeditor and vdr2iso.
# A theme is a way to paint DVD-Menus and - of cause -
#  a way to ask the user for optional settings.
#       written by ...: geronimo at vdrportal dot de
# 
# COPYRIGHT:   (c) 2006 Creative Commons by-nc-sa
#               some rights reserved. For details on copyright see:
#               http://creativecommons.org/licenses/by-nc-sa
#
# DISCLAIMER:   NO WARANTY AT ALL. Use at your own risk.
# 
# vi: ts=3
#
package V2I::Theme;

use strict;
use Data::Dumper;
use Carp qw(carp croak);
use Storable qw(dclone);
use File::Basename;

my $debug = 0;
 
sub supportedUserVars {
   my $rv = {};

   $rv->{'jfont'}   = [qw(header title item summary)];
   $rv->{'jimage'}  = [qw(bg)];
   $rv->{'saspect'} = [qw(4:3)];

   return $rv;
}

sub getFontLimits {
   return { header =>[20,200]
          , title  =>[20,100]
          , item   =>[11, 80]
          , summary=>[11, 70]};
}

sub defaultValues {
   my $rv = {};

   $rv->{'headerfont'}  = {value=>'', size=>90, color=>'red'};
   $rv->{'titlefont'}   = {value=>'', size=>30, color=>'blue'};
   $rv->{'itemfont'}    = {value=>'', size=>20, color=>'cyan1'};
   $rv->{'summaryfont'} = {value=>'', size=>16, color=>'springgreen1'};
   $rv->{'bgimage'}     = {value=>'', anchor=>'bottom', color=>'blue'};
   $rv->{'aspect'}      = '4:3';

   return $rv;
}

sub importFlat {
   my $self = shift;
   my $flatArgs = shift;

   foreach my $cat (keys(%{$self->{'uv'}})){
           print('import category <'.$cat.">\n") if $debug;
           if($cat =~ /^j/){
              my $name = substr($cat, 1);     

              foreach my $entry (@{$self->{'uv'}{$cat}}){
                      if($name =~ /^font$/){
                         foreach my $elem (qw(value size color)){
                                 if($elem eq 'value'){     
                                    if(not $flatArgs->{$entry.$name} eq 'unset'){
                                       $self->{'def'}{$entry.$name}{value} = $flatArgs->{$entry.$name};     
                                       }
                                    }
                                 else{
                                    if(not $flatArgs->{$entry.$name.$elem} eq 'unset'){
                                       $self->{'def'}{$entry.$name}{$elem} = $flatArgs->{$entry.$name.$elem};     
                                       }
                                    }
                                 }
                         }
                      elsif($name =~ /^image$/){
                         foreach my $elem (qw(value anchor color)){
                                 if($elem eq 'value'){     
                                    if(not $flatArgs->{$entry.$name} eq 'unset'){
                                       $self->{'def'}{$entry.$name}{value} = $flatArgs->{$entry.$name};     
                                       }
                                    }
                                 else{
                                    if(not $flatArgs->{$entry.$name.$elem} eq 'unset'){
                                       $self->{'def'}{$entry.$name}{$elem} = $flatArgs->{$entry.$name.$elem};     
                                       }
                                    }
                                 }
                         }
                      elsif($name =~ /^color$/){
                         print('looking for <'.$entry.$name.">\n") if $debug;
     
                         if(not $flatArgs->{$entry.$name} eq 'unset'){
                            $self->{'def'}{$entry.$name}{value} = $flatArgs->{$entry.$name};     
                            }
                         }
                      else{ croak('Oups, unknown category: <'.$name.'>'); }
                      }
              }
           elsif($cat =~ /^n/){
              my $name = substr($cat, 1);     
     
              if(not $flatArgs->{$name} eq 'unset'){
                 $self->{$name} = $flatArgs->{$name};
                 }
              }
           elsif($cat =~ /^s/){
              my $name = substr($cat, 1);     
     
              if(not $flatArgs->{$name} eq 'unset'){
                 my $valid = 0;
                 
                 foreach my $ve (@{$self->{'uv'}{$cat}}){
                         print('validate <'.$name.'> ['.$flatArgs->{$name}.']<>['.$ve."]\n") if $debug;
                         if($flatArgs->{$name} eq $ve){
                            $valid = 1;
                            last;
                            }
                         }
                 croak('invalid value ['.$flatArgs->{$name}.'] for property <'.$name.'>') if(not $valid);
                 $self->{$name} = $flatArgs->{$name};
                 }
              }
           elsif($cat eq 'flat'){
              foreach my $property (@{$self->{'uv'}{$cat}}){     
                      $self->{'def'}{$property} = $flatArgs->{$property} if not $flatArgs->{$property} eq 'unset';  
                      }
              }
           }
}

sub importHash {
   my $self = shift;
   my $cfgRef = shift;

   croak('invalid call ('.ref($cfgRef).' <> HASH expected) !') if not ref($cfgRef) eq 'HASH';
   foreach my $property ($self->getProperties){
           print(ref($self).'::importHash() ... have to import property <'.$property.">\n") if $debug;     
           if(exists($cfgRef->{$property})){
              if(ref($cfgRef->{$property})){ $self->{'def'}{$property} = dclone($cfgRef->{$property}); }
              else{ $self->{'def'}{$property} = $cfgRef->{$property}; }
              }
           }
}

sub getFlatArgs {
   my $self = shift;
   my $rv = {};

   foreach my $cat (keys(%{$self->{'uv'}})){
           print('process category <'.$cat.">\n") if $debug;     
           if($cat =~ /^j/){
              my $name = substr($cat, 1);
              
              foreach my $entry (@{$self->{'uv'}{$cat}}){
                      if($name =~ /^font$/){
                         foreach (qw(value size color)){
                                 $rv->{$entry.$name} = 'unset' if $_ eq 'value';     
                                 $rv->{$entry.$name.$_} = 'unset' if not $_ eq 'value';     
                                 }
                         }
                      elsif($name =~ /^color$/){
                         print('getFlatArgs() color<'.$entry.">\n") if $debug;
                         $rv->{$entry.$name} = 'unset';
                         }
                      elsif($name =~ /^image$/){
                         foreach (qw(value anchor color)){
                                 $rv->{$entry.$name} = 'unset' if $_ eq 'value';     
                                 $rv->{$entry.$name.$_} = 'unset' if not $_ eq 'value';     
                                 }
                         }
                      else{ print('Oups, unknown category: <'.$name.">\n"); }
                      }
              }
           elsif($cat =~ /^(?:s|n)/){
              my $name = substr($cat, 1);
     
              $rv->{$name} = 'unset';     
              }
           elsif($cat eq 'flat'){
              foreach my $property (@{$self->{'uv'}{$cat}}){     
                      $rv->{$property} = 'unset';
                      }
              }
           else{ croak('invalid definition of suppportedUserVars in '.ref($self)); }
           }
   return $rv;
}

sub getProperties {
   my $self = shift;
   my @rv;

   foreach my $cat (keys(%{$self->{'uv'}})){
           print('process category <'.$cat.">\n") if $debug;
           for($cat){
              /^j/       and do { my $name = substr($cat, 1);

                                  foreach my $entry (@{$self->{'uv'}{$cat}}){
                                          push(@rv, $entry.$name);     
                                          }
                                  last;
                                  };
              /^(?:s|n)/ and do { my $name = substr($cat, 1);

                                  push(@rv, $name);     
                                  last;
                                  };
              /^flat/    and do { foreach my $entry (@{$self->{'uv'}{$cat}}){
                                          push(@rv, $entry);     
                                          }
                                  last;
                                  };
              push(@rv, $cat);     
              }
           }
   return @rv;   
}

sub init {
   my $self = shift;
   my $args = shift;

   if(ref($args->[0]) eq 'HASH'){
      if(ref($args->[0]{'titlefont'}) eq 'HASH'){
         $self->importHash($args->[0]);     
         }
      else{
         my $validArgs = $self->getFlatArgs;
         my $hash = $args->[0];

         foreach my $flatArg (keys(%{$validArgs})){
                 if(defined($hash->{$flatArg})){
                    $validArgs->{$flatArg} = $hash->{$flatArg};
                    }
                 }
         $self->importFlat($validArgs);
         }
      }
   $self->dump if $debug;
}

sub new {
   my $class = shift;
   my $args = \@_;
   my $self = {'uv'=>{}, 'def'=>{}};
   bless($self, $class);
   $self->{'uv'}  = $self->supportedUserVars;
   $self->{'def'} = $self->defaultValues;
   $self->init($args);

   return $self;
}

sub check {
   my $self = shift;
   my %missing;

   foreach (keys(%{$self->{'def'}})){
           print(ref($self).'::check()  property <'.$_.">\n") if $debug;     
           for($_){
              /font$/  and do { $missing{$_} = $self->{'def'}{$_}{'value'} if not -s $self->{'def'}{$_}{'value'};
                                last; 
                                };
              /image$/ and do { $missing{$_} = $self->{'def'}{$_}{'value'} if not -s $self->{'def'}{$_}{'value'};
                                last; 
                                };
              }
           }
   return \%missing;
}

sub getDefaults { return $_[0]->{'def'}; }

sub copyDefaults {
   my $self = shift;
   my $target = shift;

   foreach my $elem (keys(%{$self->{'def'}})){
           if(ref($elem) eq 'HASH'){ $target->{$elem} = {$self->{'def'}{$elem}}; }
           elsif(ref($elem) eq 'ARRAY'){ $target->{$elem} = [$self->{'def'}{$elem}]; }
           else{ $target->{$elem} = $self->{'def'}{$elem}; }
           }
}

sub checkImage {
   my $self = shift;
   my $imgFN = shift;
   my $type = shift;
   my $rv = $imgFN;

   $type = 'gif' if not $type;
   croak('missing image filename!') if not $imgFN;
   my $rawName = basename($imgFN);
   my $name = $rawName;
   my $xt   = '';

   if($rawName =~ /^(.+?)\.([^\.]+)$/){
      $name = $1;
      $xt   = $2;
      }
   if(not $xt eq $type){
      my $target = $self->{'work'}{'appConfig'}->getConfig->{'temp'};
      
      if($self->{'work'}{'appArgs'}[0] and -d $self->{'work'}{'appArgs'}[0]){
         $target = $self->{'work'}{'appArgs'}[0];     
         }
      $target .= '/' if not $target =~ /\/$/;
      $target .= $name.'.'.$type;

      print(ref($self).'::checkImage( '.$imgFN.' ): - image has different type, gonna convert it to ['.$target."]\n") if $debug;

      my $cmd = $self->{'work'}{'appConfig'}->workerCommand('convert').' \''.$imgFN.'\' \''.$target.'\'';

      system($cmd);
      if(-s $target){ $rv = $target; }
      else{ croak('Oups, could not convert ['.$imgFN.']: '.$!); }
      }
   return $rv;
}

sub dump { print(ref($_[0]).' looks like this: ...'."\n".Dumper($_[0])."\n"); }

sub createDiskSettings {
   my $self = shift;
   my $page = shift;
   my $frLeft  = shift;
   my $frRight = shift;
   my $refConfig = shift;

   foreach my $cat (keys(%{$self->{'uv'}})){
           print('process category <'.$cat.">\n") if $debug;     
           for($cat){
              /^j/    and do { my $name = substr($cat, 1);
              
                               foreach my $entry (@{$self->{'uv'}{$cat}}){
                                       if($name =~ /^font$/){
                                          $refConfig->{$entry.$name} = {} if(not ref($refConfig->{$entry.$name}) eq 'HASH');     
                                          print('create font-element for entry <'.$entry.$name.">\n") if $debug;     
                                          main::guiElem($frLeft, 18, 190, $entry.$name, 'Font', $refConfig->{$entry.$name}, $self->getFontLimits->{$entry});
                                          }
                                       elsif($name =~ /^color$/){
                                          main::guiElem($frLeft,  18, 30, $entry.$name, 'Color', \$refConfig->{$entry.$name});
                                          }
                                       elsif($name =~ /^image$/){
                                          print('create image-element for entry <'.$entry.$name.">\n") if $debug;     
                                          main::guiElem($frLeft,  18, 212, $entry.$name, 'Image', $refConfig->{$entry.$name});
                                          main::guiElem($frRight, 15, 20, $entry.$name.'anchor', 'Radio', \$refConfig->{$entry.$name}{'anchor'}, ['top', 'middle', 'bottom'], 'h');
                                          }
                                       else{ print('Oups, unknown category: <'.$name.">\n"); }
                                       }
                               last;
                               };
              /^n/    and do { my $name = substr($cat, 1);
     
                               print('process <N>-category - entry=['.$name.'], value=( '.Dumper($self->{'uv'}{$cat})." )\n") if $debug;
                               main::guiElem($frRight, 15, 10, $name, 'Number', \$refConfig->{$name}, $self->{'uv'}{$cat});
                               last;
                               };
              /^s/    and do { my $name = substr($cat, 1);
     
                               print('process <S>-category - entry=['.$name.'], value=( '.Dumper($self->{'uv'}{$cat})." )\n") if $debug;
                               main::guiElem($frRight, 15, 20, $name, 'Radio', \$refConfig->{$name}, $self->{'uv'}{$cat}, 'h');
                               last;
                               };
              /flat/  and do { foreach my $property (@{$self->{'uv'}{$cat}}){
                                       main::guiElem($frLeft, 18, 30, $property, 'Entry', \$refConfig->{$property}); 
                                       }
                                last;
                                };
              croak('invalid definition of suppportedUserVars in '.ref($self)); 
              }
           }
}

sub createJobSettings {
   my $self = shift;
   my $page = shift;
   my $refConfig = shift;
   my $frLeft  = $page->Frame(-relief=>'groove', -bd=>1)->pack(-side=>'left', -expand=>1, -fill=>'both');
   my $frRight = $page->Frame(-relief=>'groove', -bd=>1)->pack(-side=>'left', -expand=>1, -fill=>'both');

   $self->createDiskSettings($page, $frLeft, $frRight, $refConfig);
}

sub createSpecialSettings {
   my $self = shift;
   my $page = shift;
   my $frLeft = shift;
   my $frRight = shift;
   my $addonPage = shift;
   
   main::guiElem($frLeft, 11, 18, 'anchor', 'Radio', \$addonPage->{'image0'}{'anchor'}, [qw(tl tr bl br)]);
   main::guiElem($frLeft, 11, 200, 'image0','Image', $addonPage->{'image0'});
   my $edit = $frRight->Scrolled('Text', -scrollbars=>'ose')->pack(-side=>'left', -expand=>1, -fill=>'both');
   
   $main::specialEdit = $edit->Subwidget('text');
   $edit->configure(-wrap=>'word');
   $edit->insert('end', $addonPage->{'summary'});
}

sub createMainMenu    { 1; }
sub createSubMenu     { 1; }
sub createSpecialMenu { 1; }
sub createSpecialPage { 1; }

sub createDVDMenu {
   my $self = shift;
   my $curDisk = shift;
   my $appArgs = shift;
   my $appCfg = shift;
   my $writeXml = shift;
   my $work = $appArgs->[0];
   my $fp;
   
   $writeXml = 0 if not $writeXml;
   $self->{'work'}{'disk'} = $curDisk;
   $self->{'work'}{'appArgs'} = $appArgs;
   $self->{'work'}{'appConfig'} = $appCfg;
   
   $work .= '/' if not $work =~ /\/$/;
   system('mkdir -p \''.$work.'\'') if not -d $work;
   foreach my $i (0 .. $#{$curDisk->{'recordings'}}){
          next if not $curDisk->{'recordings'}[$i]{'title'};     
          my $text = $curDisk->{'recordings'}[$i]{'summary'};
          my $dest = $work.'VDRSYNC.'.$i.'/';
          my $page = 0;
          my($xml,$xmlSub, $oldText);

          system('mkdir -p \''.$dest.'\'') if not -d $dest;
          while($text){ 
               print("\n".'------------------------------------------------------------------------------'."\n");
               print('--- '.ref($self).'::create submenu for ['.$curDisk->{'recordings'}[$i]{'title'}.'] page #'.$page.' ...'."\n");
               print('------------------------------------------------------------------------------'."\n");
               $xml = '<subpictures><stream><spu force="yes" start="00:00:00.00"'."\n"
                     .'image="'.$dest.'menu-no-buttons.png"'."\n"
                     .'select="'.$dest.'menu-no-buttons.png"'."\n"
                     .'highlight="'.$dest.'menu-bt-'.$page.'a-fs8.png"';
               $xmlSub = '';
               $oldText = $text;
               $text = $self->createSubMenu($curDisk->{'recordings'}[$i], $dest, $page, $text, \$xmlSub); 
               if($xmlSub){ $xml .= '>'."\n".$xmlSub; }
               else{ print('automatic button detection is NOT supported any longer!'."\n"
                          .'Please specify the location of the buttons yourself!'."\n"
                          .'Have a look at ThemeGD_Demo.pm as sample.'."\n");
                     exit;
                     }
               $xml .= '</spu></stream></subpictures>'."\n";
               if($writeXml){
                 my $cmd = $appCfg->workerCommand('convert').' "'.$dest.'menu-bt-'.$page.'.png" -resize 720x576\! "'.$dest.'menu-bt-'.$page.'a.png"; '.
                           $appCfg->workerCommand('pngquant').' 4 \''.$dest.'menu-bt-'.$page.'a.png\'';
   
                 print($cmd."\n");
                 system($cmd);
                 if(open($fp, '> '.$dest.'menu-'.$page.'.xml')){
                   print($fp $xml); 
                   close($fp);
                   }
                 my $aspect = 2;
   
                 $aspect = 1 if $curDisk->{'recordings'}[$i]{'settings'}{'aspect'} =~ /1:1/;
                 $aspect = 2 if $curDisk->{'recordings'}[$i]{'settings'}{'aspect'} =~ /4:3/;
                 $aspect = 3 if $curDisk->{'recordings'}[$i]{'settings'}{'aspect'} =~ /16:9/;
                 $aspect = 4 if $curDisk->{'recordings'}[$i]{'settings'}{'aspect'} =~ /2.21:1/;
                 $cmd = $appCfg->workerCommand('convert').' "'.$dest.'menu-bg-'.$page.'.png" -resize 720x576\! pnm:- | '
                       .$appCfg->workerCommand('ppmtoy4m').' -S 420mpeg2 -n 1 -F25:1 -A 59:54 -I t -L -r -v 0 | '
                       .$appCfg->workerCommand('mpeg2enc').' -q 2 -a '.$aspect.' -n p -f 8 -v 2 -o "'.$dest.'menu-bg-'.$page.'.m2v" && '
                       .$appCfg->workerCommand('mplex').' -f 8 -vbr -v 1 -o /dev/stdout "'.$dest.'menu-bg-'.$page.'.m2v" "'
                       .$appCfg->getAppAddonsDir.'/silence.mp2" | '
                       .$appCfg->workerCommand('spumux').' -v 2 "'.$dest.'menu-'.$page.'.xml" > "'.$dest.'menu-'.$page.'.mpg"';
                 print("command: <|$cmd|>\n") if $debug;
                 system($cmd) if not $main::testOnly;
                 print("\n");
                 }
               last if $oldText eq $text;
               $page++;
               }
          }
   if($curDisk->{'special'}{'title'}){
      print("\n".'------------------------------------------------------------------------------'."\n");
      print('--- create addons for ['.$curDisk->{'title'}.']...'."\n");
      print('------------------------------------------------------------------------------'."\n");
      my $dest = $work.'VDRSYNC.'.($#{$curDisk->{'recordings'}}+1).'/';
      
      system('mkdir -p \''.$dest.'\'') if not -d $dest;
      foreach my $i (0 .. $#{$curDisk->{'special'}{'pages'}}){
              my $curPage = $curDisk->{'special'}{'pages'}[$i];
              next if not $curPage->{'title'};     
              my $text = $curPage->{'summary'};
              my $page = 0;
              my($xml,$xmlSub, $oldText);
    
              while($text){ 
                   print("\n".'------------------------------------------------------------------------------'."\n");
                   print('--- '.ref($self).'::create addon-page for ['.$curPage->{'title'}.'] page #'.$page.' ...'."\n");
                   print('------------------------------------------------------------------------------'."\n");
                   $xml = '<subpictures><stream><spu force="yes" start="00:00:00.00"'."\n"
                         .'image="'.$dest.'menu-no-buttons.png"'."\n"
                         .'select="'.$dest.'menu-no-buttons.png"'."\n"
                         .'highlight="'.$dest.'menu'.$i.'-bt-'.$page.'a-fs8.png"';
                   $xmlSub = '';
                   $oldText = $text;
                   $text = $self->createSpecialPage($curPage, $dest, $page, $i, $text, \$xmlSub); 
                   if($xmlSub){ $xml .= '>'."\n".$xmlSub; }
                   else{ print('automatic button detection is NOT supported any longer!'."\n"
                              .'Please specify the location of the buttons yourself!'."\n"
                              .'Have a look at ThemeGD_Demo.pm as sample.'."\n");
                         exit;
                         }
                   $xml .= '</spu></stream></subpictures>'."\n";
                   if($writeXml){
                     my $cmd = $appCfg->workerCommand('convert').' "'.$dest.'menu'.$i.'-bt-'.$page.'.png" -resize 720x576\! "'.$dest.'menu'.$i.'-bt-'.$page.'a.png"; '
                              .$appCfg->workerCommand('pngquant').' 4 \''.$dest.'menu'.$i.'-bt-'.$page.'a.png\'';
       
                     print($cmd."\n");
                     system($cmd);
                     if(open($fp, '> '.$dest.'menu'.$i.'-'.$page.'.xml')){
                       print($fp $xml); 
                       close($fp);
                       }
                     my $aspect = 2;
       
                     $aspect = 1 if $curDisk->{'recordings'}[$i]{'settings'}{'aspect'} =~ /1:1/;
                     $aspect = 2 if $curDisk->{'recordings'}[$i]{'settings'}{'aspect'} =~ /4:3/;
                     $aspect = 3 if $curDisk->{'recordings'}[$i]{'settings'}{'aspect'} =~ /16:9/;
                     $aspect = 4 if $curDisk->{'recordings'}[$i]{'settings'}{'aspect'} =~ /2.21:1/;
                     $cmd = $appCfg->workerCommand('convert').' "'.$dest.'menu'.$i.'-bg-'.$page.'.png" -resize 720x576\! pnm:- | '
                           .$appCfg->workerCommand('ppmtoy4m').' -S 420mpeg2 -n 1 -F25:1 -A 59:54 -I t -L -r -v 0 | '
                           .$appCfg->workerCommand('mpeg2enc').' -q 2 -a '.$aspect.' -n p -f 8 -v 2 -o "'.$dest.'menu'.$i.'-bg-'.$page.'.m2v" && '
                           .$appCfg->workerCommand('mplex').' -f 8 -vbr -v 1 -o /dev/stdout "'.$dest.'menu'.$i.'-bg-'.$page.'.m2v" "'
                           .$appCfg->getAppAddonsDir.'/silence.mp2" | '
                           .$appCfg->workerCommand('spumux').' -v 2 "'.$dest.'menu'.$i.'-'.$page.'.xml" > "'.$dest.'menu'.$i.'-'.$page.'.mpg"';
                     print("command: <|$cmd|>\n") if $debug;
                     system($cmd) if not $main::testOnly;
                     print("\n");
                     }
                   last if $oldText eq $text;
                   $page++;
                   }
              }
      print("\n".'------------------------------------------------------------------------------'."\n");
      print('--- create menu for addons ['.$curDisk->{'special'}{'title'}.']...'."\n");
      print('------------------------------------------------------------------------------'."\n");
      my $xml = '<subpictures><stream><spu force="yes" start="00:00:00.00"'."\n"
               .'image="'.$dest.'menu-main-empty.png"'."\n"
               .'select="'.$dest.'menu-main-empty.png"'."\n"
               .'highlight="'.$dest.'menu-main-btt-fs8.png"';
      my $xmlSub = '';

      $self->createSpecialMenu($curDisk->{'special'}, $dest, \$xmlSub);
      if($xmlSub){ $xml .= '>'."\n".$xmlSub; }
      else{ print('automatic button detection is NOT supported any longer!'."\n"
                 .'Please specify the location of the buttons yourself!'."\n"
                 .'Have a look at ThemeGD_Demo.pm as sample.'."\n");
            exit;
            }
      $xml .= '</spu></stream></subpictures>'."\n";
      if($writeXml){
         my $cmd = $appCfg->workerCommand('convert').' "'.$dest.'menu-main-bt.png" -resize 720x576\! "'.$dest.'menu-main-btt.png"; '.
                   $appCfg->workerCommand('pngquant').' 4 \''.$dest.'menu-main-btt.png\'';
   
         print($cmd."\n") if $debug;
         system($cmd);
         print('createDVDMenu() - write XML for menu'."\n") if $debug;
         if(not $main::testOnly and open($fp, '> '.$dest.'menu-main.xml')){
            print $fp $xml;
            close($fp);
            }
         my $aspect = 2;
   
         $aspect = 1 if $curDisk->{'special'}{'settings'}{'aspect'} =~ /1:1/;
         $aspect = 2 if $curDisk->{'special'}{'settings'}{'aspect'} =~ /4:3/;
         $aspect = 3 if $curDisk->{'special'}{'settings'}{'aspect'} =~ /16:9/;
         $aspect = 4 if $curDisk->{'special'}{'settings'}{'aspect'} =~ /2.21:1/;
         $cmd = $appCfg->workerCommand('convert').' "'.$dest.'menu-main.png" -resize 720x576\! pnm:- | '
               .$appCfg->workerCommand('ppmtoy4m').' -S 420mpeg2 -n 1 -F25:1 -A 59:54 -I t -L -r -v 0 | '
               .$appCfg->workerCommand('mpeg2enc').' -q 2 -a '.$aspect.' -n p -f 8 -v 2 -o "'.$dest.'menu-bg.m2v" && '
               .$appCfg->workerCommand('mplex').' -f 8 -vbr -v 1 -o /dev/stdout "'.$dest.'menu-bg.m2v" "'
               .$appCfg->getAppAddonsDir.'/silence.mp2" | '
               .$appCfg->workerCommand('spumux').' -v 2 "'.$dest.'menu-main.xml" > "'.$dest.'menu.mpg"';
         print("command: <|$cmd|>\n") if $debug;
         system($cmd) if not $main::testOnly;
         }
      print("\n");
      }
   print("\n".'------------------------------------------------------------------------------'."\n");
   print('--- create main menu for ['.$curDisk->{'title'}.']...'."\n");
   print('------------------------------------------------------------------------------'."\n");
   my $xml = '<subpictures><stream><spu force="yes" start="00:00:00.00"'."\n"
            .'image="'.$work.'menu-main-empty.png"'."\n"
            .'select="'.$work.'menu-main-empty.png"'."\n"
            .'highlight="'.$work.'menu-main-btt-fs8.png"';
   my $xmlSub = '';

   $self->createMainMenu($curDisk, $work, \$xmlSub);
   if($xmlSub){ $xml .= '>'."\n".$xmlSub; }
   else{ print('automatic button detection is NOT supported any longer!'."\n"
              .'Please specify the location of the buttons yourself!'."\n"
              .'Have a look at ThemeGD_Demo.pm as sample.'."\n");
         exit;
         }
   $xml .= '</spu></stream></subpictures>'."\n";
   if($writeXml){
      my $cmd = $appCfg->workerCommand('convert').' "'.$work.'menu-main-bt.png" -resize 720x576\! "'.$work.'menu-main-btt.png"; '.
                $appCfg->workerCommand('pngquant').' 4 \''.$work.'menu-main-btt.png\'';

      print($cmd."\n") if $debug;
      system($cmd);
      print('createDVDMenu() - write XML for menu'."\n") if $debug;
      if(not $main::testOnly and open($fp, '> '.$work.'menu-main.xml')){
         print $fp $xml;
         close($fp);
         }

      my $aspect = 2;

      $aspect = 1 if $curDisk->{'settings'}{'aspect'} =~ /1:1/;
      $aspect = 2 if $curDisk->{'settings'}{'aspect'} =~ /4:3/;
      $aspect = 3 if $curDisk->{'settings'}{'aspect'} =~ /16:9/;
      $aspect = 4 if $curDisk->{'settings'}{'aspect'} =~ /2.21:1/;
      $cmd = $appCfg->workerCommand('convert').' "'.$work.'menu-main.png" -resize 720x576\! pnm:- | '
            .$appCfg->workerCommand('ppmtoy4m').' -S 420mpeg2 -n 1 -F25:1 -A 59:54 -I t -L -r -v 0 | '
            .$appCfg->workerCommand('mpeg2enc').' -q 2 -a '.$aspect.' -n p -f 8 -v 2 -o "'.$work.'menu-bg.m2v" && '
            .$appCfg->workerCommand('mplex').' -f 8 -vbr -v 1 -o /dev/stdout "'.$work.'menu-bg.m2v" "'
            .$appCfg->getAppAddonsDir.'/silence.mp2" | '
            .$appCfg->workerCommand('spumux').' -v 2 "'.$work.'menu-main.xml" > "'.$work.'menu.mpg"';
      print("command: <|$cmd|>\n") if $debug;
      system($cmd) if not $main::testOnly;
      }
   print("\n");
}

sub getDAMenuSub {
   my $self = shift;
   my $data = shift;
   my $work = shift;
   my $lNr  = shift;
   my $page = shift;
   my $rv = '      <pgc';
   
   $rv .= ' entry="root"' if not $page;
   $rv .= '>'."\n";
   $rv .= '        <vob file="'.$work.'menu-'.$page.'.mpg"/>'."\n";
   $rv .= '        <button name="play">jump title 1 chapter 1;</button>'."\n";
   $rv .= '        <button name="main">jump vmgm menu;</button>'."\n";
   $rv .= '        <button name="prev">jump menu '.$page.';</button>'."\n" if $page;
   $rv .= '        <button name="next">jump menu '.($page+2).';</button>'."\n" if -s $work.'menu-'.($page+1).'.mpg';
   $rv .= '      </pgc>'."\n";

   return $rv;
}

sub getDAMenuMain {
   my $self = shift;
   my $data = shift;
   my $work = shift;
   my $rv = '      <pgc entry="title">'."\n";
   my $i  = 1;
   
   $rv .= '        <vob file="'.$work.'/menu.mpg"/>'."\n";
   foreach (@{$data->{'recordings'}}){
           next if not $_->{'title'};
           $rv .= '        <button name="item'.$i.'">jump titleset '.$i++.' menu;</button>'."\n";
           }
   $rv .= '        <button name="item'.$i.'">jump vmgm menu 2;</button>'."\n" if $data->{'special'}{'title'};
   $rv .= '      </pgc>'."\n";

   return $rv;
}

sub getDASpecMainMenu {
   my $self = shift;
   my $data = shift;
   my $work = shift;
   my $rv = '      <pgc>'."\n";
   my $i  = shift;
   my $bNr = 1;

   $rv .= '        <vob file="'.$work.'menu.mpg"/>'."\n";
   foreach (@{$data->{'pages'}}){
           next if not $_->{'title'};
           $rv .= '        <button name="item'.$bNr.'">jump titleset '.++$i.' menu;</button>'."\n";
           $bNr++;
           }
   $rv .= '        <button name="main">jump vmgm menu 1;</button>'."\n";
   $rv .= '      </pgc>'."\n";
      
   return $rv;
}

sub getDASpecSubMenu {
   my $self = shift;
   my $data = shift;
   my $work = shift;
   my $lNr  = shift;
   my $page = shift;
   my $rv = '      <pgc';
   
   $rv .= ' entry="root"' if not $page;
   $rv .= '>'."\n";
   $rv .= '        <vob file="'.$work.'menu'.$lNr.'-'.$page.'.mpg"/>'."\n";
   $rv .= '        <button name="play">jump vmgm menu 2;</button>'."\n";
   $rv .= '        <button name="main">jump vmgm menu;</button>'."\n";
   $rv .= '        <button name="prev">jump menu '.$page.';</button>'."\n" if $page;
   $rv .= '        <button name="next">jump menu '.($page+2).';</button>'."\n" if -s $work.'menu'.$lNr.'-'.($page+1).'.mpg';
   $rv .= '      </pgc>'."\n";

   return $rv;
}

1;
