#!/usr/bin/perl
#
#  Perl Audio Converter (Installation)
#
#  Copyright (C) 2006 Philip Lyons (viiron@gmail.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

use strict;
use warnings;
use File::Copy;
use Getopt::Long;
use ExtUtils::Installed;
use CPAN;

use Term::ANSIColor qw(:constants);

$Term::ANSIColor::AUTORESET = 1;

my $name          = "PACPL";
my $version       = "v3.2.5";

my $install_msg    = "$name - $version: Installing";
my $uninstall_msg  = "$name - $version: Uninstalling";

my ($install, $uninstall, $checkinstall, $help);
my ($all, $base, $kde, $tags, $lang);

my $prefix       = "/usr/local";
my $kde_prefix;
 
   $kde_prefix   = "$ENV{'KDEDIR'}"  if     $ENV{'KDEDIR'};
   $kde_prefix   = "/usr"            if not $ENV{'KDEDIR'};

my $conf_path = "/etc/pacpl";
my $doc_path  = "$prefix/doc/pacpl-$version";

GetOptions('i|install=s'    => \$install,
           'u|uninstall=s'  => \$uninstall,
           'c|checkinstall' => \$checkinstall,
           'p|prefix=s'     => \$prefix,
           'k|kprefix=s'    => \$kde_prefix,

           'all'            => \$all,
           'base'           => \$base,
           'kde'            => \$kde,
           'tags'           => \$tags,
           'lang'           => \$lang,
           
           'h|help'         => \$help);
           
my @KDE        = qw(pacpl.desktop);

my @MIMES      = qw(x-shn.desktop  x-ape.desktop   x-wavpack.desktop
                    x-ofr.desktop  x-ofs.desktop   x-tta.desktop
                    x-lpac.desktop x-kxs.desktop   x-la.desktop
                    x-bonk.desktop);

my @BASE       = qw(pacpl      pacpl.conf  pacpl-install pacpl.1.gz
                    README     ChangeLog   GPL      
                    INSTALL    TODO        FAQ);
              
my @MODULES    = qw(Parse::RecDescent      Carp                      Inline
                    Inline::C              Audio::Musepack           Audio::WMA
                    Audio::FLAC::Header    MP3::Tag                  Ogg::Vorbis::Header
                    MP4::Info              Audio::APETags            CDDB_get);


my @LANGS      = qw(FR PT);
my @LANG_MODS  = qw(help long_help rip_help video_help tag_help);
my @LANG_DOCS  = qw(README FAQ INSTALL TODO);


