#! /usr/bin/perl

# convert *.po files to texts.* files suitable for gfxboot
# usage: po2txt lang.po >texts.lang
# Note: en.po ist treated specially!

use Getopt::Long;
use IPC::Open2;

sub read_texts;
sub join_msg;

$opt_product = "SUSE Linux";

GetOptions(
  'product=s' => \$opt_product
);


for $lang (@ARGV) {
  $lang = 'en' if $lang eq 'bootloader.pot';
  $lang =~ s/\.po$//;
  read_texts $lang;
}

sub read_texts
{
  local $_;

  my ($lang, @f, $txt, $context, $fuzzy, $t, $p, $ids, $file);

  $lang = shift;

  $file = "$lang.po";
  $file = 'bootloader.pot' if $lang eq 'en';

  if($lang eq 'en') {
    $ids = 1;
  }

  open F, $file;
  @f = (<F>);
  close F;

  map { s/<product>/$opt_product/g; } @f;

  $_ = $lang;
  s/.*\///;

  for (@f) {
    if(/^\s*#\.\s*(txt_\S+)/) {
      if($txt) {
        @msgstr = @msgid if $ids || $fuzzy || join_msg(\@msgstr) eq "";
        $txts{$txt} = join_msg(\@msgstr);
      }

      $txt = $1;

      undef @msgid;
      undef @msgstr;
      undef $context;
      undef $fuzzy;
      next;
    }

    if(/^\s*#,\s*fuzzy/) {
      $fuzzy = 1;
      next;
    }

    next if /^\s*#.*|^\s*$/;
    
    if(/^\s*msgid\s*(\".*\")\s*$/) {
      push @msgid, $1 unless $1 eq '""';
      $context = 1;
      next;
    }

    if(/^\s*msgstr\s*(\".*\")\s*$/) {
      push @msgstr, $1 unless $1 eq '""';
      $context = 2;
      next;
    }

    if(/^\s*(\".*\")\s*$/) {
      if($context == 1) {
        push @msgid, $1;
      }
      elsif($context == 2) {
        push @msgstr, $1;
      }
      else {
        die "format oops in ${lang}.po: $_"
      }
    }
  }

  if($txt) {
    @msgstr = @msgid if $ids || $fuzzy || join_msg(\@msgstr) eq "";
    $txts{$txt} = join_msg(\@msgstr);
  }

  @txts = sort keys %txts;

  for (@txts) {
    $txt = $txts{$_};
    $txt =~ s/\\"/"/g;
    $txt =~ s/\\\\/\\/g;
    $txt =~ s/\\n/\n/g;
    if($lang eq "he")
    {
      my $bidi_pid = open2(\*BIDI_OUT, \*BIDI_IN, 'fribidi', '--nopad', '--nobreak');
      print BIDI_IN $txt;
      close BIDI_IN;
      { local $/ = undef; $txt = <BIDI_OUT>; }
      $txt =~ s/(.)%/%$1/g;
      waitpid $bidi_pid, 0;
    }
    print "$txt\x00"
  }

  if($ids) {
    open W, ">text.inc";
    print W "%\n% This file is generated automatically. Editing it is pointless.\n%\n\n";
    print W "/texts [\n";
    $p = pop @txts;
    for (@txts) { print W "  /$_\n" }
    print W "  /$p\n] def\n";
    close W;
  }
  else {
    open F, "text.inc";
    for (<F>) {
      if(/\s+\/(txt_\S+)/) {
        $txt_ref{$1} = undef;
      }
    }
    close F;
    my (%txt_list, %txt_miss, %txt_unknown, %txt_multi);
    for (@txts) {
      $txt_list{$_}++;
      $txt_multi{$_} = 1 if $txt_list{$_} > 1;
    }
    for (@txts) {
      $txt_unknown{$_} = 1 unless exists $txt_ref{$_};
    }
    for (keys %txt_ref) {
      $txt_miss{$_} = 1 unless exists $txt_list{$_};
    }

    if(%txt_miss || %txt_unknown || %txt_multi) {
      print STDERR "$lang:\n";
      for (sort keys %txt_miss) {
        print STDERR "  missing: $_\n"
      }
      for (sort keys %txt_unknown) {
        print STDERR "  unknown: $_\n"
      }
      for (sort keys %txt_multi) {
        print STDERR "  multi: $_\n"
      }
    }
  }

}


sub join_msg
{
  local $_;
  my ($s, $msg, $m);

  $msg = shift;

  for $s (@{$msg}) {
    $_ = $s;
    s/^\"(.*)\"$/$1/;
    $m .= $_;
  }

  return $m;
}
