#!/usr/bin/perl

###################################################
#
#  Copyright 2005 Tian
#
#  This file is part of GCfilms.
#
#  GCfilms 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.
#
#  GCfilms 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 GCfilms; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
###################################################

use strict;
use FindBin qw($RealBin);
use File::Copy;
use File::Path;

use lib "$RealBin/lib/gcfilms";
use GCLang;

sub usage
{
    print "Usage: gcfilms [options]\n";
    print "	--text			Force text installation\n";       
    print "	--prefix=PREFIX		Installs GCfilms in PREFIX [/usr/local]\n";
    print "	--nomenu		Don't install menu entry\n";
    print "	--noclean		Don't remove previous installation files\n";
    print "	--help			Show this message\n";
}

use Getopt::Long;
my ($withHelp, $withText, $withPrefix, $withoutMenu, $withoutClean);
(usage, exit 1) if !GetOptions("help"=>\$withHelp,
                               "text"=>\$withText,
                               "prefix=s"=>\$withPrefix,
                               "nomenu"=>\$withoutMenu,
                               "noclean",\$withoutClean);
           
(usage, exit 1) if ($ARGV[0]);

our $binName = 'gcfilms';
$binName .= '.pl' if ($^O =~ /win32/i);

chdir $RealBin;

our %lang;

if ($ENV{LANG} =~ /fr/i)
{
    %lang = %{$GCLang::langs{'FR'}};
}
elsif ($ENV{LANG} =~ /es/i)
{
    %lang = %{$GCLang::langs{'ES'}};
}
elsif ($ENV{LANG} =~ /it/i)
{
    %lang = %{$GCLang::langs{'IT'}};
}
elsif ($ENV{LANG} =~ /de/i)
{
    %lang = %{$GCLang::langs{'DE'}};
}
else
{
    %lang = %{$GCLang::langs{'EN'}};
}

our $type = 'graphic';

$type = 'text' if (($withPrefix) || ($withHelp) || ($withText) || ($withoutMenu) || ($withoutClean));

sub checkDependancies;

our ($mand, $opt) = checkDependancies('GC');

sub clean
{
    my $baseDir = shift;

    foreach (glob $baseDir.'/lib/gcfilms/*')
    {
        unlink if -f $_;
        if (-d _)
        {
            unlink foreach (glob "$_");
        }
    }
    
    foreach (glob $baseDir.'/share/gcfilms/*')
    {
        unlink if -f $_;
        if (-d _)
        {
            unlink foreach (glob "$_");
        }
    }
    
    unlink $baseDir.'/bin/'.$binName;
}

sub installMenu
{
	my $home = $ENV{HOME};

	if (-w '/usr/share/applications') {
		copy 'share/applications/gcfilms.desktop', '/usr/share/applications';
	}
	else {
		copy 'share/applications/gcfilms.desktop', $home.'/.local/share/applications';
	}

	copy 'share/gcfilms/icons/gcfilms_logo128.png', '/usr/share/pixmaps/gcfilms.png'
		if (-w '/usr/share/pixmaps');
}

