#!/usr/bin/perl

#
# Pinched from Debian:
#  http://cvs.debian.org/oo-deb/debian/local/openoffice-dpack-lang?rev=1.2&cvsroot=debian-openoffice&content-type=text/vnd.viewcvs-markup
#

use File::Copy;

# Load settings from 'setup'
my $Vars;
my %setup_vars;

if (!$ENV{'TOOLSDIR'}) {
    print "Sucking env from setup\n";
    open ($Vars, ". ./setup ; set|") || die "Can't find setup: $!";
    while (<$Vars>) {
	/([^=]*)=(.*)/ || next;
	$setup_vars{$1} = $2;
    }
    close ($Vars);
} else {
    print "Using inherited env\n";
    for $a (keys %ENV) {
	$setup_vars{$a} = $ENV{$a};
    }
}

my $UnzipCommand = "/usr/bin/unzip";
my $BuildDir = $setup_vars{'BUILDDIR'};
my $DestDir = $setup_vars{'OOINSTDIR'};
my $Xlate = $setup_vars{'TOOLSDIR'}. "/bin/openoffice-xlate-lang";
my @Langs = split (' ', `$Xlate -p all`);
my $Target = 'unxlngi4.pro';
my $Id = '645';


# Parse enough of <setup.ins> to get correct Directory and File sections.
sub ReadSetup($) {
    my ($file) = @_;
    my $e;
    my %entries;
    open FILE,"$file" || die "Can't read setup from $file : $!\n";
    while (<FILE>) {
		if (/^([_A-Za-z]+)\s*([_A-Za-z0-9]+)/) {
			$entries{$1}{$2} = $e = { };
		}
                elsif (/\s*([_A-Za-z]+)\s*=\s*\"?([^;\"]+)\"?;/) {
			$e->{$1} = $2;
		}
    }
    close FILE;
	
	# Expand predefined dirs to de $DestDir variable
	$entries{Directory}{$_} = { HostName => "$DestDir" } foreach
		qw( PREDEFINED_HOMEDIR  PREDEFINED_PROGDIR PREDEFINED_CONFIGDIR );
			
    \%entries;
}

sub DumpEntries(\%$) {
    my $entries = shift;
    my ($basename) = @_;
    my $sections = $entries->{$basename} if $entries->{$basename};
    while (my ($key, $value) = each(%$sections)) {
	print "$basename $key\n";
	$value->{$_} and print "\t$_\t= \"$value->{$_}\";\n"
	    foreach qw(Bitmap Date DefaultDestPath DefaultLanguage
		       Description FadeType FileName fontsDirFile
		       fontsDirGlobalFile fontspath HostName ID Key
		       Languages Name PackedName Path ProcName
		       ProductName ProductVersion Section Text Time
		       Value VendorBitmap);
	$value->{$_} and print "\t$_\t= $value->{$_};\n"
	    foreach qw(ArchiveFiles ArchiveSize BitmapPosX BitmapPoxY
		       Carrier Default Dir DiskNo FileID FontSize
		       Minimal ModuleID NetDir Order ParentID
		       ProfileID RegistryID ScriptVersion Size
		       TextHeight TextWidth UnixRights);
	print "End\n\n";
    }
}

sub GetFullPath {
    my $dirs = shift;
    my ($id) = @_;
	return ( $dirs->{$id}->{ParentID} ? GetFullPath($dirs, $dirs->{$id}->{ParentID}) . "/" : "" )
		   . $dirs->{$id}->{HostName};
}

