package be.msyben.vinylManager.gui;

import be.msyben.vinylManager.controller.Controller;
import be.msyben.vinylManager.exceptions.VinylManagerException;
import be.msyben.vinylManager.gui.icon.Icons;
import be.msyben.vinylManager.properties.Language;
import be.msyben.vinylManager.properties.Preferences;
import be.msyben.vinylManager.tools.WaitThread;
import be.msyben.vinylManager.tools.filter.FileFilterCSV;
import be.msyben.vinylManager.tools.filter.FileFilterXLSX;
import be.msyben.vinylManager.tools.importexport.TableFormatExportField;
import be.msyben.vinylManager.tools.log.VinylManagerLogger;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

/**
 *
 * @author TCL459
 */
public class TableExportGui extends JFrame {

    /**
     * uid
     */
    private static final long serialVersionUID = 51603320945678L;
    /**
     * Le controller
     */
    private Controller controller;    
    /**
     * Le thread d'attente
     */
    private WaitThread waitThread = new WaitThread();
    
    /*private final ExportElem[] allFields = new ExportElem[]{
        new ExportElem("name.artiste"),
        new ExportElem("name.titre"),
        new ExportElem("name.compositeur.full"),
        new ExportElem("name.reference"),
        new ExportElem("name.editeur"),
        new ExportElem("name.annee"),
        new ExportElem("name.annee.parution"),
        new ExportElem("name.pays"),
        new ExportElem("name.chef"),
        new ExportElem("name.orchestre"),
        new ExportElem("name.musiciens"),
        new ExportElem("name.etat"),
        new ExportElem("name.commentaire"),
        new ExportElem("name.etoiles"),
        new ExportElem("name.genre"),
        new ExportElem("name.valeur"),
        new ExportElem("name.support"),
        new ExportElem("name.parolier"),
        new ExportElem("name.location"),
        new ExportElem("name.possede"),
        new ExportElem("name.date.achat"),
        new ExportElem("name.compilation"),
        new ExportElem("name.num.disque"),
        new ExportElem("name.etat.disque"),
        new ExportElem("name.taille"),
        new ExportElem("name.vitesse"),
        new ExportElem("name.couleur"),
        new ExportElem("name.canaux"),
        new ExportElem("name.face"),
        new ExportElem("name.numero.piste"),
        new ExportElem("name.piste"),
        new ExportElem("name.duree"),
        new ExportElem("name.piste.artiste"),
        new ExportElem("name.piste.annee")
    };*/
    
    
    /**
     * Constructeur
     *
     * @param controller le controller
     */
    public TableExportGui(Controller controller) {
        super(Language.getInstance().get("export.window.title"));
        this.controller = controller;
        setIconImage(Icons.getInstance().icon.getImage());
        MainWindow.getInstance().setEnabled(false);
        this.setSize(710, 520); //On donne une taille à notre fenêtre
        this.setLocationRelativeTo(null); //On centre la fenêtre sur l'ecran
        this.setResizable(false); //On interdit la redimensionnement de la fenêtre
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); //On dit à l'application de se fermer

        putElements();

