#!/usr/bin/perl -w
#
# Author: Petter Reinholdtsen <pere@td.org.uit.no>
# Date:   2001-08-05
# Source: http://www.student.uit.no/~pere/linux/
#
# Read available translations from .po files, and allow translations
# already done in one file to be inserted into all the other places
# where the original text occurs.
#
# Usage: auto_translate <po-files>
#
# Changes:
#   2001-08-05 v0.2
#      Fixed bug.  Unable to handle multiline 'msgid'.
#   2001-08-05 v0.3
#      Add 'fuzzy' tag when inserting text.
#   2001-08-05 v0.4
#      Only add 'fuzzy' tag in the changed files.

#use strict;
use Getopt::Std;

my ($pofile, %translation, @problem, %msgstrs, %files);
my $showfile = 1;

#########################################################################

sub add_translation {
  my ($pofile, $msgid, $msgstr) = @_;
#  print " Translation: $msgid = $msgstr\n";
  $msgstr = $1;
  $msgstrs{"$msgid\t$msgstr"}++;
  push(@{$files{"$msgid\t$msgstr"}}, $pofile);
  if ( !defined($translation{$msgid}) ) {
    push(@{$translation{$msgid}}, $msgstr);
  } else {
    if ( ! in_array($msgstr, $translation{$msgid}) ) {
      push(@{$translation{$msgid}}, $msgstr);
      push(@problem, $msgid) unless grep($msgid, @problem);
    }
  }
  $msgid = "";
}

sub in_array ($$) {
  my ($str, $aref) = @_;
  my $test;
  for $test (@$aref) {
    return 1 if ($test eq $str);
  }
  return 0;
}

sub replace_translation {
    my ($filename, $msgid, $msgstr) = @_;
    my $count = 0;
    open(POTMPFILE, ">$filename.new") || die "Unable to open $filename.new";

    open(POFILE, "<$filename") || die "Unable to open $filename";
    while (<POFILE>) {
        chomp;
        my @lines = ();
        if (m/^msgid\s+\"(.*)\"\s*$/) {
            my $thisid = $1;
            my $thisstr = "";
            push(@lines, $_);
            while (<POFILE>) {
                chomp;
                push(@lines, $_);
                if (m/^\s*\"(.+)\"\s*$/) {
                    print "Appending \'$thisid\' \n  + \'$1\'\n" if ($debug);
                    $thisid .= $1;
                }
                if (m/^msgstr\s\"(.*)\"\s*$/) {
                    print "ID: $thisid\n" if ($debug);
                    $thisstr = $1;
                    while (<POFILE>) {
                        chomp;
                        push(@lines, $_);
                        last if (/^\s*$/);
                        if (m/^\s*\"(.+\")\s*$/) {
                            $thisstr .= $1;
                        }
                    }
                    print "Msg: $thisstr\n" if ($debug);
                    last;
                }
            }
            if ("\"$thisid\"" eq $msgid &&
                "\"$thisstr\"" ne $msgstr) {
                print POTMPFILE "#, fuzzy\n";
                print POTMPFILE "msgid $msgid\n";
                print POTMPFILE "msgstr $msgstr\n";
                print POTMPFILE "\n";
                $count++;
            } else {
                print POTMPFILE join("\n", @lines), "\n";
            }
        } else {
            print POTMPFILE "$_\n";
        }
    }
    close(POFILE) || die "unable to close $filename";
    close(POTMPFILE) || die "unable to close $filename.new";
    rename "$filename.new", $filename;

    if (0 == $count) {
        print "Did not find anything to replace!\n";
    }
}

sub choose_transl {
  my ($msgid) = @_;
  print "\n$msgid\n";
  my $msgstr;
  my $num = 0;
  print "  $num - skip this translation\n";
  my @strings = sort { $msgstrs{"$msgid\t$b"} <=> $msgstrs{"$msgid\t$a"}; } @{$translation{$msgid}};
  my %curfiles;
  for $msgstr (@strings) {
      $num++;
      print "  $num $msgstr # (" . $msgstrs{"$msgid\t$msgstr"}. ") " or die;
      print "[" . join(",", @{$files{"$msgid\t$msgstr"}}) . "]" or die if $showfile;
      print "\n" or die;
      my $file;
      for $file (@{$files{"$msgid\t$msgstr"}}) {
          $curfiles{$file}++;
      }
  }
  if ($num != 2)
  {
      print "** To many choices. **\n";
      return;
  }

  print "Choice: ";
  $choice = <STDIN>;

  return if (0 == $choice);
  $msgstr = $strings[$choice-1];
  print "\n  Translating $msgid as $msgstr in\n";
  for $file (keys %curfiles) {
      print "    $file\n";
      replace_translation($file, $msgid, $msgstr);
  }
}

# Remove leading space and '&' before comparing
sub kde_magic_sort {
  my $aa = $a;
  my $bb = $b;

  $aa =~ s/\&|^\s+//;
  $bb =~ s/\&|^\s+//;
  return lc($aa) cmp lc($bb);
}

sub translate {
  my ($msgid);
  my ($count, $icount) = (0,0);
  for $msgid (sort kde_magic_sort keys %translation ) {
      $count++;
      if ( 1 < scalar(@{$translation{$msgid}}) ) {
          $icount++;
          choose_transl($msgid);
      }
  }
}

sub read_files
{
    my @argv = @_;

    for $pofile ( @argv ) {
        open(POFILE, "<$pofile") || next;

        my ($next, $msgid, $msgstr);

        while (1) {
            $_ = $next || <POFILE>;
            last unless $_;
            $next = "";

            chomp;

            s/^\#.+$//; # Remove comments

            next if (/^\s*$/);

            if (/^msgid (\".+)/) {
                $msgid = $1;
                while (<POFILE>) {
                    chomp;
                    unless (/^\"/) {
                        $next = $_;
                        last;
                    }
                    $msgid .= $_;
                    $msgid =~ s/\"\"//;
                }

                $msgstr = "";
                next;
            }

            if (/^msgstr (\".+)/) {
                $msgstr = $1;
                while (<POFILE>) {
                    chomp;
                    unless (/^\"/) {
                        $next = $_;
                        last;
                    }
                    $msgstr .= $_;
                    $msgstr =~ s/\"\"//;
                }

                add_translation($pofile, $msgid, $msgstr);

                $msgid = "";
                $msgstr = "";
            }

        }
        close(POFILE);
    }
}
#########################################################################

getopt('f');

if (defined $opt_f) {
    $showfile = 1;
    print "Showing filenames\n";
}

print "Reading .po files...\n";
read_files(@ARGV);

print "Ready to autotranslate\n";
translate();