sub mkpath {
    # Stolen in File::Path
    my($paths, $verbose, $mode) = @_;
    # $paths   -- either a path string or ref to list of paths
    # $verbose -- optional print "mkdir $path" for each directory created
    # $mode    -- optional permissions, defaults to 0777
    local($")= "/";
    $mode = 0777 unless defined($mode);
    $paths = [$paths] unless ref $paths;
    my(@created,$path);
    foreach $path (@$paths) {
        next if -d $path;
	# parent=dirname
        my $parent = $path; $parent =~ s#/[^/]*/?$##;
        unless (-d $parent or $path eq $parent) {
            push(@created,mkpath($parent, $verbose, $mode));
        }
        print "mkdir $path\n" if $verbose;
        unless (mkdir($path,$mode)) {
            my $e = $!;
            # allow for another process to have created it meanwhile
            die "mkdir $path: $e" unless -d $path;
        }
        push(@created, $path);
    }
    @created;
}

sub AddParentDirs {
    my($pUsedDirs, $dir) = @_;
    if (index ($dir, $DestDir) == 0) {
	$pUsedDirs->{"$dir"} = 1;
	my $parent = $dir; $parent =~ s#/[^/]*/?$#/#;
	AddParentDirs ($pUsedDirs, $parent);
    }
}	

sub BuildLang {
	my $lang = shift;
	my $lang_iso = `$Xlate -i $lang`;
	chomp ($lang_iso);
	$lang_iso =~ s/\r//;
	my $SetupDir = $setup_vars{'OOBUILDDIR'} . "/instsetoo/$Target/$lang/normal";
	my $SolverDir = $setup_vars{'OOBUILDDIR'} . "/solver/$Id/$Target";
	my $SetupConf = "$SetupDir/setup.ins";
	my @instFiles;

	if (!-r $SetupConf) {
		print "not found";
		return 1;
	}

	# Parse the file and get all entries
	my $setup = ReadSetup($SetupConf);

	#DumpEntries %$setup, "Directory";
	#DumpEntries %$setup, "File";

	die "$UnzipCommand not found, please set the full path to the unzip command\n" if
	    ( ! -x "$UnzipCommand" );

		
	while (my ($key, $value) = each (%{$setup->{File}})) {
		if ($value->{PackedName}) {
			# Find language-specific candidates
			if (($key =~ /_Lang$/) || ($value->{Name} =~ /\.res$/) ||
			    ($key =~ /File_Help/ && $value->{Dir} =~ /gid_Dir_Help_Isolanguage/)) {

			    # Prefer NetDir path over simple Dir
			    my $outpath = GetFullPath \%{$setup->{Directory}}, $value->{NetDir} ? $value->{NetDir} : $value->{Dir};
			    my $action = "None";
			    -d $outpath or mkpath($outpath);
			    if ($value->{Styles} =~ /PACKED/) {
				my $fileToCopy = $SolverDir . '/bin/' . $value->{Name};
				my $destFile = $outpath . '/' . $value->{Name};
				
				if( -f $destFile ) {
				    unlink $destFile or die "Can't delete $destFile";
				}

				push (@instFiles, $destFile);
				
				# Try to link file first
				if(link($fileToCopy,$destFile)) {
				    $action = "Link";
				}
				else {
				    copy($fileToCopy,$outpath) or die "Can't copy $fileToCopy to $outpath";
				    $action = "Copy";
				}
			    }
			    else {
				my $fileToUnzip = $SolverDir . '/pck/' . $value->{Name};
				if( -r $fileToUnzip ) {

				    open(UNZIP, "$UnzipCommand -qq -l $fileToUnzip |");
				    while (<UNZIP>) {
					#    907346  08-19-03 20:29   th_fr_FR.dat
				    	if ($_ =~ m/\s+\d+\s+\d+-\d+-\d+\s+\d+:\d+\s+(\S+)/m) {
					    push (@instFiles, "$outpath/$1");
				    	}
				    }
				    close(UNZIP);
				    
				    $action = "Unzip";
				    system("$UnzipCommand -qq -o $fileToUnzip -d $outpath");
				}
				else {
				    $action = "Skip";
				}
			    }	
			    print "$action $value->{PackedName} - $value->{Name} $value->{Styles} $value->{NetDir} $value->{Dir} \n";
			}
		    }
	    }
	    
	    # write list of files and directories
	    $langl_file = $BuildDir . '/lang_' . $lang_iso . '_list.txt';
	    open(LANGL, ">>$langl_file");

	    my @realFiles;
	    my %usedDirs;
	    # create lists of used directories and files
	    foreach my $file (@instFiles) {
		if (-d $file) {
	            $file .= "/" unless ($file =~ "/\$");
	    	    AddParentDirs (\%usedDirs, $file);
	        } else {
	    	    push (@realFiles, $file);
	    	    my $dir=$file; $dir =~ s#/[^/]*/?$#/#;
	    	    AddParentDirs (\%usedDirs, $dir);
	        }
	    }
	    # print the list of used directories
	    foreach my $dir (sort (keys %usedDirs)) {
	        print LANGL "\%dir $dir\n"; 
	    }
	    # print the list of installed files
		foreach my $file (sort (@realFiles)) {
	    	    print LANGL "$file\n";
	    }
	    
	    close(LANGL);

	print "done";

	return 0;
}

system("rm -f $BuildDir/lang_*_list.txt");

for $a (@Langs) {
	# the folowing line is disabled because we need to get the list of files
	# also for English
	# $a eq '01' && next; # English built-in

	$std_locale = `$Xlate -i $a`;
	chomp ($std_locale);
	$std_locale =~ s/\r//;
	$txt_name = `$Xlate -l $a`;
	chomp ($txt_name);
	$txt_name =~ s/\r//;

	print "Building language $txt_name ($std_locale:$a): ";

	BuildLang ($a);

	print "\n";
}
