#!/usr/bin/perl -w

###########################################################################
#
# translate.pl 
# A component of the Greenstone digital library software
# from the New Zealand Digital Library Project at the 
# University of Waikato, New Zealand.
#
# Copyright (C) 1999 New Zealand Digital Library Project
#
# 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.
#
###########################################################################

# translate.pl takes a translated macro file (filename passed in on command
# line) and generates any images required by it. Check out english.dm for
# an example of the format translate.pl expects

# translate.pl uses gimp to generate images so needs gimp installed and set
# up for scripting with perl

BEGIN {
    die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
    unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
}

use Gimp;
use parsargv;
use util;
use unicode;

# these html entities will be translated correctly when occurring in 
# images. Any entities not in this list will not.
my %rmap = ('auml' => chr (228),
	    'euml' => chr (235),
	    'iuml' => chr (239),
	    'ouml' => chr (246),
	    'uuml' => chr (252),
	    'Auml' => chr (196),
	    'Euml' => chr (203),
	    'Iuml' => chr (207),
	    'Ouml' => chr (214),
	    'Uuml' => chr (220),
	    'szlig' => chr (223),
	    'aacute' => chr (225),
	    'eacute' => chr (233),
	    'iacute' => chr (237),
	    'oacute' => chr (243),
	    'uacute' => chr (250),
	    'Aacute' => chr (193),
	    'Eacute' => chr (201),
	    'Iacute' => chr (205),
	    'Oacute' => chr (211),
	    'Uacute' => chr (218),
	    'agrave' => chr (224),
	    'egrave' => chr (232),
	    'igrave' => chr (236),
	    'ograve' => chr (242),
	    'ugrave' => chr (249),
	    'Agrave' => chr (192),
	    'Egrave' => chr (200),
	    'Igrave' => chr (204),
	    'Ograve' => chr (210),
	    'Ugrave' => chr (217),
	    'ntilde' => chr (241),
	    'Ntilde' => chr (209),
	    'atilde' => chr (227),
	    'Atilde' => chr (195),
	    'otilde' => chr (245),
	    'Otilde' => chr (213),
	    'ccedil' => chr (231),
	    'Ccedil' => chr (199),
	    'ecirc' => chr (234),
	    'Ecirc' => chr (202),
	    'acirc' => chr (226),
	    'Acirc' => chr (194),
	    );

my $hand_made = 0;

sub print_usage {
    print STDERR "\n";
    print STDERR "translate.pl: Uses gimp to generate any images required by a\n";
    print STDERR "              Greenstone macro file.\n\n";
    print STDERR "  usage: $0 [options] macrofile\n\n";
    print STDERR "  options:\n";
    print STDERR "   -save_orig_file       edited macrofile will be written to\n";
    print STDERR "                         macrofile.new leaving macrofile unchanged\n";
    print STDERR "   -language_symbol      ISO abbreviation of language (e.g. German=de,\n";
    print STDERR "                         French=fr, Maori=mi)\n";
    print STDERR "   -image_dir directory  full path to directory in which to create images\n";
    print STDERR "                         (defaults to `pwd`/images)\n\n";
}

sub gsdl_translate {

    if (!parsargv::parse(\@ARGV, 
			 'save_orig_file', \$save_orig_file,
			 'language_symbol/[A-Za-z]{2}', \$language_symbol,
			 'image_dir/.*/images', \$image_dir)) {
	&print_usage();
	die "\n";
    }

    if ($image_dir eq "images") {
	$image_dir = `pwd`;
	chomp $image_dir;
	$image_dir = &util::filename_cat ($image_dir, "images");
    }

    if (!defined $ARGV[0]) {
	print STDERR "no macro file supplied\n\n";
	&print_usage();
	die "\n";
    }
    my $macrofile = $ARGV[0];
    die "\nmacrofile $macrofile does not exist\n\n" unless -e $macrofile;

    if (!-e $image_dir) {
	mkdir ($image_dir, 511) || die "\ncouldn't create image_dir $image_dir\n\n";
    }

    open (INPUT, $macrofile) || die "\ncouldn't open $macrofile for reading\n\n";
    open (OUTPUT, ">$macrofile.new") || die "\ncouldn't open temporary file $macrofile.new for writing\n\n";

    &parse_file (INPUT, OUTPUT);

    close OUTPUT;
    close INPUT;

    if (!$save_orig_file) {
	`mv $macrofile.new $macrofile`;
    }

    print STDERR "\n\n";
    print STDERR "translation of macro file $macrofile completed\n";
    print STDERR "the translated macro file is $macrofile.new\n" if $save_orig_file;
    print STDERR "\n";
    if ($hand_made) {
	print STDERR "$hand_made hand made images were found within $macrofile,\n";
	print STDERR "these will need to be made by hand (grep $macrofile for 'hand_made'\n\n";
    }
    print STDERR "To add your new interface translation to Greenstone you'll need to:\n";
    print STDERR "  1. Copy your new macro file to your GSDLHOME/macros directory\n";
    print STDERR "  2. Add your new macro file to the macrofiles list in your\n";
    print STDERR "     GSDLHOME/etc/main.cfg configuration file\n";
    print STDERR "  3. Copy your newly created images from $image_dir to \n";
    print STDERR "     GSDLHOME/images/$language_symbol/\n\n";
    print STDERR "Access your new interface language by setting the language (l) cgi\n";
    print STDERR "argument to '$language_symbol'\n\n";

}

