#!/usr/bin/perl -w

# po-i18n-check - scanning recursively for catalog of messages and parse its translatable sections

# This is a hack of
# http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdesdk/scripts/kde-spellcheck.pl
# Revision 1.18
# Artistic License, Dirk Mueller <mueller@kde.org> 2003.

# This software released under the terms of the Artistic License
# <http://www.opensource.org/licenses/artistic-license.html>

# Changues:
# Copyright (C) 2003 by Antoni Bella <bella5@teleline.es>
# Version 0.1
#    - ui output use a *dialog interface (si it is available) or a console (text).
#    - This hack parse a catalog of messages suggesting possible changes.
#    - The hash is modified completely for the Catalan language.
#    - Use gettxet utilities for encode.

# TODO:
#    - Apply your improvements/whislist (if I can) ;-)

# You are going to modify it?
#    - Adapt the hash. "HASH"
#    - Change charset to your language code. "CS"
#    - Translate messages of the user interface. "UI"
#        * added references
#            ca=Catalan
#            en=English


use POSIX;
use strict;

# "CS"
# charset
my $lcode = 'ISO-8859-15';

# check the dependencies
die "Error: This program require Gettext utilities!!\n\n" if (!qx(which msgconv));

# Multiple references for the hash
my $sep = '----------';
my $bookmark = "bookmark: Un «punt» d'Internet.\nlink: Un fitxer «enllaç».\nmarcador -> Una marca en un fitxer de text.\n$sep\nUn punt a l'escrit/imatge.\nEl meu punt de vista.\nPunts en el joc/test.";
my $arrencada = "arrenca | arrencar | partició d'arrencada | durant la següent arrencada del sistema (modificar la frase per a que s'avingui)";
my $ates = "atés que es tracta d'un directori | es deu a que | per culpa de | a causa de";
my $settings = "Options: Opcions\nSettings: Arranjament | Configuració | Preferències";
my $prova = "prova | comprova com va això\n$sep\nprobable | probablement";
my $amunt = "amunt (lloc o nivell més alt.)\navall (lloc o nivell més baix.)\n_a baix | a sota (a on? a baix | vista des d'abaix | inferior.)\n_a dalt | a sobre (a on? a dalt | vista des d'adalt | superior)\n$sep\na sobre de | quant a";