sub doInstall
{
    my ($baseDir, $baseDir2) = @_;
    $baseDir = $baseDir2->get_text if $baseDir2;

    print $lang{InstallDirInfo}.$baseDir."\n";

    mkpath $baseDir.'/bin';
    copy 'bin/gcfilms', $baseDir.'/bin/'.$binName;
    
    chmod 0755, $baseDir.'/bin/'.$binName;

    mkpath $baseDir.'/lib/gcfilms';
    foreach (glob 'lib/gcfilms/*')
    {
        copy $_, $baseDir.'/lib/gcfilms';
    }
    mkpath $baseDir.'/lib/gcfilms/GCLang';
    foreach (glob 'lib/gcfilms/GCLang/*')
    {
        copy $_, $baseDir.'/lib/gcfilms/GCLang';
    }
    mkpath $baseDir.'/lib/gcfilms/GCPlugins';
    foreach (glob 'lib/gcfilms/GCPlugins/*')
    {
        copy $_, $baseDir.'/lib/gcfilms/GCPlugins';
    }
    mkpath $baseDir.'/lib/gcfilms/GCExport';
    foreach (glob 'lib/gcfilms/GCExport/*')
    {
        copy $_, $baseDir.'/lib/gcfilms/GCExport';
    }
    mkpath $baseDir.'/lib/gcfilms/GCImport';
    foreach (glob 'lib/gcfilms/GCImport/*')
    {
        copy $_, $baseDir.'/lib/gcfilms/GCImport';
    }

    mkpath $baseDir.'/share/gcfilms';
    foreach (glob 'share/gcfilms/*')
    {
        copy $_, $baseDir.'/share/gcfilms';
    }
    mkpath $baseDir.'/share/gcfilms/plugins';
    foreach (glob 'share/gcfilms/plugins/*')
    {
        copy $_, $baseDir.'/share/gcfilms/plugins';
    }
    mkpath $baseDir.'/share/gcfilms/icons';
    foreach (glob 'share/gcfilms/icons/*')
    {
        copy $_, $baseDir.'/share/gcfilms/icons';
    }
    mkpath $baseDir.'/share/gcfilms/xml_models';
    foreach (glob 'share/gcfilms/xml_models/*')
    {
        copy $_, $baseDir.'/share/gcfilms/xml_models';
    }
    mkpath $baseDir.'/share/gcfilms/html_models';
    foreach (glob 'share/gcfilms/html_models/*')
    {
        copy $_, $baseDir.'/share/gcfilms/html_models';
    }
    mkpath $baseDir.'/share/gcfilms/genres';
    foreach (glob 'share/gcfilms/genres/*')
    {
        copy $_, $baseDir.'/share/gcfilms/genres';
    }
    mkpath $baseDir.'/share/gcfilms/style';
    foreach (glob 'share/gcfilms/style/*')
    {
        next if /CVS/;
        mkpath $baseDir.'/'.$_;
        foreach my $style(glob $_.'/*')
        {
            copy $style, $baseDir."/".$_;
        }
    }
}

if ($type eq 'text')
{
    if ($withHelp)
    {
        usage;
    	exit 0;
    }

    print "\n".$lang{InstallMandatory}."\n\n";
    my %mand = %$mand;
    my @missing = ();
    foreach (sort keys %mand)
    {
        print $_, ' 'x(35-length($_)), $mand{$_}, "\n";
        push @missing, $_  if ($mand{$_} eq 'KO');
    }

    print "\n".$lang{InstallOptional}."\n\n";
    my %opt = %$opt;
    foreach (sort keys %opt)
    {
        print $_, ' 'x(35-length($_)), $opt{$_}, "\n";
    }

    if (scalar(@missing))
    {
        print "\n".$lang{InstallErrorMissing}."\n\n";
        print "$_\n" foreach (@missing);
        exit 1;
    }

    my $dir;
    if ($withPrefix)
    {
        $dir = $withPrefix;
    }
    else
    {
        print $lang{InstallPrompt};

        $| = 1;
        $_ = <stdin>;
        chomp;
        $dir = ($_ ? $_ : '/usr/local/');
    }

    $dir =~ s/^~/$ENV{HOME}/;

    eval 'mkpath $dir' if (! -e $dir);
    if (-w $dir && !$@)
    {
        clean $dir unless ($withoutClean);
        installMenu unless ($withoutMenu);
        doInstall $dir;
	
        print $lang{InstallEnd}."\n".$lang{InstallNoError}."\n".$lang{InstallLaunch}.$dir."/bin/".$binName."\n";
	
        exit 0;
     }
     else 
     {
     	print $lang{InstallNoPermission}."\n";
     	exit 0;
     }
	
}

