/*
Copyright 2005-2013 Samuel Gesche

This file is part of ArcEnCiel.

ArcEnCiel 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.

ArcEnCiel 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 ArcEnCiel.  If not, see <http://www.gnu.org/licenses/>.
*/

package ihm;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;

import javax.swing.border.Border;

import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.Toolkit;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import java.util.HashMap;
import java.util.Map;
import javax.swing.JOptionPane;

/**
 * Cette classe aux méthodes statiques est la feuille de style de l'application.
 * Aucun appel à des méthodes de paramétrage de l'IHM ne devrait être faite sans
 * appel à cette classe (du moins en ce qui concerne les paramétrages de couleur,
 * de police et de bordure).<br>
 *
 * @author Samuel GESCHE
 * @version 3.5.1
 * @since 3.0.1
 */
public class Charte {

    /**
     * Donne le numéro de version de l'application.
     * @return String le numéro de version en question
     * @since 3.5.2
     */
    public static String getVersion() {
        return "4.1";
    }

    static private String lastUser = "";
    static private Map langues;
    static private String langue;

    /**
     * Taille Standard de la police;
     */
    static private int TAILLE_POLICE = 13;
    static{
        if(Toolkit.getDefaultToolkit().getScreenSize().width<=800){
            TAILLE_POLICE = 11;
        } else if(Toolkit.getDefaultToolkit().getScreenSize().width<=1024){
            TAILLE_POLICE = 12;
        }
    }
    final static private Font policeNorm = new Font("Garamond", 0, TAILLE_POLICE);
    final static private Color couleurEcriture = Color.BLACK;
    final static private Color couleurSurlignage = Color.BLUE;
    final static private Color couleurFond = new Color(224, 224, 224);
    final static private Color couleurAutres = new Color(0, 0, 0);
    final static private Border bordure = BorderFactory.createBevelBorder(
            0, new Color(255, 255, 255), new Color(192, 192, 192),
            new Color(255, 255, 255), new Color(192, 192, 192));
    final static private ImageIcon image = new ImageIcon(
            Toolkit.getDefaultToolkit().createImage("dat/img/fond.jpg").
            getScaledInstance(Toolkit.getDefaultToolkit().getScreenSize().width,
                              Toolkit.getDefaultToolkit().getScreenSize().height,
                              Image.SCALE_SMOOTH));
    final static private ImageIcon imageBlanche = new ImageIcon(
            Toolkit.getDefaultToolkit().createImage("dat/img/blanc.jpg").
            getScaledInstance(Toolkit.getDefaultToolkit().getScreenSize().width,
                              Toolkit.getDefaultToolkit().getScreenSize().height,
                              Image.SCALE_SMOOTH));
    final static private ImageIcon filigrane = new ImageIcon(
            Toolkit.getDefaultToolkit().createImage("dat/img/filigrane.jpg").
            getScaledInstance(Toolkit.getDefaultToolkit().getScreenSize().width,
                              Toolkit.getDefaultToolkit().getScreenSize().height,
                              Image.SCALE_SMOOTH));
    final static private ImageIcon logo = new ImageIcon("dat/img/icone.gif");
    final static private ImageIcon son = new ImageIcon("dat/img/son.gif");

    /**
     * Le texte pour les boutons OK
     */
    static public String OK = "";
    /**
     * Le texte pour les boutons Annuler
     */
    static public String CANCEL = "";
    /**
     * Le texte pour les boutons Oui
     */
    static public String OUI = "";
    /**
     * Le texte pour les boutons Non
     */
    static public String NON = "";

