/*
    Fichier tradmail.c
    Auteur Bernard Chardonneau

    Logiciel libre, droits d'utilisation précisés en français
    dans le fichier : licence-fr.txt

    Traductions des droits d'utilisation dans les fichiers :
    licence-de.txt , licence-en.txt , licence-es.txt ,
    licence-it.txt , licence-nl.txt , licence-pt.txt ,
    licence-eo.txt , licence-eo-utf.txt

    Droits d'utilisation également sur la page web :
    http://libremail.tuxfamily.org/voir.php?page=droits


    Bibliothèque de fonctions permettant de :

    - spécifier la langue d'origine du mail
    - lancer sa traduction dans la langue de l'utilisateur
*/


#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "messages.h"
#include "buflect.h"
#include "trtligne.h"
#include "groupeligne.h"
#include "modepage.h"
#include "carspe.h"
#include "szchemin.h"
#include "tradmail.h"

#define  szlig   120  // longueur maximale des lignes du fichier trad-libremail

#define  AUCUN     0  // pas de conversion de caractères
#define  ISO_UTF   1  // conversion de iso-8859-1 à utf-8 nécessaire
#define  UTF_ISO   2  // conversion de utf-8 à iso-8859-1 nécessaire



/* prototype */
void genligne (char *buffer);

/* prototypes de fonctions locales à ce source */

void recup_chemtradlib ();
void select_trad (int numlangue);


/* variable globale au source */

char chemtradlib [szchemin] = ""; // chemin d'accès au fichier trad-libremail
char fic_cmd_trad [20] = "";      // fichier contenant la commande de traduction
FILE *ftradlib = NULL;            // descripteur du fichier trad-libremail
int  convert_car;                 // jeu de caractères du logiciel de traduction




/* recherche du chemin d'accès au fichier trad-libremail */

void recup_chemtradlib ()
{
    char *resenv;

    // si ce chemin d'accès est mémorisé dans une variable d'environnement
    resenv = getenv ("trad-libremail");

    if (resenv)
        // le récupérer
        strcpy (chemtradlib, resenv);
    // sinon
    else
    {
        // si libremail est implanté localement
        if (strcmp (dircom (), "/usr/bin") != 0)
            // fichiers de données dans le même répertoire que les commandes
            sprintf (chemtradlib, "%s/%s", dircom (), "trad-libremail");
        // sinon, les commandes de libremail sont dans /usr/bin
        else
            // et les fichiers de données dans /usr/share/libremail
            strcpy (chemtradlib, "/usr/share/libremail/trad-libremail");
    }
}


/* sélection de la langue d'origine du mail */

