/*
Copyright 2012-2014 Samuel Gesche

This file is part of the Greek Reuse Toolkit.

The Greek Reuse Toolkit 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 3 of the License, or
(at your option) any later version.

The Greek Reuse Toolkit 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 the Greek Reuse Toolkit.  If not, see <http://www.gnu.org/licenses/>.
*/

package fr.cnrs.liris.drim.grt.proc.parsers;

import fr.cnrs.liris.drim.grt.modele.convertisseurs.ConvertisseurTexteUnicodeVersUnicode;
import fr.cnrs.liris.drim.grt.modele.convertisseurs.ConvertisseurUnicodeVersFormeNormale;
import fr.cnrs.liris.drim.grt.modele.convertisseurs.ConvertisseurUnicodeVersMinuscules;
import fr.cnrs.liris.drim.grt.modele.convertisseurs.ConvertisseurUnicodeVersBetaCode;
import fr.cnrs.liris.drim.grt.modele.convertisseurs.ConvertisseurUnicodeVersRienDuTout;
import fr.cnrs.liris.drim.grt.modele.convertisseurs.ConvertisseurBetaCodeVersUnicode;
import java.nio.charset.Charset;
import java.util.ArrayList;
import fr.cnrs.liris.drim.grt.modele.Terme;
import fr.cnrs.liris.drim.grt.modele.listes.Lemmatiseurs;
import org.apache.commons.lang.StringUtils;

/**
 *
 * @author sgesche
 */
public class Textes {
    public static byte[] format(String s) {
        return s.getBytes(Charset.forName("UTF-8"));
    }
    
    public static byte[] ligne(String s) {
        return format(s+"\n");
    }
    
    public static boolean estVideDeTermes(String s) {
        return (nettoiePonctuation(s).isEmpty() || nettoiePonctuation(s).equals(" "));
    }
    
    public static boolean estUnTermeValide(String terme) {
        String test = terme;
        // + acceptés (éclate les contractions)
        test = test.replaceAll("\\+", "");
        // - acceptés sauf en début et en fin de mot (mots composés)
        test = test.replaceAll(".\\-.", "");
        // ' acceptés en fin de mot (apostrophe)
        test = test.replaceAll(".'", "");
        // caractères grecs acceptés
        test = ConvertisseurUnicodeVersRienDuTout.conversion(test);
        
        /*if(!test.isEmpty()) {
            System.err.println("Test de validité : " + terme + " -> " + test);
        }*/
        return test.isEmpty();
    }
    
    public static Terme[] decoupeEnTermes(String s) {
        String[] mots = nettoiePonctuation(s).split(" ");
        
        ArrayList<Terme> resultat = new ArrayList<>();
        for(int i=0; i<mots.length; i++) {
            if(mots[i].endsWith(".")) {
                String mot = mots[i].replaceAll("\\.", "");
                if(!mot.isEmpty()) {
                    resultat.add(Terme.cree(mot));
                }
                resultat.add(Terme.cree("."));
            } else if(!mots[i].isEmpty()) {
                resultat.add(Terme.cree(mots[i]));
            }
        }
        Terme[] resultat0 = new Terme[resultat.size()];
        resultat.toArray(resultat0);
        return resultat0;
    }
    
    public static String testeEncodage(String s) {
        String s2 = unicodifie(betacodifie(s));
        int d = distanceEdition(s, s2);
        if(d>1) {
            return "["+d+"] {"+s+" -> "+s2+"}\n";
        } else {
            return "";
        }
    }
    
    public static String nettoieTerme(String expression) {
        // Enlève tous les signes de ponctuation sauf les fins de phrases et les apostrophes
        String s0 = nettoiePonctuation(expression);
        s0 = nettoieEncodageLettres(s0);
        // Enlève les fins de phrases
        s0 = StringUtils.replace(s0, "\\.", "");
        return s0;
    }
    
    public static String nettoieLatin(String expression) {
        String s0 = expression.replaceAll("[A-Za-z0-9]", "");
        return s0;
    }
    
