#!/usr/bin/perl
#
# MiniVend localizer
#
# $Id: localize,v 1.1 1998/03/21 12:16:48 mike Exp $
#
# Copyright 1996-1998 by Michael J. Heins <mikeh@minivend.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., 675 Mass Ave, Cambridge, MA 02139, USA.

BEGIN {

    eval {
        require 5.004;
        require FindBin;
        1 and $Global::VendRoot = "$FindBin::RealBin";
        1 and $Global::VendRoot =~ s/.bin$//;
    };

	($Global::VendRoot = $ENV{MINIVEND_ROOT})
		if defined $ENV{MINIVEND_ROOT};

	$Global::VendRoot = $Global::VendRoot || '/home/minivend';
	$Global::ErrorFile = "$Global::VendRoot/error.log";
}

### END CONFIGURABLE VARIABLES

sub dontwarn { $FindBin::RealBin; }

use lib $Global::VendRoot;
use lib "$Global::VendRoot/lib";

use Vend::Util qw(readfile escape_chars);
require Vend::Config;
use Getopt::Std;

use vars qw($opt_d $opt_l $opt_m $opt_o $opt_t $USAGE);
use strict;

$USAGE = <<EOF;
$0 -- produce localization file from set of pages

usage:    localize -l lg_CC [-d lg_CC] [-m file|-t] file [file2 file3 ...]

OPTIONS

    -d lg_CC   Create default domain file with Locale lg_CC as prefix
    -l lg_CC   Create file with Locale lg_CC as prefix
    -m <file>  Read existing information to merge from <file>
    -o         Rewrite [L] sections with [L msgNNNN], adjust file and data
    -t         Two page mode, mutually exclusive with -m

lg_CC refers to the POSIX norm of specifying two-letter
language and country codes to refer to a locale.
    
Two-page mode requires two files (one for each language) to compare and
merge into one locale definition.

The merge file for the -m option should use the Perl reference form --
see the MiniVend documentation for more information.

If [L msg_key]default text[/L] keys are found, will produce a comment
with the default text for reference.

A backup file (filename.html.bak) is saved if -o is used, but only
one level. Subsequent .bak files will be overwritten.

EOF

getopts('d:l:m:ot') or die "$USAGE\n";

die "$USAGE\n" if $@;
die "$USAGE\n" unless $opt_l;
die "$USAGE\n" if $opt_d && $opt_l eq $opt_d;

my $def = $opt_d || 'default';

my $Uneval;

if($Data::Dumper::Version) {
	$Uneval = \&Data::Dumper::Dumper;
	$Data::Dumper::Useqq = 1;
}
else {
	$Uneval = \&Vend::Util::uneval_it;
}

my $C = {};

Vend::Config::setcat($C);

if(! $opt_m) {
	# do nothing
}
elsif ( open(CONFIG, $opt_m) ) {
	my $value;
	while (<CONFIG>) {
		chomp;
		next unless s/^\s*locale\s+//i;
		$value = $_;
        if ($value =~ /^(.*)<<(\w+)\s*/) {                  # "here" value
            my $begin  = $1 || '';
            $begin .= "\n" if $begin;
            my $mark = $2;
            my $startline = $.;
            $value = $begin . Vend::Config::read_here(\*CONFIG, $mark);
            unless (defined $value) {
                die (sprintf('%d: %s', $startline,
                    qq#no end marker ("$mark") found#));
            }
        }
		Vend::Config::parse_locale('Locale', $value);
	}
}
else {
	warn "Couldn't read merge file $opt_m, continuing without.\n";
}

$C->{Locale} = {} unless $C->{Locale};

my $Locale = $C->{Locale};

my $one_text;
my $two_text;
my $one;
my $two;

if($opt_t) {
	$one = shift;
	$two = shift || die "$USAGE\n";
	my @one;
	my @two;
	my @comment;

	$one_text = readfile($one) or die "file $one not present or empty.\n";
	$two_text = readfile($two) or die "file $two not present or empty.\n";

	while ($one_text =~ m:\[L(\s+[\w+]\s*)?\](.*?)\[/L\]:) {
			if($1) {
				push (@one, $1);
				push (@comment, $2);
			}
			else {
				push (@one, $2);
				push (@comment, '');
			}
	}
	$two_text =~ s:\[L\](.*?)\[/L\]:push (@two, $1):eg;

	print "Locale $opt_l <<EOF\n";
	print "{\n";
	my $i;
	for($i = 0; $i < @one; $i++) {
		print "'";
		$one[$i] =~ s/'/\\'/g;
		print $one[$i];
		print "',\n";
		if ($comment[$i]) {
			$comment[$i] =~ s/\n/\n# /g;
			print "# $comment[$i]\n";
		}
		print "'";
		$two[$i] =~ s/'/\\'/g;
		print $two[$i];
		print "',\n\n";
	}
	print "\n}\nEOF\n";
	exit;
}

my %Comment;
my $Key = 'msg0001';

sub getkey {
	$Key++ until ! defined $Locale->{default}->{$Key};
	return $Key;
}

sub write_structure {
	my($key, $default) = @_;
	if($key) {
		$Locale->{$def}->{$key} = $default;
		$Comment{$key} = $default;
		$Comment{$key} =~ s/\n/\n# /g;
	}
	else {
		$Locale->{$def}->{$default} = $default;
	}
}

my $data;
my $key;
my $file;

foreach $file (@ARGV) {
	unless ($data = readfile($file)) {
		warn "file $file non-existent or empty, skipping.\n";
		next;
	}

	if($opt_o) {
		rename($file, "$file.bak") or die "Couldn't rename $file: $!\n";
		while ($data =~ s:\[L\](.*?)(\[/L\]):
					'[L ' . ($key = getkey()) . ']' . $1. $2:e) {
				write_structure($key, $1);
		}
	}
	while ($data =~ m:\[L(\s+(\w+)\s*)?\](.*?)\[/L\]:g) {
				write_structure($2 || undef, $3);
	}

	if($opt_o) {
		Vend::Util::writefile($file, $data);
	}
}

my $loc_text = "Locale $opt_l <<EOF\n{\n";
my $def_text = "Locale $def <<EOF\n{\n";

my $d = $Locale->{$def};
my $l = $Locale->{$opt_l};

my($text, $dat, $cmt);

foreach $key (sort keys %$d) {

		$dat = ($Comment{$key} || '') and
			$dat =~ s/\n/\n# /g;

		$def_text .= "# $dat\n" if $dat;

		if ($dat) {
			$cmt = $dat;
		}
		else {
			$cmt = $key;
			$cmt =~ s/\n/\n# /g;
		}
		$loc_text .= "# $cmt\n";

		$text = &$Uneval($key);
		$loc_text .= "$text,\n";
		$loc_text .= &$Uneval ($l->{$key} || '');
		$loc_text .= ",\n\n";

		next unless $Comment{$key};
		$def_text .= "$text,\n";
		$def_text .= &$Uneval($Comment{$key});
		$def_text .= ",\n\n";
	

}

$def_text .= "\n}\nEOF\n";
$loc_text .= "\n}\nEOF\n\n";

print $loc_text;
print $def_text;

