#!/usr/bin/perl -w
#*****************************************************************************
# 
#  ooffice - Wrapper script for OpenOffice.org
# 
#  Based on the Mandrake work.
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License version 2, as
#  published by the Free Software Foundation.
# 
#  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 IO::Handle;
use Fcntl ':flock';

my $Debug = $ENV{OOO_DEBUG};
my $DebugRH = $ENV{OOO_RH_DEBUG};

# Define the vendor of this particular OOo pacakge
my $VendorName = 'Aurox';
# Substituted by the build system:
# Define OpenOffice.org version
my $Version = '1.1.1';
# Define system installation directory
# Autoconf totally sucks for @libdir@ type substitution
my $SystemInstallDir = '/usr/lib/ooo-1.1.1';
# Suffix for parallel installable versioning
my $BinSuffix = '';
# Debugging

if ( $DebugRH ) {
	$Debug = 1;
	$VendorName = "RedHat";
}
if ($Debug && $Version =~ /^\@/) {
    $Version = "1.1.1";
    $SystemInstallDir = "/usr/lib/ooo-1.1";
    $BinSuffix = '';
}
my $ConfigSuffix = $Version;
$ConfigSuffix =~ s/([0-9]+\.[0-9]+).*/$1/;
# Define lock-file for this script
my $LockFile = "$ENV{HOME}/.openoffice-lock";
# Define user OOo versions file
my $VersionFile = "$ENV{HOME}/.sversionrc";

my ($UserInstallDir, $SetupConfig);

if ( $VendorName eq "RedHat" ) {
    # Define user installation directory
    $UserInstallDir = "$ENV{HOME}/.auropenoffice$ConfigSuffix";
} else {
    if ( $VendorName eq "Aurox" ) {
        # Define user installation directory
        $UserInstallDir = "$ENV{HOME}/.auropenoffice$ConfigSuffix";
    } else {
        # Define user installation directory
        $UserInstallDir = "$ENV{HOME}/.xopenoffice$ConfigSuffix";
    }
}

# Define setup autoresponse file for user installation
$SetupConfig = "/etc/openoffice/autoresponse$BinSuffix.conf";

# Define OOo setup program
my $SetupProgram = "$SystemInstallDir/program/setup";
# Where gconftool is...
my $GConfTool = 'gconftool-2';
# GConf configuration keys
my $ConfQuickstart = '/apps/ooo/quickstart';
# Note about default format key values:
# MS = Force MS Office to be default
# OO = Force OOo to be default
# Ximian always prefers MS formats in absence of "OO" in this key,
# while Red Hat always prefers OOo formats unless forced to MS
my $ConfDefaultFormat = '/apps/ooo/default-format';

sub GetConfBool($)
{
    my ($path) = @_;
    my ($value, $ret);

    $value = `$GConfTool --get $path 2>&1`;

    if (!$value) {
	$ret = 0;
    } elsif ($value =~ m/^true.*/i ||
	     $value =~ m/^yes.*/i ||
	     $value =~ m/^on.*/i) {
	$ret = 1;
    } else {
	$ret = 0;
    }

    return $ret;
}

sub ReadVersionFile($) {
    my ($file) = @_;
    my $e;
    my %entries;
    my $Rc;

    if (open ($Rc, "$file")) {
        while (<$Rc>) {
            chomp;
            if (/^\[(\w+)\]/) {
                $entries{$1} = $e = { };
            }
            elsif (/^([^=]+)=([^\r\n]+)/) {
                $e->{$1} = $2;
            }
        }
        close ($Rc);
    }
    %entries;
}

sub DoWriteVersionFile(%$) {
    my ($config, $file) = @_;
    local *F;
    
    if ($file) {
        open F, ">$file" or die "Cant write to $file\n";
        select F;
    }
    local $\ = "\n";
    while (my ($secname, $secvars) = each %$config) {
        print "[$secname]";
        while (my ($key, $value) = each %$secvars) {
            print "$key=$value";
        }
        print "";
    }
    if ($file) {
        close F;
        select STDOUT;
    }
}

sub WriteVersionFile(%) {
    my (%config) = @_;
    DoWriteVersionFile \%config, "$VersionFile";
}

#=============================================================================
# Main
#=============================================================================

# Parse command line arguments
my @ooo_argv;
my $session_quickstart;
while ($ARGV[0]) {
    $_ = shift;
    if (m/^--session-quickstart/) {
	$session_quickstart = 1;
    } else {
        push @ooo_argv, $_;
    }
}