# "HASH"
my %fix = (
# The flat hyphen means that it is a suggestion.
# ca: El guió pla vol dir que es tracta d'un suggeriment d'estil.
    # ca: NO!!
    "oculta" => "hola",
    "á" => "Accent ¿? -- á -> à",
    "ì" => "Accent ¿? -- ì -> í",
    "ù" => "Accent ¿? -- ù -> ú",
    "ñ" => "Error ¿? -- ñ -> ny",
    " y " => "Error ¿? -- y -> i",
    # ca: Gènere
    "el CPU" => "la CPU",
    # ca: Pronoms
    " lus " => "l'ús",
    "m'els" => "me'ls",
    " mels" => "me'ls",
    "s'el " => "se'l",
    " sel " => "se'l",
    "s'els" => "se'ls",
    "sels" => "se'ls",
    "s'em " => "se'm",
    " sem " => "se'm",
    "s'hem" => "se'm",
    "s'ens" => "se'ns",
    " sens " => "se'ns",
    "s'et" => "se't",
    " susa " => "s'usa",
    "s'us " => "se us",
    "su's" => "se us",
    "t'els" => "te'ls",
    "t'el" => "te'l",
    "t'em" => "te'm",
    "t'hem" => "te'm",
    "t'ens" => "te'ns",
    " tens " => "te'ns",
    "t'en" => "te'n",
    " ten " => "te'n",
    # ca: errades comuns o munió de criteris
    "a munt" => "$amunt",
    "a vall" => "$amunt",
    "aball" => "$amunt",
    "a baix" => "$amunt",
    "abaix" => "$amunt",
    "a dalt" => "$amunt",
    "adalt" => "$amunt",
    "a sobre" => "$amunt",
    "asobre" => "$amunt",
    #
    "inch" => "polzades (mesura de longitud i de quantitat | el dit polze)",
    "polsad" => "polzada (mesura de longitud i de quantitat | el dit polze)",
    # Misc
    "aborta" => "avorta aquesta acció",
    "ademés" => "a demés",
    "algún" => "algun",
    "ancora" => "àncora | ancorar (una aplicació ancorada a la safata del sistema)",
    "anula" => "anul·la aquesta acció",
    "aplet" => "_applet | miniaplicació",
    "arranca" => "$arrencada",
    "arranqueu" => "$arrencada",
    "autorit" => "autenticació d'una contrasenya | sols estaran autoritzats",
    "avans" => "abans",
    "avis" => "avís d'error | avisa'm",
    "bora " => "_vora | contorn | aresta",
    "cambia" => "canvia",
    "camvi" => "canvi",
    "cancela" => "cancel·la",
    "cancella" => "cancel·la",
    "cela" => "cel·la",
    "chip" => "xip",
    "colec" => "col·lecció",
    "colegi" => "col·legi",
    "coloca" => "col·loca",
    "coloqui" => "col·loqui",
    "comte" => "compte d'usuari | comptador d'ítems",
    "compta" => "compte d'usuari | comptador d'ítems",
    "conecta" => "connecta",
    "conector" => "connector",
    "conexió"=> "connexió",
    "contindre" => "contenir | hauria de contenir l'eixida",
    "defecte" => "_per omissió | omissió | defecte | per defecte",
    "degut" => "$ates",
    "diga" => "digui",
    " disol " => "dissol (soluble en aigua)",
    "dracera" => "drecera",
    "diseny" => "disseny",
    "donat que" => "$ates",
    "el·labora" => "elabora",
    "email" => "correu electrònic | correu-e",
    "encripta" => "xifra | desxifra un contingut (criptogràfic | criptografia)",
    "endarrera" => "endarrere",
    "endollat" => "connector",
    "enllaç" => "$bookmark",
    "errònea" => "errònia",
    "es sap" => "se sap",
    "escritori" => "escriptori",
    "estigan" => "estiga'n",
    "estiguan" => "estiga'n",
    "estreu" => "extreu una cosa",
    "expon" => "exposa | exposar",
    "extes" => "partició estesa de Linux",
    "formate" => "formatat d'un disquet",
    "fussi" => "fusió | fusionar",
    "gracies" => "gràcies per tot (l'accent)",
    "haurieu" => "hauríeu (l'accent)",
    "hi han" => "_hi ha algunes coses",
    "ilegal" => "aquest negoci sembla il·legal",
    "indenta" => "_sagna el text",
    "identa" => "_sagna el text",
    "interpret" => "intèrpret | interpretació",
    "introduida" => "introduïda",
    "introduiu" => "introduïu",
    "invàlid" => "_no vàlid",
    "lactual" => "l'actual",
    "l'icona" => "la icona",
    "l'instalació" => "la instal·lació",
    "l'universitat" => "la universitat",
    "la última" => "l'última",
    "línea" => "línia de text",
    "llabors" => "_llavors | llavores (mirar que no es refereixi a la grana)",
    "llabores" => "llavores | llavors",
    "mantindre" => "mantenir",
    "marcador" => "$bookmark",
    "mirall" => "rèplica del servidor",
    "modem" => "mòdem",
    "obtindre" => "obtenir el que es vol",
    "pendre" => "prendre la pilota",
    "permissos" => "permisos per accedir-hi",
    " pero " => "però",
    "plugin" => "connector",
    "punt" => "$bookmark",
    "proba" => "$prova",
    "procesa" => "processa les dades",
    "provab" => "$prova",
    "pixel" => "píxel de la pantalla",
    " prous " => "prou permisos",
    "revut" => "rebut dades (rebre)",
    "sencill" => "senzill (simple | sense cap complicació)",
    "sigan" => "siga'n",
    "siguan" => "siga'n",
    "siusplau" => "si us plau",
    "solicit" => "sol·lícit | sol·licitar | sol·licitud",
    "sols " => "tan sols es requerirà | _només serà necessari | sols lectura",
    "sotmetre" => "enviar (submit)",
    "tals com" => "com ara",
    "tantmateix" => "tanmateix",
    "tant sols" => "tan sols",
    "tinc que" => "he de fer-ho",
    "tenen que" => "s'han de comptar",
    " tindre " => "tenir el torn de joc",
    "tindre-" => "tenir-la a punt",
    "tindreu" => "_haureu de fer-ho | tindreu els permisos",
    "volguem" => "vulguem anar-hi",
    # English translatable
    "array" => "matriu",
    "audio" => "àudio",
    "backup" => "còpia de seguretat",
    "bitmap" => "mapa de bits",
    "bootloader" => "carregador d'arrencada",
    "box" => "_caixa | màquina | sistema",
    "broadcast" => "difusió",
    "buffer" => "memòria cau | cau | memòria temporal (framebuffer no es tradueix)",
    "bug" => "error de programació",
    "built-in" =>  "encastada | integrada",
    "byte" => "_octet",
    "cache" => "memòria cau",
    "charset" => "joc de caràcters",
    "checksum" => "suma de control",
    "cipher" => "xifra | xifres (fa referència al xifrat)",
    "click" => "clic | clicar | cliqueu",
    "clipart" => "fitxer d'imatges",
    "cookie" => "galeta des d'un servidor d'!nternet",
    "core" => "protocol base (core protocol), biblioteques esencials (core libraries)",
    "dialer" => "marcador",
    "Enter" => "Intro",
    "firewall" => "tallafocs",
    "fire-wall" => "tallafocs",
    "fire wall" => "tallafocs",
    "firmware" => "microprogramari",
    "footer" => "peu | peu de pàgina",
    "free software" => "_programari lliure",
    "Free Software"  => "_Programari Lliure (a excepció d'un nom propi)",
    "gateway" => "passarel·la",
    "GUI" => "IGU (Interfície Gràfica d'Usuari)",
    "hardware" => "maquinari",
    "I/O" => "E/S de l'aplicació o del maquinari (entrada/sortida)",
    "kernel" => "_nucli (Linux | *BSD | Hurd) ",
    "login" => "entrada | _accés",
    "logo" => "_logotip del Narangito",
    "member" => "membre de la comunitat",
    "mirror" => "rèplica del servidor",
    "netmask" => "màscara de xarxa",
    "non-parity" => "sense paritat",
    "offset" => "desplaçament",
    "patch" => "pedaç amb les millores",
    "prompt" => "indicatiu de la consola",
    "proxy" => "servidor intermediari",
    "query" => "consulta a la base de dades",
    "raw" => "en cru (format pur)",
    "render" => "representar | renderitzar una imatge",
    "report" => "informar d'un error",
    "reset" => "reinici de l'ordinador | reajusta el mòdem",
    "ripper" => "extractor de pistes de CD",
    "root" => "root l'usuari | arrel del sistema de fitxers",
    "Shift" => "Majús. (la tecla de majúscules)",
    "slot" => "ranura d'expansió",
    "socket" => "connector",
    "software" => "programari",
    "source" => "font | origen",
    "tarball" => "arxiu tar",
    "verbose" => "depuració",
    "widget" => "estri del programa",
    "zoom" => "apropa | allunya (zoom in | zoom out)"
     );