    private static String nettoiePonctuation(String s) {
        // Remplace par des espaces tous les signes de ponctuation sauf 
        // les fins de phrases, les apostrophes et les tirets 
        // (mots composés ou passages à la ligne)
        
        String s0 = s;
        s0 = StringUtils.replace(s0, "\"", " ");
        s0 = StringUtils.replace(s0, "\t", " ");
        s0 = StringUtils.replace(s0, "(", " ");
        s0 = StringUtils.replace(s0, ")", " ");
        s0 = StringUtils.replace(s0, "(", " ");
        s0 = StringUtils.replace(s0, ")", " ");
        s0 = StringUtils.replace(s0, "&", " ");
        s0 = StringUtils.replace(s0, ",", " ");
        s0 = StringUtils.replace(s0, ";", "."); // point d'interrogation grec
        s0 = StringUtils.replace(s0, ":", " ");
        s0 = StringUtils.replace(s0, "[", " ");
        s0 = StringUtils.replace(s0, "]", " ");
        s0 = StringUtils.replace(s0, "[", " ");
        s0 = StringUtils.replace(s0, "]", " ");
        s0 = StringUtils.replace(s0, "*", " ");
        s0 = StringUtils.replace(s0, ">", " ");
        s0 = StringUtils.replace(s0, "<", " ");
        s0 = StringUtils.replace(s0, "#", " ");
        s0 = StringUtils.replace(s0, "=", " ");
        s0 = StringUtils.replace(s0, "_", " ");
        s0 = StringUtils.replace(s0, ".", " ");
        s0 = StringUtils.replace(s0, "*", " ");
        s0 = StringUtils.replace(s0, "⌊", " ");
        
        // caractères de ponctuation spéciaux
        s0 = StringUtils.replace(s0, ""+(char)37, " ");
        s0 = StringUtils.replace(s0, ""+(char)64, " ");
        s0 = StringUtils.replace(s0, ""+(char)12314, " ");
        s0 = StringUtils.replace(s0, ""+(char)12315, " ");
        s0 = StringUtils.replace(s0, ""+(char)65279, " "); // ﻿
        s0 = StringUtils.replace(s0, ""+(char)183, " ");
        s0 = StringUtils.replace(s0, ""+(char)903, " ");   // ·
        s0 = StringUtils.replace(s0, ""+(char)769, " ");
        s0 = StringUtils.replace(s0, ""+(char)803, " ");
        s0 = StringUtils.replace(s0, ""+(char)697, " "); // ʹ
        s0 = StringUtils.replace(s0, ""+(char)8869, ""); // ⊥
        s0 = StringUtils.replace(s0, ""+(char)9169, ""); // ⏑
        s0 = StringUtils.replace(s0, ""+(char)8224, ""); // †
        s0 = StringUtils.replace(s0, ""+(char)8211, "-"); // –
        s0 = StringUtils.replace(s0, ""+(char)65533, ""); // �
        s0 = StringUtils.replace(s0, "\\- ", "-"); // tirets de passage à la ligne a priori
        
        // contraction des espacts
        s0 = s0.replaceAll(" {1,}", " ");
        
        
        // Tirets : à conserver uniquement au milieu et à la fin des mots
        if(!s0.isEmpty()) {
            while(s0.charAt(0) == '-') {
                s0 = s0.substring(1);
                if(s0.isEmpty()) {
                    break;
                }
            }
        }
        
        // Apostrophes (ou guillemets) : à supprimer du début des mots
        /*while(s0.startsWith("'")) {
            s0 = s0.substring(1, s0.length());
        }*/
        // A la fin des mots, difficile de savoir si c'est un guillemet fermant ou un apostrophe...
        // Espace + apostrophe = guillemet, à supprimer
        //s0 = StringUtils.replace(s0, " '", "");
        
        // Heuristique : suppression des apostrophes finaux (donc ceux qui restent)
        s0 = StringUtils.replace(s0, "'", "");
        
        
        return s0.trim();
    }
    
    public static String nettoieEncodageLettres(String s) {
        return ConvertisseurTexteUnicodeVersUnicode.conversion(s, false);
    }
    
    public static String supprimeMajuscules(String s) {
        return ConvertisseurUnicodeVersMinuscules.conversion(s);
    }
    
    public static String normalise(String s) {
        return ConvertisseurUnicodeVersFormeNormale.conversion(nettoiePonctuation(nettoieEncodageLettres(s)));
    }
    
    
    public static String betacodifie(String s) {
        return ConvertisseurUnicodeVersBetaCode.conversion(s);
    }
    
    public static String unicodifie(String s) {
        return ConvertisseurBetaCodeVersUnicode.conversion(s);
    }
    
    public static int distanceEdition(String s, String t){
        int m=s.length();
        int n=t.length();
        int[][]d=new int[m+1][n+1];
        for(int i=0;i<=m;i++){
            d[i][0]=i;
        }
        for(int j=0;j<=n;j++){
            d[0][j]=j;
        }
        for(int j=1;j<=n;j++){
            for(int i=1;i<=m;i++){
                if(s.charAt(i-1)==t.charAt(j-1)){
                    d[i][j]=d[i-1][j-1];
                }
                else{
                    d[i][j]=min((d[i-1][j]+1),(d[i][j-1]+1),(d[i-1][j-1]+1));
                }
            }
        }
        return(d[m][n]);
    }
    
    private static int min(int a,int b,int c){
        return(Math.min(Math.min(a,b),c));
    }
    
    public static String echappeXML(String xmlNonEchappe) {
        String s0 = xmlNonEchappe;
        s0 = StringUtils.replace(s0, "&", "&amp;");
        s0 = StringUtils.replace(s0, "<", "&lt;");
        s0 = StringUtils.replace(s0, ">", "&gt;");
        s0 = StringUtils.replace(s0, "\"", "&quot;");
        return s0;
    }
    
    public static String desechappeXML(String xmlEchappe) {
        String s0 = xmlEchappe;
        s0 = StringUtils.replace(s0, "&quot;", "\"");
        s0 = StringUtils.replace(s0, "&gt;", ">");
        s0 = StringUtils.replace(s0, "&lt;", "<");
        s0 = StringUtils.replace(s0, "&amp;", "&");
        return s0;
    }
}