if ($0 =~ m/\/oo(calc|draw|impress|math|writer)$BinSuffix$/) {
    my $app = $1;
    push @ooo_argv, "-$app";
    $Debug && print "Append arg: -$app\n";
}

my $Lock;

$Debug && print "Taking lock: $LockFile\n";
open ($Lock, ">$LockFile") || print "Can't open $LockFile\n";
flock ($Lock, LOCK_EX) || print "Warning: can't flock $LockFile\n";
$Debug && print "Obtained lock: $LockFile\n";

my %config;
my $config_changed = 0;


sub config_remove_by_path($$)
{
    my $config = shift;
    my $path = shift;
    my $versions = $config->{'Versions'};
    my $changed = 0;
    
    foreach (keys %$versions) {
	if ($versions->{$_} eq $path) {
	    delete $versions->{$_};
	    $changed++;
	}
    }

    return $changed;
}

my $targetVersion = "OpenOffice.org $Version";

# Remove any non-standard path installs
if ( -r "$VersionFile" ) {
    %config = ReadVersionFile "$VersionFile";
    my $versions = $config{Versions};
    my $home = $versions->{$targetVersion};
    if ($home && $home ne "file://$UserInstallDir") {
	$Debug && print "Removing odd path $home\n";
	$config_changed += config_remove_by_path (\%config, $home);
    }
}

# Prune broken looking installs & force a re-install
if ( ! -d $UserInstallDir || ! -e "$UserInstallDir/soffice" ) {
    $config_changed += config_remove_by_path (\%config, "file://$UserInstallDir");
}

if (%config && $config_changed) {
    $Debug && print "Write version file\n";
    WriteVersionFile %config;
}

# Perform a user install / upgrade, if necessary.
if (! exists $config{'Versions'}->{$targetVersion}) {
    # We can safely do the installation now
    # We also must make sure setup can find the libraries it needs
    my $setup_cmd = "LD_LIBRARY_PATH=$SystemInstallDir:$SystemInstallDir/program " .
                    "$SetupProgram -R:$SetupConfig -v -nogui";
    if (!$Debug) {
	$setup_cmd .= " >& ~/.openoffice-install-log";
    }

    $Debug && print "Calling setup: '$setup_cmd'\n";
    system ($setup_cmd) &&
        die "Installation of OpenOffice.org $Version failed:\n '$setup_cmd'\n";
 
#### Aurox hacks
    $setup_cmd = "$SystemInstallDir/ooffice_postinstall $UserInstallDir $SystemInstallDir";
    system ($setup_cmd) &&
        die "Post installation setup of OpenOffice.org $Version failed:\n '$setup_cmd'\n";

#### END Aurox hacks
}

sub symlinkf { unlink $_[1]; symlink $_[0], $_[1] }
symlinkf "$SystemInstallDir/program/soffice", "$UserInstallDir/soffice";
symlinkf "$SystemInstallDir/program/setup",   "$UserInstallDir/setup";

my $format = `$GConfTool --get $ConfDefaultFormat 2>&1`;

# See "Note about default format key values" above for values
# expected of the gconf key used here
if ( $VendorName eq "RedHat" ) {
    # For RH, only set MS as default if forced
    if ($format =~ m/^MS/i) {
        $ENV{OOO_MS_DEFAULTS}="1";
    }
} else {
    if ( $VendorName eq "Aurox" ) {
        # For Aurox, only set MS as default if forced
        if ($format =~ m/^MS/i) {
            $ENV{OOO_MS_DEFAULTS}="1";
        }
    } else {
        # For Ximian, only set _OpenOffice.org_ as default if forced
        if (! ($format =~ m/^OO/i)) {
            $ENV{OOO_MS_DEFAULTS}="1";
        }
    }
}

flock ($Lock, LOCK_UN);
close ($Lock);
$Debug && print "Released lock: $LockFile\n";

if ($session_quickstart) {
    my $do_qstart = GetConfBool ($ConfQuickstart);
    if (!$do_qstart) {
	exit 1;
    }
    $Debug && print "Execute quickstarter\n";
    push @ooo_argv, '-quickstart';
}

if (!(-f '/proc/version')) {
    print STDERR "\n\n --- Warning - OO.o will not work without a mounted /proc filesystem --- \n\n\n";
}

# And here we go. ;-)
exec "$UserInstallDir/soffice", @ooo_argv