void choixlangue (int dialogue)
{
    unsigned char ligne_ftrad [szlig];
    int  nbtrad, numtrad;
    int  car;
    int  i;


    // récupérer si nécessaire le nom du fichiers qui contienda
    // la commande de traduction
    if (! *fic_cmd_trad)
        if (getenv ("libremail-cmd-trad"))
            strcpy (fic_cmd_trad, getenv ("libremail-cmd-trad"));
        // si la processus père n'a pas fabriqué la chaine, le faire
        else
            sprintf (fic_cmd_trad, "/tmp/cmd-trad-%04X", getppid ());

    // initialisation
    nbtrad = 0;
    convert_car = AUCUN;

    // si le fichier trad-libremail n'a pas été ouvert auparavant
    if (! ftradlib)
    {
        // si on n'a pas encore récupéré le chemin d'accès à ce fichier
        if (! *chemtradlib)
            // le récupérer
            recup_chemtradlib ();

        // tenter d'ouvrir le fichier en lecture
        ftradlib = fopen (chemtradlib, "r");
    }

    // si le fichier a pu être ouvert
    if (ftradlib)
    {
        // se positionner au début du fichier (si on l'a déja exploré)
        rewind (ftradlib);

        // "Traductions disponibles"
        affiche_msg ("TRAD_DISPO");

        // tant qu'on n'a pas lu en entier le fichier trad-libremail
        // lire une ligne
        while (fgets (ligne_ftrad, szlig, ftradlib))
        {
            // si la ligne contient une information sur un type de traduction
            if (*ligne_ftrad >= 'A')
            {
                // afficher le numéro de la traduction
                printf ("%d : ", ++nbtrad);
                i = 0;

                // afficher le mnémonique en début de ligne
                do
                {
                    // en remplaçant les _ par des espaces
                    if (ligne_ftrad [i] != '_')
                        putchar (ligne_ftrad [i]);
                   else
                        putchar (' ');

                    i++;
                }
                // jusqu'à ce qu'on trouve un blanc ou une tabulation
                while (ligne_ftrad [i] > ' ');

                putchar ('\n');
            }
            // sinon si directive sur le jeu de caractères du traducteur
            else if (*ligne_ftrad == '#' && ligne_ftrad [1] == '!')
            {
                // la prendre en compte si nécessaire
                if (tolower (ligne_ftrad [2]) == 'i' && util_utf8 ())
                    convert_car = UTF_ISO;
                else if (tolower (ligne_ftrad [2]) == 'u' && ! util_utf8 ())
                    convert_car = ISO_UTF;
            }
        }

        // si plus d'un mode de traduction possible
        if (nbtrad > 1)
        {
            // "Numéro de traduction choisi ?"
            affiche_msg ("NUMTRAD_CHOISI");
            numtrad = 0;

            do
            {
                car = leccar ();

                if (car >= '0')
                    numtrad = (numtrad * 10) + (car - '0');
            }
            while (numtrad <= (nbtrad / 10) && car != '\n');

            if (1 <= numtrad && numtrad <= nbtrad)
                select_trad (numtrad);
            else
                // "Numéro de traduction incorrect"
                affiche_msg ("NUMTRAD_INCORRECT");
        }
        // sinon si un seul mode de traduction
        else if (nbtrad == 1)
        {
            select_trad (1);

            if (dialogue)
            {
                // "C'est le type de traduction sélectionné"
                affiche_msg_nocr ("CHOIXTRAD_UNIQUE");
                attendre (2);
            }
        }
        // sinon erreur
        else
        {
            // "Aucun mode de traduction défini dans trad-libremail"
            affiche_msg ("AUCUNE_TRAD");
        }
    }
    // sinon
    else
    {
        // éditer le message d'erreur adéquat
        if (access (chemtradlib, 0) == 0)
            // "Fichier %s protégé en lecture"
            aff_err_arg ("ACCES_FICH_LECT", chemtradlib);
        else
            // "Fichier %s manquant ou inaccessible"
            aff_err_arg ("FICH_MANQUANT", chemtradlib);
    }

    // message si on n'a pu sélectionner aucune traduction
    if (access (fic_cmd_trad, 0) != 0)
    {
        // "Appuyez sur une touche pour continuer"
        affiche_msg ("ATTENTE_CLAVIER");
        leccar ();
    }
}


/* sélection d'une commande de traduction du mail */

void select_trad (int numlangue)
{
    unsigned char ligne_ftrad [szlig];
    char *retour;
    FILE *fcmdtrad = NULL;  // descripteur du fichier fic_cmd_trad
    int  i;


    // revenir au début du fichier trad-libremail
    rewind (ftradlib);

    // initialisation compteur
    i = 0;

    // recherche de la ligne du fichier contenant la commande de traduction
    do
    {
        // lire une ligne du fichier
        retour = fgets (ligne_ftrad, szlig, ftradlib);

        // si la ligne contient une information significative
        if (*ligne_ftrad >= 'A')
            // incrémenter le compteur
           i++;
    }
    // on s'arrête sur la bonne ligne ou en fin de fichier
    while (i < numlangue && retour);

    // si ligne trouvée dans le fichier
    if (retour)
    {
        // sauter le mnémonique en début de ligne
        i = 0;

        while (ligne_ftrad [i] > ' ')
            i++;

        // sauter les espaces et tabulations qui suivent
        while (ligne_ftrad [i] == ' ' || ligne_ftrad [i] == '\t')
            i++;

        // ouvrir le fichier qui contiendra la commande de traduction
        fcmdtrad = fopen (fic_cmd_trad, "w");

        // si l'ouverture en écriture s'est bien passée
        if (fcmdtrad)
        {
            // récupérer et mémoriser cette commande de traduction
            while (ligne_ftrad [i] && ligne_ftrad [i] != '\n')
                fputc (ligne_ftrad [i++], fcmdtrad);

            fclose (fcmdtrad);
        }
    }
}


/* traduction du mail */