# Main Install
sub doinstall {

if (!grep(/base|all|tags|kde|lang/, $install)) { 
    print "\nUnrecognized option in --install '$install': See $0 --help\n";
    exit(1);
}

# Install base program
if ($install =~ /base|all/i) {

  if (!-e "$prefix/doc") { mkdir("$prefix/doc") }
  
  mkdir("$doc_path");
  
  foreach my $i (@BASE) {
  if ($i eq "pacpl") {  
     print "$install_msg $i -> $prefix/bin/\n";
     copy("$i","$prefix/bin/$i"); 
     chmod(0755, "$prefix/bin/$i");
        
  }
  
  elsif ($i eq "pacpl-install") {
        
        print "$install_msg $i -> $prefix/bin/\n";
   
        copy("$i", "$prefix/bin/$i");
        chmod(0755,"$prefix/bin/$i");
        
  }
  
  elsif ($i eq "pacpl.conf") {  

     unless(-d "$conf_path") { mkdir("$conf_path"); }
     print "$install_msg $i -> $conf_path/\n";

     copy("$i","$conf_path/$i");  
  }
  
  elsif ($i eq "pacpl.1.gz") {
  
      print "$install_msg man/$i -> $prefix/man/man1\n";
      copy("man/$i", "$prefix/man/man1");
      
  }
                           
  else { 

     print "$install_msg docs/$i -> $doc_path/\n";
     copy("docs/$i","$doc_path/$i");  

  }
 }
}            

# Konqueror service menu & KDE audio mime types
if ($install =~ /kde|all/i) {

  if (`which kdialog 2>/dev/null`) {
  
     foreach my $i (@KDE)   {
  
           print "$install_msg kde/konqueror/$i\n";
           copy("kde/konqueror/$i","$kde_prefix/share/apps/konqueror/servicemenus/$i");
     }
  
     foreach my $i (@MIMES) {
   
           print "$install_msg kde/konqueror/mimes/$i\n";
           copy("kde/konqueror/mimes/$i","$kde_prefix/share/mimelnk/audio/$i");
     }

  } else { print "\nCould not find 'kdialog' in your path.\n\nKonqueror extension will not be installed\n\nPress enter to continue."; my $nokonq = <STDIN>; }
     
}

# Language Packs
if ($install =~ /lang|all/i) {

 foreach my $i (@LANGS) {
 
        # Create directory for each language
        if (not -d "$conf_path/$i") { 
            mkdir("$conf_path/$i");
            print "$name - $version: Creating directory $conf_path/$i\n"; 
        }
                      
    # Install help menu modules
    foreach my $x (@LANG_MODS) {
                       
        print "$install_msg lang/$i/$x.$i -> $conf_path/$i/$x.$i\n";
        copy("lang/$i/$x.$i","$conf_path/$i/$x.$i");
    }
                                                
        # Create documentation directory for each language
        if (not -d "$doc_path/$i") {
            mkdir("$doc_path/$i");
            print "$name - $version: Creating directory $doc_path/$i\n"; 
        }

    # Install translated documentation
    foreach my $y (@LANG_DOCS) {
   
            print "$install_msg lang/$i/docs/$y -> $doc_path/$i/$y\n";
            copy("lang/$i/docs/$y","$doc_path/$i/$y");
    }
 }
}

# Install tag handling modules
if ($install =~ /tags|all/i) {
   
      foreach my $i (@MODULES) {

         print "$install_msg $i via CPAN\n";
         
         if (`which pkg-config 2>/dev/null`) {

            if ($i eq "Ogg::Vorbis::Header") { 
              
                    if (!`pkg-config --libs ogg 2>/dev/null`) {
                     
                        die "\n\nlibogg is required to compile the $i module.\n\nPlease install the libogg package before proceeding.\n";

                    } elsif (!`pkg-config --libs vorbis 2>/dev/null`) {
                     
                        die "\n\nlibvorbis is required to compile the $i module.\n\nPlease install the libvorbis package before proceeding.\n";
     
                      }  else { CPAN::Shell->install("$i"); }
           }
         }
                
         if ($i eq "Audio::FLAC::Header") {

                 if (`which flac`) {
                
                     CPAN::Shell->force( "install", $i );
                  
                 } else { warn "\n\nFLAC is required to compile the $i module.\n\nskipping...\n\n"; }
   
           } else { CPAN::Shell->install("$i"); }
              
      }
                         
}

checkinstall() if grep(/all|base/, $install);

} # End Install

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