sub checkDependancies
{
    my $pref = shift;

    my @dependancies = ();
    my @optionals = ();

    my @files = glob 'lib/gcfilms/*';
    push @files, glob 'lib/gcfilms/GCLang/*';
    push @files, glob 'lib/gcfilms/GCPlugins/*';
    push @files, glob 'lib/gcfilms/GCExport/*';
    push @files, glob 'lib/gcfilms/GCImport/*';
    foreach my $file(@files)
    {
        open FILE, $file;
        while (<FILE>)
        {
            push (@dependancies, $1) if ((/^\s*use\s*(.*?);/) && ($1 !~ /base|vars|locale|^lib|utf8|strict|^$pref/));
            push (@optionals, $1) if ((/eval.*?[\"\']use\s*(.*?)[\"\'];/) && ($1 !~ /base|vars|locale|^lib|utf8|strict|^$pref/));
            #"
        }
    }

    my %saw1;
    @saw1{@dependancies} = ();
    @dependancies = sort keys %saw1;

    my %saw2;
    @saw2{@optionals} = ();
    @optionals = sort keys %saw2;

    my %mandatoryResults = ();
    my %optionalResults = ();

    foreach (@dependancies)
    {
        $mandatoryResults{$_} = 'OK';
        eval "use $_";
        $mandatoryResults{$_} = 'KO' if ($@);
    }
    foreach (@optionals)
    {
        $optionalResults{$_} = 'OK';
        eval "use $_";
        $optionalResults{$_} = 'KO' if ($@);
    }

    return \%mandatoryResults, \%optionalResults;
}

eval
'
    use Gtk2 \'-init\';
    use GCDialogs;
';

#our $path;
our $installDialog = Gtk2::Window->new('toplevel');

sub graphicInstall
{
    my $widget = shift;
    
    if (-w $installDialog->{path}->get_text)
    {
        clean($installDialog->{path}->get_text)
            if $installDialog->{clean}->get_active;
	
        installMenu if $installDialog->{menu}->get_active;
	
        doInstall($installDialog->{path}->get_text);
	
        my $dialog = Gtk2::MessageDialog->new($installDialog,
                        [qw/modal destroy-with-parent/],
                        'info',
                        'ok',
                        $lang{InstallEnd}."\n\n".$lang{InstallNoError}."\n\n".$lang{InstallLaunch}.$installDialog->{path}->get_text."bin/".$binName);
        $dialog->run();
        $dialog->destroy ;
	
        Gtk2->main_quit;
    }
    else
    {
     	my $dialog = Gtk2::MessageDialog->new($installDialog,
						[qw/modal destroy-with-parent/],
						'error',
						'ok',
						$lang{InstallNoPermission}."\n\n");
        $dialog->run();
        $dialog->destroy ;
    }
}

sub browse
{
    my $widget = shift;
    my $dialog = new GCFileChooserDialog($lang{InstallDirectory}, $installDialog, 'select-folder');
    $dialog->set_filename($installDialog->{path}->get_text);
    my $response = $dialog->run;
    if ($response eq 'ok')
    {
        $installDialog->{path}->set_text($dialog->get_filename);
    }
    $dialog->destroy;

}

$installDialog->set_title($lang{InstallTitle});

my $vbox = new Gtk2::VBox(0,0);

my $panelDepend;
eval { my $dialog = new Gtk2::Expander() };
my $hasExpander = ($@ ? 0 : 1);
if ($hasExpander)
{
    $panelDepend = new Gtk2::Expander($lang{InstallDependancies});
    $panelDepend->set_expanded(0);
}
else
{
    $panelDepend = new Gtk2::VBox();
    $panelDepend->set_border_width(0);
    my $button = new Gtk2::Button($lang{InstallToggleDependancies});
    $panelDepend->add($button);
    $button->signal_connect(clicked => sub {
        my ($widget, $panel) = @_;
        my @children = $panel->get_children;
        my $table = $children[1];
        if ($table->visible)
        {
            $table->hide;
        }
        else
        {
            $table->show;
        }
        $panelDepend->get_parent->get_parent->resize(1,1);
    }, $panelDepend);
}

my %mand = %$mand;
my %opt = %$opt;
my $tableDepend = new Gtk2::Table(3 + scalar(keys %mand) + scalar(keys %opt),2, 0);
$tableDepend->set_row_spacings(10);
$tableDepend->set_col_spacings(20);
$tableDepend->set_border_width(10);

my @missing = ();
my $labelMand = new Gtk2::Label($lang{InstallMandatory});
$labelMand->set_alignment(0.5, 0.0);
$tableDepend->attach($labelMand, 0, 2, 0, 1, 'fill', 'fill', 0, 10);
my $i = 1;
foreach (sort keys %mand)
{
    my $label1 = new Gtk2::Label($_);
    my $label2 = new Gtk2::Label($mand{$_});

    $tableDepend->attach($label1, 0, 1, $i, $i+1, 'fill', 'fill', 0, 0);
    $tableDepend->attach($label2, 1, 2, $i, $i+1, 'fill', 'fill', 0, 0);

    push @missing, $_  if ($mand{$_} eq 'KO');
    $i++;
}

%opt = %$opt;
my $labelOpt = new Gtk2::Label($lang{InstallOptional});
$tableDepend->attach(new Gtk2::HSeparator, 0, 2, $i, $i+1, 'fill', 'fill', 0, 10);
$i++;
$tableDepend->attach($labelOpt, 0, 2, $i, $i+1, 'fill', 'fill', 0, 10);

$i++;
foreach (sort keys %opt)
{
    my $label1 = new Gtk2::Label($_);
    my $label2 = new Gtk2::Label($opt{$_});

    $tableDepend->attach($label1, 0, 1, $i, $i+1, 'fill', 'fill', 0, 0);
    $tableDepend->attach($label2, 1, 2, $i, $i+1, 'fill', 'fill', 0, 0);

    $i++;
}

my $scrollDepend = new Gtk2::ScrolledWindow;
$scrollDepend->set_policy ('automatic', 'automatic');
$scrollDepend->set_shadow_type('none');
$scrollDepend->add_with_viewport($tableDepend);
$scrollDepend->set_size_request(200, 300);
$panelDepend->add($scrollDepend);


my $hboxActions = new Gtk2::HBox(0,0);
my $hboxControls = new Gtk2::HBox(0,0);
my $vboxClean = new Gtk2::VBox(0,0);
my $ok = new Gtk2::Button->new_from_stock('gtk-ok');
my $cancel = new Gtk2::Button->new_from_stock('gtk-cancel');

my $label;

if (scalar(@missing))
{
    $hboxActions->set_border_width(10);
    $label = new Gtk2::Label($lang{InstallErrorMissing});
    my $vboxMissings = new Gtk2::VBox(0,0);

    $vboxMissings->pack_start(new Gtk2::Label($_),0,0,0) foreach (@missing);

    $hboxActions->pack_start($vboxMissings,0,0,0);
}
else
{
    $installDialog->{menu} = new Gtk2::CheckButton($lang{InstallWithMenu});
    $installDialog->{menu}->set_active(1);
    $vboxClean->pack_start($installDialog->{menu},0,0,10);

    $installDialog->{clean} = new Gtk2::CheckButton($lang{InstallWithClean});
    $installDialog->{clean}->set_active(1);
    $vboxClean->pack_start($installDialog->{clean},0,0,10);

    $vboxClean->pack_start(Gtk2::HSeparator->new, 0, 0, 10);

    $hboxControls->pack_end($ok, 0, 0, 10);
    $hboxActions->set_border_width(20);
    $label = new Gtk2::Label($lang{InstallSelectDirectory});
    $installDialog->{path} = new Gtk2::Entry;
    $installDialog->{path}->set_text('/usr/local/');
    $hboxActions->pack_start($installDialog->{path},1,1,5);
    my $imagesButton = Gtk2::Button->new_from_stock('gtk-open');
    $imagesButton->signal_connect('clicked', \&browse, $installDialog);
    $hboxActions->pack_start($imagesButton,0,0,5);
}

$hboxControls->pack_end($cancel, 0, 0, 10);

my $sep1 = new Gtk2::HSeparator;
my $sep2 = new Gtk2::HSeparator;

$vbox->pack_start($panelDepend,1,1,10);
$vbox->pack_start($sep1,0,0,0);
$vbox->pack_start($vboxClean,0,0,10);
$vbox->pack_start($label,0,0,5);
$vbox->pack_start($hboxActions,0,0,10);
$vbox->pack_start($sep2,0,0,0);
$vbox->pack_start($hboxControls,0,0,5);

$installDialog->add($vbox);

$ok->signal_connect('clicked' => \&graphicInstall);
$cancel->signal_connect('clicked' => sub { Gtk2->main_quit; });
$installDialog->signal_connect(destroy => sub { Gtk2->main_quit; });

$installDialog->show_all;
$installDialog->resize(1,1);

$tableDepend->hide if ! ($hasExpander);

Gtk2->main;

0;