int trad_mail (char *nomfic, int mode_affich, char *fic_mailtrad, char **ligne)
{
    char commande_trad [szlig]  = ""; // sous-commande appelant le traducteur
    char cmd_trad_mail [szlig + 50] = ""; // commande pour traduire le mail
    char *charcmdtrad;                // un caractère de cmd_trad_mail
    char *ajoutmode;
    FILE *fcmdtrad = NULL;            // descripteur du fichier fic_cmd_trad
    FILE *fmtrad;
    int  numlig;


    // récupérer si nécessaire le nom du fichier qui contienda
    // la commande de traduction
    if (! *fic_cmd_trad)
        if (getenv ("libremail-cmd-trad"))
            strcpy (fic_cmd_trad, getenv ("libremail-cmd-trad"));
        // si la processus père n'a pas fabriqué la chaine, le faire
        else
            sprintf (fic_cmd_trad, "/tmp/cmd-trad-%04X", getppid ());

    // fabriquer si nécessaire le nom du fichier qui contienda
    // le mail traduit (sans une partie de l'entête)
    if (! *fic_mailtrad)
        sprintf (fic_mailtrad, "/tmp/mail-trad-%04X", getpid ());


    // si pas encore de langue de choisie pour le texte d'origine, le faire
    if (access (fic_cmd_trad, 0) != 0)
    {
        effpage ();
        fflush (stdout);

        choixlangue (0);
    }


    // si le fichier contenant la traduction n'existe pas encore
    if (access (fic_mailtrad, 0) != 0)
    {
        // ouvrir le le fichier contenant la sous-commande de traduction
        fcmdtrad = fopen (fic_cmd_trad, "r");

        // si l'ouverture s'est bien passée
        if (fcmdtrad)
        {
            // récupérer la sous-commande de traduction
            fgets (commande_trad, szlig, fcmdtrad);

            // on peut refermer ce fichier
            fclose (fcmdtrad);

            // fabriquer la commande pour traduire le mail

            // si le jeu de caractères nécessaire au traducteur
            // n'est pas celui utilisé par l'ordinateur
            if (convert_car)
            {
                // on va passer au jeu de caractères du traducteur
                sprintf (cmd_trad_mail, "LANG=%s", getenv ("LANG"));

                // rechercher l'endroit dans $LANG où l'indication
                // .UTF-8 se trouve ou doit être rajoutée
                charcmdtrad = &cmd_trad_mail [6];

                while (*charcmdtrad && *charcmdtrad != '.'
                                    && *charcmdtrad != '@')
                    charcmdtrad ++;

                // rajouter ou supprimer le .UTF-8 au nouveau $LANG
                if (convert_car == ISO_UTF)
                    strcpy (charcmdtrad, ".UTF-8 ; ");
                else
                    strcpy (charcmdtrad, " ; ");
            }
            // sinon, on conserve le même jeu de caractères
            else
                *cmd_trad_mail = '\0';

            // voirfmail -T
            strcat (cmd_trad_mail, "voirfmail -T ");

            // rajout option -H éventuelle
            if (mode_affich == TextHtml)
                strcat (cmd_trad_mail, "-H ");

            // rajout nom du mail à traduire
            strcat (cmd_trad_mail, nomfic);

            // rajout commande de traduction
            strcat (cmd_trad_mail, " | ");
            strcat (cmd_trad_mail, commande_trad);

            // revenir si nécessaire au jeu de caractères de l'ordinateur
            if (convert_car)
            {
                if (convert_car == ISO_UTF)
                    strcat (cmd_trad_mail, " | utf8-iso8859");
                else
                    strcat (cmd_trad_mail, " | iso8859-utf8");
            }

            // ajout d'une redirection vers le fichier du mail traduit
            strcat (cmd_trad_mail, " > ");
            strcat (cmd_trad_mail, fic_mailtrad);

            // et exécuter cette commande de traduction
            system (cmd_trad_mail);
        }
    }


    // essayer d'ouvrir le fichier contenant le mail traduit
    fmtrad = fopen (fic_mailtrad, "r");

    // s'il a pu être ouvert
    if (fmtrad)
    {
        // chercher la ligne du mail d'origine contenant le sujet
        numlig = 0;

        while (memcmp (ligne [numlig], "Subject", 7) != 0
                                && ligne [numlig][0] != 0)
            numlig ++;

        // effacer cette ligne et tout ce qui suit
        while (nb_lignes > numlig)
            free (ligne [--nb_lignes]);

        // pour la première ligne traduite générer le champ Subject:
        strcpy (buf_lect, "Subject:");

        // et rajouter la traduction du sujet
        fgets (buf_lect + 8, sz_buflect, fmtrad);

        // répéter jusqu'en fin de fichier
        do
        {
            // mémoriser la ligne lue
            // on pourra éventuellement regrouper des lignes
            if (buf_lect [strlen (buf_lect) - 1] == '\n')
                genligne (buf_lect);
            else
                regroupeligne (buf_lect);
        }
        // et lire la ligne suivante
        while (fgets (buf_lect, sz_buflect, fmtrad));

        // on n'a plus besoin du fichier contenant la traduction
        fclose (fmtrad);

        // si numéro de ligne courant trop grand
        if (lignecour >= nb_lignes)
            // le corriger
            lignecour = nb_lignes - 1;

        // idem pour la position à l'écran
        if (lignecran > nb_lignes)
            lignecran = nb_lignes;

        return (1);
    }
    // sinon (pas de traduction effectué)
    else
        return (0);
}