sub parse_file {
    my ($input, $output) = @_;

    undef $/;
    my $dmfile = <$input>;
    $/ = "\n";

    # process all the images

    $dmfile =~ s/(?:^|\n)\#\#\s*\"([^\"]*)\"\s*\#\#\s*([^\s\#]*)\s*\#\#\s*([^\s\#]*)\s*\#\#(.*?)(?=(\n\#|\s*\Z))/&process_image ($1, $2, $3, $4)/esg;

    # add language parameter to each macro
    $dmfile =~ s/(\n\s*)(_[^_]*_)\s*(\[[^\]]*\])?\s*\{/$1 . &add_language_param ($2, $3)/esg;
    
    print $output $dmfile;
}

sub process_image {
    my ($text, $image_type, $image_name, $image_macros) = @_;

    my $origtext = $text;
    $text =~ s/&(\d{3,4});/chr($1)/ge;
    $text =~ s/&([^;]*);/$rmap{$1}/g;

    # special case for russian images - fonts expect text to be koi8-r encoded
    if ($language_symbol eq "ru") {
	$text = &unicode::unicode2koi8r(&unicode::utf82unicode($text));
    }

    # edit image macros
    $image_macros =~ s/(_httpimg_\/)(?:[^\/\}]*\/)?([^\}]*\.(?:gif|jpe?g|png))/$1$language_symbol\/$2/gs;

    if ($image_type eq "top_nav_button") {
	
	# generate images
	my $options = "-text \"$text\" -filenamestem $image_name";
	# special case for russian images
	if ($language_symbol eq "ru") {
	    $options .= " -fontsize 10 -height 20 -whitespace -image_dir $image_dir";
	    $options .= " -foundry cronyx -fontname helvetica";
	} else {
	    $options .= " -fontsize 12 -height 20 -whitespace -image_dir $image_dir";
	}
	`$ENV{'GSDLHOME'}/bin/script/gimp/flash_button.pl $options`;

	# get width of new images and edit width macro
	# my $fullfilename = &util::filename_cat ($image_dir, "${image_name}on.gif");
	# &process_width_macro ($fullfilename, $image_name, \$image_macros);

    } elsif ($image_type eq "nav_bar_button") {
	
	# generate on and off images
	my $options = "-text \"$text\" -filenamestem $image_name";
	$options .= " -fontsize 17 -height 17 -fixed_width -width 87";
	$options .= " -image_dir $image_dir";
	# special case for russian images
	if ($language_symbol eq "ru") {
	    $options .= " -foundry cronyx -fontname helvetica";
	}
	`$ENV{'GSDLHOME'}/bin/script/gimp/flash_button.pl $options`;

	# generate green image
	$options = "-text \"$text\" -filename ${image_name}gr.gif";
	$options .= " -image_dir $image_dir";
	# special case for russian images
	if ($language_symbol eq "ru") {
	    $options .= " -foundry cronyx -fontname helvetica";
	}
	`$ENV{'GSDLHOME'}/bin/script/gimp/green_bar.pl $options`;

	# get width of new images and edit width macro
	my $fullfilename = &util::filename_cat ($image_dir, "${image_name}on.gif");
	&process_width_macro ($fullfilename, $image_name, \$image_macros);

    } elsif ($image_type eq "document_button") {

	# generate on and off images
	my $options = "-text \"$text\" -filenamestem $image_name";
	$options .= " -fixed_width -whitespace -image_dir $image_dir";
	if ($language_symbol eq "ru") {
	    $options .= " -fontsize 8 -foundry cronyx -fontname helvetica";
	}
	`$ENV{'GSDLHOME'}/bin/script/gimp/flash_button.pl $options`;

	# get width of new images and edit width macro
	# my $fullfilename = &util::filename_cat ($image_dir, "${image_name}on.gif");
	# &process_width_macro ($fullfilename, $image_name, \$image_macros);

    } elsif ($image_type eq "green_bar_left_aligned") {

	# generate green bar image (we're assuming these bars are always 537
	# pixels and are never stretched by excess text
	my $options = "-text \"$text\" -filename ${image_name}.gif -dont_center";
	$options .= " -width 537 -width_space 15 -image_dir $image_dir";
	if ($language_symbol eq "ru") {
	    $options .= " -foundry cronyx -fontname helvetica";
	}
	`$ENV{'GSDLHOME'}/bin/script/gimp/green_bar.pl $options`;

    } elsif ($image_type eq "green_title") {

	# read the width if it is specified in $image_macros
        my ($width) = $image_macros =~ /_width${image_name}x?_\s*[^\{]*\{(\d+)\}/;
        $width = 200 unless ($width);

        # generate green title image
	my $options = "-text \"$text\" -filename ${image_name}.gif -image_dir $image_dir";
	$options .= " -width $width -height 57 -stripe_alignment right -text_alignment right";
	$options .= " -fontsize 26 -fontweight bold";
	# special case for russian images
	if ($language_symbol eq "ru") {
	    $options .= " -foundry cronyx -fontname helvetica";
	}
	`$ENV{'GSDLHOME'}/bin/script/gimp/title_icon.pl $options`;

	# get width of resulting image and edit _width..._ macro in $image_macros
        # (no longer needed since we always resize to the width read from $image_macros.)
        # my $fullfilename = &util::filename_cat ($image_dir, "${image_name}.gif");
	# &process_width_macro ($fullfilename, $image_name, \$image_macros);

    } elsif ($image_type eq "hand_made") {
	
	$hand_made ++;

    } else {
	
	print STDERR "WARNING (translate.pl): unknown image type found ($image_type)\n";

    }

    return "\n\#\# \"$origtext\" \#\# $image_type \#\# $image_name \#\#$image_macros";
}