    /*
     * Lecture des fichiers d'internationalisation au démarrage.
     * @since 3.5.1
     */
    static {
        langues = new HashMap();
        File f = new File("dat/lng");
        File[] fLangues = f.listFiles();
        for(int i=0; i<fLangues.length; i++){
            if(fLangues[i].getName().endsWith(".lng")){
                Map donnees = new HashMap();
                try {
                    BufferedReader lect = new BufferedReader(new FileReader(
                            fLangues[i]));
                    while (lect.ready()) {
                        String[] ligne = lect.readLine().trim().split("=");
                        donnees.put(ligne[0].trim(), ligne[1].trim());
                    }
                    langues.put(fLangues[i].getName().split("\\.")[0].trim(),
                                donnees);
                } catch (IOException ioe) { // fichier non lisible
                    ioe.printStackTrace();
                } catch (ArrayIndexOutOfBoundsException aioobe) { // entrée incorrecte (sans =)
                    aioobe.printStackTrace();
                }
            }
        }

        File fl = new File("arcenciel.ini");
        if(fl.exists()){
            String nomS = "";
            try {
                BufferedReader r = new BufferedReader(new FileReader(fl));
                String s = "";
                while (!s.startsWith("dernier utilisateur=")) {
                    s = r.readLine();
                }
                lastUser = s.split("=")[1].trim();
                while (!s.startsWith("langue=")) {
                    s = r.readLine();
                }
                setLangue(s.split("=")[1].trim());
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        } else {
            setLangue(""+langues.keySet().iterator().next());
        }
        // Ayé, fini !
    }


    /**
     * Formate le composant donné en paramètre. Le formatage définit la couleur
     * de police, la police, et enlève l'opacité et la bordure.
     * @param jc JComponent le composant à formater
     * @since 3.0.1
     */
    public static void formate(JComponent jc) {
        jc.setOpaque(false);
        jc.setBorder(null);
        jc.setForeground(couleurEcriture);
        jc.setFont(policeNorm);
    }

    /**
     * Effectue la même opération que formate(JComponent), mais en retournant
     * la composant formaté.<br>
     * Cette méthode permet d'éviter de créer un composant juste pour le
     * formater, avant de l'insérer dans un conteneur.<br><br>
     * <i>Exemple : </i><br><br>
     * getContentPane().add(Charte.format(new JLabel("texte"));<br><br>
     * au lieu de<br><br>
     * JLabel l = new JLabel("texte");<br>
     * Charte.formate(l);<br>
     * getContentPane().add(l);
     * @param jc JComponent le composant à formater
     * @return JComponent le même composant, formaté
     * @since 3.0.1
     */
    public static JComponent format(JComponent jc) {
        formate(jc);
        return jc;
    }

    /**
     * Renvoie la police standard de l'application. Les polices non standards
     * doivent être calculées en utilisant Font.deriveFont() sur celle-ci.
     * @return Font la police standard de l'application
     * @since 3.1
     */
    public static Font getFont() {
        return policeNorm;
    }

    /**
     * Renvoie la couleur de police standard de l'application.
     * @return Color la couleur de police standard de l'application
     * @since 3.1
     */
    public static Color getForeground() {
        return couleurEcriture;
    }

    /**
     * Renvoie la couleur de fond standard de l'application.<br>
     * Notez que les composants devraient tous être transparents, pour ne pas
     * cacher l'image de fond. Cependant, si cela n'était pas le cas, utiliser
     * cette couleur.
     * @return Color la couleur de police standard de l'application
     * @since 3.1
     */
    public static Color getBackground() {
        return couleurFond;
    }

    /**
     * Renvoie la couleur spéciale de l'application. Cette couleur est à
     * utiliser pour colorer des zones avec une autre couleur que celle de la
     * police ou celle de fond.
     * @return Color la couleur de police standard de l'application
     * @since 3.1
     */
    public static Color getMiscellaneous() {
        return couleurAutres;
    }

    /**
     * Renvoie la bordure standard de l'application.
     * @return Border la bordure standard de l'application
     * @since 3.1
     */
    public static Border getBorder() {
        return bordure;
    }

    /**
     * Renvoie l'image de fond de l'application. Cette image de fond doit
     * normalement rester toujours visible, les composants étant transparents.
     * @return ImageIcon l'image de fond de l'application
     * @since 3.1
     */
    public static ImageIcon getImage() {
        return image;
    }

    /**
     * Renvoie l'image de fond blanche de l'application. Cette image de fond est
     * utilisée pour prendre des captures d'écran sans tenir compte de l'image
     * de fond normale, qui pourrait rendre difficile l'exploitation de la
     * capture.
     * @return ImageIcon l'image de fond blanche de l'application
     * @since 3.4.1
     */
    public static ImageIcon getImageBlanche() {
        return imageBlanche;
    }

    /**
     * Renvoie l'image de fond en filigrane de l'application. Cette image est
     * atténuée, pour pouvoir voir mieux les composants.
     * @return ImageIcon l'image de fond en filigrane de l'application
     * @since 3.1.2
     */
    public static ImageIcon getFiligrane() {
        return filigrane;
    }

    /**
     * Renvoie le logo de l'application.
     * @return ImageIcon le logo de l'application
     * @since 3.2.3
     */
    public static ImageIcon getLogo() {
        return logo;
    }

    /**
     * Renvoie l'icône "jouer un son" de l'application.
     * @return ImageIcon l'icône "jouer un son" de l'application
     * @since 3.5.1
     */
    public static ImageIcon getIconeSon() {
        return son;
    }

    public final static String ANGE = "dat/img/_ange.gif";
    public final static String CHASSE = "dat/img/_chasse.gif";
    public final static String CHOC = "dat/img/_choc.gif";
    public final static String CLIN_D_OEIL = "dat/img/_cligne.gif";
    public final static String COLERE = "dat/img/_colere.gif";
    public final static String DODO = "dat/img/_dodo.gif";
    public final static String CONFUS = "dat/img/_euh.gif";
    public final static String DELIRE = "dat/img/_fou.gif";
    public final static String MALIN = "dat/img/_hehe.gif";
    public final static String MOQUEUR = "dat/img/_langue.gif";
    public final static String PEUR = "dat/img/_maman.gif";
    public final static String FAIM = "dat/img/_miam.gif";
    public final static String MITIGE = "dat/img/_mouais.gif";
    public final static String SADIQUE = "dat/img/_mouark.gif";
    public final static String EXTASIE = "dat/img/_mrgreen.gif";
    public final static String PLEUR = "dat/img/_ouin.gif";
    public final static String DEPRIME = "dat/img/_pfff1.gif";
    public final static String LAS = "dat/img/_pfff2.gif";
    public final static String EN_VEUT = "dat/img/_rambo.gif";
    public final static String NEUTRE = "dat/img/_rien.gif";
    public final static String RIRE = "dat/img/_rire.gif";
    public final static String YEUX_AU_CIEL = "dat/img/_roll.gif";
    public final static String SOURIANT = "dat/img/_sourire.gif";
    public final static String ETUDE = "dat/img/_study.gif";
    public final static String TRISTE = "dat/img/_triste.gif";
    public final static String CONTENT = "dat/img/_veryhappy.gif";

    /**
     * Renvoie une émoticone choisie parmi les noms disponible (Charte.XXX)
     * @param icone String le nom de l'émoticone à afficher
     * @return ImageIcon l'émoticone correspondante
     * @since 3.3.2
     */
    public static ImageIcon getSmiley(String icone) {
        return new ImageIcon(icone);
    }

    /**
     * Donne le message associé à la circonstance précisée.
     * @param id String l'identifiant du message
     * @return String le message correspondant
     * @since 3.5.1
     */
    public static String getMessage(String id){
        Object s = ((Map)(langues.get(langue))).get(id);
        //System.err.println(s);
        if(s == null){
            // Un message d'erreur non localisé... en langage des signes...
            JOptionPane.showMessageDialog(null, "°x°   "+id+"   °x°");
            s = "°x°   "+id+"   °x°";
        }
        return s.toString();
    }

    /**
     * Change la langue de l'interface.
     * @param lng String la langue à sélectionner
     * @since 3.5.1
     */
    public static void setLangue(String lng){
        langue = lng;
        initUI();
    }

    /**
     * Donne la langue de l'interface.
     * @return String la langue en question
     * @since 3.5.1
     */
    public static String getLangue(){
        return langue;
    }

    /**
     * Renvoie la liste des langues disponibles pour l'interface.
     * @return String[] les langues disponibles
     * @since 3.5.1
     */
    public static String[] getLangues(){
        String[] res = new String[langues.keySet().size()];
        langues.keySet().toArray(res);
        return res;
    }

    /**
     * Renvoie le nom du dernier utilisateur de l'application.
     * @return String le nom en question
     * @since 3.5.1
     */
    public static String getDernierUtilisateur(){
        return lastUser;
    }

    /**
     * Modifie le nom du dernier utilisateur de l'application.
     * @param nom String le nom du dernier utilisateur en question
     * @since 3.5.1
     */
    public static void setDernierUtilisateur(String nom){
        lastUser = nom;
    }

    /**
     * Renvoie une liste de messages, dans les différentes langues, pour
     * demander un changement de langue.
     * @return Map les messages en question, accessibles par langue
     * @since 3.5.1
     */
    public static Map getMessagesIncomprehension(){
        String[] listeLangues = getLangues();
        Map res = new HashMap();
        res.put(langue, ((Map)(langues.get(langue))).get("InitLng_OK").toString());
        for(int i=0; i<listeLangues.length; i++){
            if(!(listeLangues[i].equals(langue))){
                res.put(listeLangues[i], ((Map)(langues.get(listeLangues[i]))).
                               get("InitLng_KO").toString());
            }
        }
        return res;
    }

    /**
     * Sauvegarde les informations de personnalisation de l'application avant
     * arrêt.
     * @since 3.5.1
     */
    public static void saveIni(){
        try {
            File f = new File("arcenciel.ini");
            f.createNewFile();
            FileWriter fw = new FileWriter(f);
            fw.write("dernier utilisateur=" + lastUser + "\n");
            fw.write("langue=" + langue + "\n");
            fw.flush();
            fw.close();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /**
     * Initialise les paramètres généraux de l'IHM. Cette méthode doit être
     * appelée au démarrage de l'application, avant de créer le moindre
     * composant.
     * @since 3.0.1
     */
    public static void initUI() {
        OK = getMessage("Button_OK");
        CANCEL = getMessage("Button_Cancel");
        OUI = getMessage("Button_Yes");
        NON = getMessage("Button_No");

        ToolTipManager.sharedInstance().setDismissDelay(Integer.MAX_VALUE);
        UIManager.put("TabbedPane.selected", new Color(255, 255, 255, 0));
        UIManager.put("TabbedPane.tabsOpaque", Boolean.FALSE);
        UIManager.put("TabbedPane.contentOpaque", Boolean.FALSE);
        UIManager.put("OptionPane.yesButtonText", OUI);
        UIManager.put("OptionPane.noButtonText", NON);
        UIManager.put("OptionPane.okButtonText", OK);
        UIManager.put("OptionPane.cancelButtonText", CANCEL);
        UIManager.put("ProgressBar.cycleTime", new Integer(2000));

        UIManager.put("ToolTip.foreground", couleurEcriture);
        UIManager.put("OptionPane.foreground", couleurEcriture);
        UIManager.put("TextArea.foreground", couleurEcriture);
        UIManager.put("OptionPane.messageForeground", couleurEcriture);
        UIManager.put("Button.foreground", couleurEcriture);
        UIManager.put("TextPane.foreground", couleurEcriture);
        UIManager.put("Panel.foreground", couleurEcriture);
        UIManager.put("Label.foreground", couleurEcriture);
        UIManager.put("TextField.foreground", couleurEcriture);
        UIManager.put("ScrollBar.foreground", couleurEcriture);
        UIManager.put("ComboBox.foreground", couleurEcriture);
        UIManager.put("Table.foreground", couleurEcriture);
        UIManager.put("TableHeader.foreground", couleurEcriture);
        UIManager.put("TextPane.foreground", couleurEcriture);
        UIManager.put("List.foreground", couleurEcriture);
        UIManager.put("ComboBox.disabledForeground", couleurEcriture);
        UIManager.put("ComboBox.selectionForeground", couleurEcriture);
        UIManager.put("Label.disabledForeground", couleurEcriture);
        UIManager.put("List.selectionForeground", couleurEcriture);
        UIManager.put("OptionPane.messageForeground", couleurEcriture);
        UIManager.put("ProgressBar.selectionForeground", couleurEcriture);
        UIManager.put("Table.focusCellForeground", couleurEcriture);
        UIManager.put("Table.selectionForeground", couleurEcriture);
        UIManager.put("TextField.caretForeground", couleurEcriture);
        UIManager.put("TextField.inactiveForeground", couleurEcriture.darker());
        UIManager.put("TextField.selectionForeground", couleurEcriture);
        UIManager.put("TextPane.caretForeground", couleurEcriture);
        UIManager.put("TextPane.inactiveForeground", couleurEcriture.darker());
        UIManager.put("TextPane.selectionForeground", couleurEcriture);

        UIManager.put("ProgressBar.foreground", couleurFond.darker());

        UIManager.put("ToolTip.background", couleurFond);
        UIManager.put("OptionPane.background", couleurFond);
        UIManager.put("Button.background", couleurFond);
        UIManager.put("TextPane.background", couleurFond);
        UIManager.put("TextArea.background", couleurFond);
        UIManager.put("Panel.background", couleurFond);
        UIManager.put("Label.background", couleurFond);
        UIManager.put("TextField.background", couleurFond);
        UIManager.put("ScrollBar.background", couleurFond);
        UIManager.put("ComboBox.background", couleurFond);
        UIManager.put("Table.background", couleurFond);
        UIManager.put("TableHeader.background", couleurFond);
        UIManager.put("ProgressBar.background", couleurFond);
        UIManager.put("TextPane.background", couleurFond);
        UIManager.put("List.background", couleurFond);
        UIManager.put("Slider.background", couleurFond);
        UIManager.put("List.selectionBackground", couleurFond.darker());
        UIManager.put("ComboBox.selectionBackground", couleurFond.darker());
        UIManager.put("ProgressBar.selectionBackground", couleurFond.darker());
        UIManager.put("Table.selectionBackground", couleurFond.darker());
        UIManager.put("TextField.selectionBackground", couleurFond.darker());
        UIManager.put("TextArea.selectionBackground", couleurFond.darker());
        UIManager.put("Button.select", couleurFond.darker());
        UIManager.put("Table.focusCellBackground", couleurFond.darker());

        UIManager.put("ToolTip.font", policeNorm);
        UIManager.put("OptionPane.font", policeNorm);
        UIManager.put("OptionPane.messageFont", policeNorm);
        UIManager.put("OptionPane.buttonFont", policeNorm);
        UIManager.put("Button.font", policeNorm);
        UIManager.put("ComboBox.font", policeNorm);
        UIManager.put("Label.font", policeNorm);
        UIManager.put("TextField.font", policeNorm);
        UIManager.put("TextArea.font", policeNorm);
        UIManager.put("Table.font", policeNorm);
        UIManager.put("TableHeader.font", policeNorm);
        UIManager.put("ProgressBar.font", policeNorm);
        UIManager.put("List.font", policeNorm);

        UIManager.put("ToolTip.border", bordure);
        UIManager.put("Button.border", bordure);
        UIManager.put("TableHeader.cellBorder", bordure);
        UIManager.put("SplitPaneDivider.border", bordure);
        UIManager.put("ProgressBar.border", bordure);
        UIManager.put("TextField.border", bordure);
        UIManager.put("TextArea.border", bordure);
        UIManager.put("TextPane.border", bordure);
        UIManager.put("List.focusCellHighlightBorder",
                      BorderFactory.createEmptyBorder());
        UIManager.put("Table.focusCellHighlightBorder",
                      BorderFactory.createEmptyBorder());
        /*java.util.Hashtable h = UIManager.getLookAndFeelDefaults();
                 String[] s = new String[h.keySet().size()];
                 h.keySet().toArray(s);
                 java.util.Arrays.sort(s);
                 for(int i=0; i<s.length; i++){
            if(s[i].startsWith("TabbedPane")){
                System.out.println(s[i] + " = " + h.get(s[i]));
            }
                 }*/
    }

}