# Check out the enviroment and it looking a *dialog
    my $dialog =0;
    if ( $ENV{'DISPLAY'} ) {
        for ("kdialog", "zenity", "gdialog", "xdialog", "dialog") {
            if ($dialog eq 0) {
                $dialog = $_ if (qx(which $_));
            }
        }
    }
    else {
        $dialog = 'dialog' if (qx(which dialog));
    }
    # Set the *dialog arguments
    my $title = '--title';
    my $box = '--yesno';
    my $heigth = 24;
    my $with = 62;

sub nota() {
system("echo -e \"\n\033[4mWarning for «$dialog»!!\033[0m\n
    - It had not been proved yet with this GUI and you are making it now.
      Please, brief some of the results to the author. Thank you
      .
      Antoni Bella <bella5 AT teleline DOT es>\n\n\"");
system("echo -e \"\n\033[4m--Answer:\033[0m [c & Enter]=Cancel [Enter]=Continue\n\"");
chop (my $valor = <STDIN>);
exit 0 if ($valor eq 'c');
}
nota() if ($dialog eq 'zenity' or 'gdialog' or 'xdialog');

sub spell_file($)
{
    my ($f) = @_;
    my $read_line = 0;
    my $name_file = "$`$&";

    print "Parsing: $name_file\n********\n";
    if(open(IN, "<$f")) {
        my @c = <IN>;

         my $num_entry = -1;
        foreach my $line (@c) {
            chop $line;
            # Only parse translated messages and initiate his counter
            $read_line = 1 if ($line =~ /^msgstr/);    # BEGIN
            $read_line = 0 if ($line =~ /^#: /);          # END
            $num_entry++ if ($line =~ /^msgstr /);  # counter
            # Edit wether we can accept the data
            $line =~ s/^msgstr\s*\"//;
            $line =~ s/^"//;    # begin quotation (gettext)
            $line =~ s/"$//;    # end quotation (gettext)
            $line =~ s/&//;    # accelerators
            $line =~ s/\`//;    # `accents
            # Skip the header
            next if ($num_entry <= 0);
            next if ($line =~ /^#~ /);
            if ($read_line != 0) {
                foreach my $w (keys %fix) {
                    # A loop for upercase words
                    my $w_orig = $w;
                    my $w_upercase = ucfirst $w;
                    for ("$w_orig", "$w_upercase") {
                        if ($line =~ /$_/) {
                            my $w_require = $fix{$_};
                            if ($dialog ne 0) {
                                # "UI"
                                # GUI output
                                system("$dialog $title \"** $name_file **\" $box \"Entrada: $num_entry\n ${line}\nConsell per a: «$_»\n $w_require\n\" $heigth $with");
                                exit 0 if (system("[ $? = 0 ]"));
                             }
                             else {
                                 # console output
                                 # "UI"
                                 # ca=«Mirar:» en=«See»
                                 system("echo -e \"\033[4m* Mirar:\033[0m\a\"");
                                 # ca=«Entrada:» en=«Entry»
                                 system("echo -e \"    \033[4m- Entrada:\033[0m «$num_entry»\"");
                                 system("echo -e \"    | $line\"");
                                 # ca=«Consell per a:» en=«To suggest»
                                 system("echo -e \"    \033[4m- Consell per a:\033[0m «$_»\"");
                                 system("echo -e \"    | $w_require\n\"");
                                 # Question
                                 # ca=«--Respondre: [c / i Intro]=Cancel·la [Intro]=Continua»
                                 # en=«--Answer: [c & Enter]=Cancel [Enter]=Continue»
                                 system("echo -e \"\033[4m--Respondre:\033[0m [c / i Intro]=Cancel·la [Intro]=Continua\n\"");
                                 chop (my $valor = <STDIN>);
                                 exit 0 if ($valor eq "c");
                             }
                        }
                    }
                }
            }
        }
        close (IN);
        unlink "/tmp/$name_file";
    }
}

my @dirqueue = ();

sub processDir($)
{
    my ($d) = @_;
    my $e;

    print "processDir: $d\n";

    opendir (DIR, "$d") || die "couldn't read dir: $d";
    while ($e = readdir(DIR)) {
        next if ($e eq ".");
        next if ($e eq "..");
        next if ($e eq "CVS");
        next if ($e eq "data");
        next if ($e eq ".cvsignore");
        next if ($e eq "charset");
        next if ($e =~ /\.desktop$/);
        next if ($e =~ /^Makefile/);
        next if ($e =~ /\.docbook$/);
        next if ($e =~ /\.png$/);
        push (@dirqueue, "$d/$e") if (-d ("$d/$e"));
        next if (-d ("$d/$e"));

        my $type = qx(file $d/$e);
        if ($type !~ /(text|ASCII)/i) {
            print "** Skipping: «$e»\n";
            next;
        }
        # Only parse catalog files
        if ($e =~ /.po$/) {
            next if ($e =~ /^\.desktop$/);
            # Frist encode to ISO-8859-15
            qx(msgconv --output-file=/tmp/$e --to-code=$lcode $d/$e 2>/dev/null);
            if (-f ("/tmp/$e")) {
                # Parse this file
                &spell_file("/tmp/$e");
            }
            else {
                # Error message if the encode fail
                system("$dialog \"Error of msgconv\" $box \"$e\n\nError: This catalog was not encoded.\" 10 30")
            }
        }
        else {
            print "** Error: «$e» is not a catalog of messages!!\n";
        }
    }
    closedir(DIR);
}

push (@dirqueue, getcwd());

while($#dirqueue >= 0) {
    processDir( pop @dirqueue );
}

# End message
    my $missatge = "** Task finished";
    if ($dialog ne 0) {
        system("$dialog $title \"** Help of translation **\" --msgbox \"$missatge\" 6 30");
    }
    else {
        print "\n\t$missatge\n\n";
    }