sub process_width_macro {
    my ($filename, $image_name, $image_macros) = @_;

    my $img_info = &get_img_info ($filename);
    $$image_macros =~ s/(_width${image_name}x?_\s*(?:\[[^\]]*\])?\s*\{)(\d+)(\})/$1$img_info->{'width'}$3/s;
}

sub add_language_param {
    my ($macroname, $paramlist) = @_;

    my $first = 1;
    if (defined $paramlist) {
	$paramlist =~ s/^\[//;
	$paramlist =~ s/\]$//;
	my @params = split /\,/, $paramlist;
	$paramlist = "";
	foreach $param (@params) {
	    # remove any existing language parameter
	    if ($param !~ /^l=/) {
		$paramlist .= "," unless $first;
		$paramlist .= $param;
		$first = 0;
	    }
	}
    }
    $paramlist .= "," unless $first;
    $paramlist .= "l=" . $language_symbol;
    return "$macroname [$paramlist] {";
}

sub get_img_info {
    my ($imagefile) = @_;
    my %info = ();

    if (!-r $imagefile) {
	print STDERR "ERROR (translate.pl): couldn't open $imagefile to get dimensions\n";
	$info{'width'} = 0;
	$info{'height'} = 0;
    } else {
	my $image = gimp_file_load (RUN_NONINTERACTIVE, $imagefile, $imagefile);
	$info{'width'} = gimp_image_width ($image);
	$info{'height'} = gimp_image_height ($image);
    }

    return \%info;
}

sub query {

  gimp_install_procedure("gsdl_translate", "translate macro files and create images",
                        "", "Stefan Boddie", "Stefan Boddie", "2000-03-14",
                        "<Toolbox>/Xtns/gsdl_translate", "*", &PROC_EXTENSION,
                        [[PARAM_INT32, "run_mode", "Interactive, [non-interactive]"]], []);
}

sub net {
  gsdl_translate;
}

exit main;