        setVisible(true);
    }

    private void putElements() {
        Container c = this.getContentPane();
        c.setLayout(null);
        c.setSize(710, 520);
        
        DefaultListModel<TableFormatExportField> dlmGauche = new DefaultListModel<>();
        JList<TableFormatExportField> listG = new JList<>(dlmGauche);
        //listG.setCellRenderer(new Rendu());
        JScrollPane listGSP = new JScrollPane(listG);
        
        
        DefaultListModel<TableFormatExportField> dlmDroite = new DefaultListModel<>();
        JList<TableFormatExportField> listD = new JList<>(dlmDroite);   
        //listD.setCellRenderer(new Rendu());     
        JScrollPane listDSP = new JScrollPane(listD);
        
        
        List<String> selectedFields = Arrays.asList(Preferences.getInstance().get(Preferences.EXPORT_TABLE_FIELDS, "").split(";"));
        for (TableFormatExportField field : TableFormatExportField.values()) {
            if (!selectedFields.contains(field.name())) {
                dlmGauche.addElement(field);
            }
        }
        for (String selected : selectedFields) {
            for (TableFormatExportField field : TableFormatExportField.values()) {
                if (field.name().equals(selected)) {
                    dlmDroite.addElement(field);
                    break;
                }
            }
        }
        
        JLabel possibles = new JLabel("Champs possibles");
        possibles.setBounds(10, 10, 200, 20);
        c.add(possibles);
        
        JLabel selections = new JLabel("Champs sélectionnés");
        selections.setBounds(350, 10, 200, 20);
        c.add(selections);
        
        
        listGSP.setBounds(10, 40, 300, 370);
        c.add(listGSP);
        
        
        listDSP.setBounds(350, 40, 300, 370);
        c.add(listDSP);
        
        
        JButton moveRight = new JButton(Icons.getInstance().rightArrow);
        JButton moveLeft = new JButton(Icons.getInstance().leftArrow);
        moveRight.setBounds(317, 50,25, 25);
        moveLeft.setBounds(317, 100, 25, 25);
        c.add(moveRight);
        c.add(moveLeft);
        
        JButton up = new JButton(Icons.getInstance().up);
        JButton down = new JButton(Icons.getInstance().down);
        up.setBounds(660, 50,25, 25);
        down.setBounds(660, 100, 25, 25);
        c.add(up);
        c.add(down);
        
        listG.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
                    TableFormatExportField sel = listG.getSelectedValue();
                    if (sel != null) {
                        dlmGauche.removeElement(sel);
                        dlmDroite.addElement(sel);
                    }
                }
            }
        });        
        moveRight.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                TableFormatExportField sel = listG.getSelectedValue();
                if (sel != null) {
                    dlmGauche.removeElement(sel);
                    dlmDroite.addElement(sel);
                }
            }
        });
        
        
        
        
        listD.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
                    TableFormatExportField sel = listD.getSelectedValue();
                    if (sel != null) {
                        dlmDroite.removeElement(sel);
                        dlmGauche.addElement(sel);
                    }
                }
            }
        });   
        moveLeft.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                TableFormatExportField sel = listD.getSelectedValue();
                if (sel != null) {
                    dlmDroite.removeElement(sel);
                    dlmGauche.addElement(sel);
                }
            }
        });
        
        up.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                TableFormatExportField sel = listD.getSelectedValue();
                if (sel != null) {
                    int index = dlmDroite.indexOf(sel);
                    if (index > 0) {
                        index = index -1;
                    }
                    dlmDroite.removeElement(sel);
                    dlmDroite.add(index, sel);
                    listD.setSelectedIndex(index);
                }
            }
        });
        
        down.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                TableFormatExportField sel = listD.getSelectedValue();
                if (sel != null) {
                    int index = dlmDroite.indexOf(sel);
                    if (index < dlmDroite.getSize() -1) {
                        index = index +1;
                    }
                    dlmDroite.removeElement(sel);
                    dlmDroite.add(index, sel);
                    listD.setSelectedIndex(index);
                }
            }
        });
        
        JLabel format = new JLabel("Format : ");
        format.setBounds(10, 420, 80, 15);
        c.add(format);
        
        //JRadioButton choix = new JRadioButton
        CheckboxGroup groupe = new CheckboxGroup();
        Checkbox box1 = new Checkbox("CSV", groupe, true);
        Checkbox box2 = new Checkbox("Excel", groupe, true);
        
        box1.setBounds(90, 420, 50, 15);
        box2.setBounds(150, 420, 50, 15);
        
        c.add(box1);
        c.add(box2);
        
        JButton exporter = new JButton("Exporter");
        exporter.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                
                String pref = "";
                List<TableFormatExportField> fields = new ArrayList<>();
                for (int i = 0; i < dlmDroite.getSize(); i++) {
                    if (!pref.isEmpty()) {
                        pref += ";";
                    }
                    TableFormatExportField elem = dlmDroite.get(i); 
                    String key = elem.name();
                    pref += key;
                    fields.add(elem);
                }
                Preferences.getInstance().set(Preferences.EXPORT_TABLE_FIELDS, pref);
                
                choixFichierExport(fields, box1.getState() );
                
            }
        });
        exporter.setBounds(90, 445, 100, 25);
        c.add(exporter);
        
        JButton cancel = new JButton(Language.getInstance().get("button.annuler"));
        cancel.setBounds(210, 445, 100, 25);
        c.add(cancel);
        cancel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                dispose();
                MainWindow.getInstance().setEnabled(true);
            }
        });
        
    }
    
    /**
     * choix du fichier pour l'export xml
     */
    private void choixFichierExport(List<TableFormatExportField> fields, boolean csv) {

        try {
            setEnabled(false);
            JFileChooser fc = new JFileChooser(Preferences.getInstance().get(Preferences.PATH_EXPORT, System.getProperty("user.home")));
            fc.setDialogTitle(Language.getInstance().get("export.dialog.title"));
            fc.setMultiSelectionEnabled(false);
            fc.setAcceptAllFileFilterUsed(false);
            
                if (csv) {
                    fc.setFileFilter(new FileFilterCSV());
                } else {
                    fc.setFileFilter(new FileFilterXLSX());
                }
            int res = fc.showSaveDialog(this);
            setEnabled(true);
            if (res == JFileChooser.APPROVE_OPTION) {
                File f = fc.getSelectedFile();
                Preferences.getInstance().set(Preferences.PATH_EXPORT, f.getParentFile().getAbsolutePath());
                String extension;
                if (csv) {
                    extension = ".csv";
                } else {
                    extension = ".xlsx";
                }
                if (!f.getAbsolutePath().toLowerCase().endsWith(extension)) {
                    f = new File(f.getAbsolutePath() + extension);
                }

                if (f.exists()) {
                    int result = JOptionPane.showConfirmDialog(this, Language.getInstance().get("export.overwrite.dialog").replace("%1", f.getName()), Language.getInstance().get("export.overwrite.title"), JOptionPane.YES_NO_OPTION);

                    switch (result) {
                        case JOptionPane.YES_OPTION:
                            exporter(f, fields, csv);
                            break;

                        case JOptionPane.NO_OPTION:
                            break;
                    }

                } else {
                    exporter(f, fields, csv);
                }

            }

        } catch (Exception e) {
            VinylManagerLogger.log( e);
            new ErrorWindow(this, Language.getInstance().get("error.export.message"), e);
        }

    }
    
    private void exporter(final File f, List<TableFormatExportField> fields, boolean csv) {
        preImport();
        new Thread() {
            @Override
            public void run() {
                try {
                    controller.exportTable(f, fields, csv);
                } catch (VinylManagerException ex) {
                    VinylManagerLogger.log(ex);
                    setException(ex);
                }
                postImport();

            }
        }.start();

    }
     /**
     * L'exception possible lancée depuis un autre thread
     */
    private VinylManagerException exception = null;

    /**
     * Set de l'exception
     *
     * @param exception l'exception
     */
    public void setException(VinylManagerException exception) {
        this.exception = exception;
    }

    /**
     * Traitement à effectuer avant un import
     */
    private void preImport() {
        waitThread.start();
        /*ok.setEnabled(false);
        cancel.setEnabled(false);
        box1.setEnabled(false);
        box2.setEnabled(false);
        box3.setEnabled(false);
        box4.setEnabled(false);
        box5.setEnabled(false);
        box6.setEnabled(false);*/
        setException(null);
    }

    /**
     * Traitement à effectuer après un import
     */
    private void postImport() {
        /*ok.setEnabled(true);
        cancel.setEnabled(true);
        box1.setEnabled(true);
        box2.setEnabled(true);
        box3.setEnabled(true);
        box4.setEnabled(true);
        box5.setEnabled(true);
        box6.setEnabled(true);*/
        waitThread.arrete();
        if (exception == null) {
            dispose();
            MainWindow.getInstance().setEnabled(true);
        } else {
            new ErrorWindow(this, Language.getInstance().get("error.export.message"), exception);
        }

    }
    
}