# Main Uninstall
sub uninstall {

# Uninstall base program
if ($uninstall =~ /base|all/i) {

  foreach my $i (@BASE) {

        if ($i eq "pacpl" and -e "$prefix/bin/$i")  {  

            print "$uninstall_msg $i -> $prefix/bin/\n";
            unlink("$prefix/bin/$i"); 
        }
        
        elsif ($i eq "pacpl-install" and -e "$prefix/bin/$i") {
            print "$uninstall_msg $i -> $prefix/bin/\n";
            unlink("$prefix/bin/$i");
        }
        
        elsif ($i eq "pacpl.1.gz" and -e "$prefix/man/man1/$i") {
            print "$uninstall_msg $i -> $prefix/man/man1/\n";
            unlink("$prefix/man/man1/$i");
        }
  
        elsif ($i eq "pacpl.conf" and -e "$conf_path/$i") {  

            print "$uninstall_msg $i -> $conf_path/\n";
            unlink("$conf_path/$i");  

        } else { print "$uninstall_msg $i -> $prefix/doc/pacpl-$version\n" and unlink("$doc_path/$i") if (-e "$doc_path/$i");  }
  }

print "$name - $version: Removing Directory $doc_path\n"  and rmdir("$doc_path")  if (-e $doc_path)  and (grep(!/lang/, $uninstall));
print "$name - $version: Removing Directory $conf_path\n" and rmdir("$conf_path") if (-e $conf_path) and (grep(!/lang/, $uninstall));

}     

# Uninstall language packs
if ($uninstall =~ /lang|all/i) {

 foreach my $i (@LANGS) {
 
    # Remove all language documentation
    foreach my $x (@LANG_DOCS) {
          print "$uninstall_msg $doc_path/$i/$x\n"   if -e "$doc_path/$i/$x";
          unlink("$doc_path/$i/$x")                  if -e "$doc_path/$i/$x";
    }
    
    # Remove all language help modules
    foreach my $y (@LANG_MODS) {
          print "$uninstall_msg $conf_path/$i/$y.$i\n"   if -e "$conf_path/$i/$y.$i";
          unlink("$conf_path/$i/$y.$i")                  if -e "$conf_path/$i/$y.$i";
    }
    
    # Remove language documentation directory
    rmdir("$doc_path/$i") if -e "$doc_path/$i";
    print "$name - $version: Removed directory '$doc_path/$i'\n" if -e "$doc_path/$i";
    
    # Remove conf path language directory
    rmdir("$conf_path/$i") if -e "$conf_path/$i";
    print "$name - $version: Removed directory '$conf_path/$i'\n" if -e "$conf_path/$i";
    
    # Remove conf path if it still exists
    rmdir("$conf_path") if -e "$conf_path";
    print "$name - $version: Removed directory '$conf_path'\n" if (-e $conf_path) and (grep(/base|all/, $uninstall));
    
    # Remove documentation directory if it still exists
    rmdir("$doc_path") if (-e $doc_path) and (grep(/base|all/, $uninstall));
    print "$name - $version: Removed directory $doc_path\n" if (-e $doc_path) and (grep(/base|all/, $uninstall));
 }
}

# Install Konqueror service menu and mime types
if ($uninstall =~ /kde|all/i) {

  foreach my $i (@KDE)   {
      if (-e "$kde_prefix/share/apps/konqueror/servicemenus/$i") {
          print "$uninstall_msg $kde_prefix/share/apps/konqueror/servicemenus/$i\n";
          unlink("$kde_prefix/share/apps/konqueror/servicemenus/$i");
      }
  }  
  
  foreach my $i (@MIMES) {
      if (-e "$kde_prefix/share/mimelnk/audio/$i") {
          print "$uninstall_msg $kde_prefix/share/mimelnk/audio/$i\n";
          unlink("$kde_prefix/share/mimelnk/audio/$i");
      }
  }
  
}


} # End Uninstall

sub checkinstall {

    my %c_type = ( lame     => 'MP3',
                   oggenc   => 'Ogg Vorbis',
                   oggdec   => 'Ogg Vorbis',
                   flac     => 'FLAC (FLA/FLAC)',
                   mac      => 'Monkey Audio (APE)',
                   shorten  => 'Shorten (SHN)',
                   faac     => 'FAAC (MP4/M4A/AAC) ',
                   faad     => 'FAAD (MP4/M4A/AAC)',
                   mppenc   => 'Musepack (MPC)',
                   mppdec   => 'Musepack (MPC)',
                   wavpack  => 'Wavpack (WV)',
                   wvunpack => 'Wavpack (WV)',
                   ofr      => 'OptimFrog (OFR)',
                   ofs      => 'OptimFrog (OFS)',
                   ttaenc   => 'TTA',
                   lpac     => 'LPAC (PAC/LPAC)',
                   kexis    => 'Kexis (KXS)',
                   sox      => 'AU/SND/AIFF/RAW/SMP/VOC',
                   ffmpeg   => 'AC3/MP2',
                   la       => 'Lossless Audio (LA)',
                   bonk     => 'BONK',
                   mplayer  => 'RealAudio (RA/RAM) & WMA',
                   
                   cdparanoia => 'CD Ripping',
                   
                   kdialog    => 'Konqueror/Amarok Extensions',
                   
                 );  
                                
    my %program  = ( lame     => '',  oggenc   => '',
                     oggdec   => '',  flac     => '',
                     mac      => '',  shorten  => '',
                     faac     => '',  faad     => '',
                     mppenc   => '',  mppdec   => '',
                     wavpack  => '',  wvunpack => '',
                     ofr      => '',  ofs      => '',
                     ttaenc   => '',  lpac     => '',
                     kexis    => '',  sox      => '',
                     ffmpeg   => '',  la       => '',
                     bonk     => '',  mplayer  => '',
                     
                     cdparanoia => '',
                     kdialog    => '',
                     
                   );

    print "\n$name - $version - Installed Apps/Tagging Modules\n\n";
    print BOLD "App           Conversion Type           Installed\n";
    print      "-------------------------------------------------\n";
                   
    foreach my $app (sort(keys(%program))) {

         if (`which $app 2>/dev/null`) {
             
             my $tmp = `which $app`;

             chomp($tmp);
             $program{$app} = $tmp;

             printf("%-13s %-28s %s", $app, $c_type{$app}, "Yes\n");

         } else { printf("%-13s %-28s %s", $app, $c_type{$app}, "No\n"); }
    }
    
 if ($install) {
 
    my $old_conf = "$conf_path/pacpl.conf";
    my $new_conf = "pacpl.conf.$$";
       
        open(O, "< $old_conf") or die "Could not open '$old_conf'" . "\n\n";
        open(N, "> $new_conf") or die "Could not open '$new_conf'" . "\n\n";
                        
    while (<O>) {
    
      s/LAME =/LAME = $program{lame}/g;
      s/OGGENC =/OGGENC = $program{oggenc}/g;
      s/OGGDEC =/OGGDEC = $program{oggdec}/g;
      s/FLAC =/FLAC = $program{flac}/g;
      s/MAC =/MAC = $program{mac}/g;
      s/SHORTEN =/SHORTEN = $program{shorten}/g;
      s/FAAC =/FAAC = $program{faac}/g;
      s/FAAD =/FAAD = $program{faad}/g;
      s/MPLAYER =/MPLAYER = $program{mplayer}/g;
      s/MPPENC =/MPPENC = $program{mppenc}/g;
      s/MPPDEC =/MPPDEC = $program{mppdec}/g;
      s/WAVPACK =/WAVPACK = $program{wavpack}/g;
      s/WVUNPACK =/WVUNPACK = $program{wvunpack}/g;
      s/OFR =/OFR = $program{ofr}/g;
      s/OFS =/OFS = $program{ofs}/g;
      s/TTAENC =/TTAENC = $program{ttaenc}/g;
      s/LPAC =/LPAC = $program{lpac}/g;
      s/SOX =/SOX = $program{sox}/g;
      s/FFMPEG =/FFMPEG = $program{ffmpeg}/g;
      s/LA =/LA = $program{la}/g;
      s/BONK =/BONK = $program{bonk}/g;
      s/CDPARANOIA =/CDPARANOIA = $program{cdparanoia}/g;
      s/KDIALOG =/KDIALOG = $program{kdialog}/g;

      print N "$_";

    }
    
    close(O);
    close(N);
    
    rename("$new_conf","$old_conf");
 }
 
    print "\nSee $doc_path/README for application URLs\n";
    print "\nPress enter to continue";

    my $enter = <STDIN>;
    
    my @TAG_MODS = qw(MP3::Tag       Ogg::Vorbis::Header Audio::FLAC::Header
                      MP4::Info      Audio::Musepack     Audio::WMA     
                      
                      CDDB_get);
                      
    print "\n$name - $version: Audio Tagging Modules\n\n";
    
    my ($inst) = ExtUtils::Installed->new();
    my (@mods) = $inst->modules();

    foreach my $i (@TAG_MODS) {                      
    
         if (grep(/$i/, @mods)) {
    
              printf("%-20s %s", $i, "-> Installed\n");
    
         } else { print "$i -> Not Installed\n"; }
    }
    
    print "\nDone.\n";

}
    

sub help {

print "

Perl Audio Converter - $version ( Install / Uninstall )

Options: all       Install ALL  below options
         base      Install PAC  & Documentation only
         kde       Install KDE  Konqueror service menu & mime types
         tags      Install TAG  modules only
         lang      Install LANG packs only (French & Portuguese)

     --prefix      Install pacpl executable in PREFIX
                   Default = $prefix

     --kprefix     Install Konqueror service menu and mime types in KPREFIX
                   Default = $kde_prefix
                   
     -c, --checkinstall (Check for required applications / tagging modules)


Examples: pacpl-install --install=all
          pacpl-install --prefix=/usr --kprefix=/opt/kde -i 'base tags'
         
          pacpl-install --uninstall=all
          pacpl-install --prefix=/usr --kprefix=/opt/kde -u 'base kde'

"; }
    

if    ($install)      { doinstall();    }

elsif ($uninstall)    { uninstall();    }

elsif ($checkinstall) { checkinstall(); }

else { help(); }

