package be.msyben.vinylManager.gui;

import be.msyben.vinylManager.controller.Controller;
import be.msyben.vinylManager.data.Data;
import be.msyben.vinylManager.entities.Album;
import be.msyben.vinylManager.entities.Disque;
import be.msyben.vinylManager.entities.Titre;
import be.msyben.vinylManager.exceptions.VinylManagerException;
import be.msyben.vinylManager.gui.icon.Icons;
import be.msyben.vinylManager.properties.*;
import be.msyben.vinylManager.tools.Tools;
import be.msyben.vinylManager.tools.log.VinylManagerLogger;
import be.msyben.vinylManager.tools.swing.Line;
import be.msyben.vinylManager.tools.swing.MyJComboBox;
import be.msyben.vinylManager.tools.swing.MyJList;
import be.msyben.vinylManager.tools.swing.SuggestionComboBox2;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

/**
 * fenêtre pour afficher un disque.
 *
 * @author Mathieu Syben
 */
public class DisqueWindow extends JFrame implements ActionListener {

    /**
     * uid
     */
    private static final long serialVersionUID = 6l;
    /**
     * Bouton pour ajouter à la face 1
     */
    private JButton addFace1 = new JButton(Icons.getInstance().fleche);
    /**
     * Bouton pour ajouter à la face 2
     */
    private JButton addFace2 = new JButton(Icons.getInstance().fleche);
    /**
     * Bouton pour vider face 1
     */
    private JButton emptyFace1 = new JButton(Icons.getInstance().poubelle);
    /**
     * Bouton pour vider face 2
     */
    private JButton emptyFace2 = new JButton(Icons.getInstance().poubelle);
    /**
     * Bouton pour rechercher les titres.
     */
    private JButton searchTitles = new JButton(Language.getInstance().get("button.rechercher.pistes"), Icons.getInstance().loupe);
    /**
     * Champs de texte contenant le numéro
     */
    private JTextField num = new JTextField();
    /**
     * Champs de texte contenant le nom
     */
    private JTextField nom = new JTextField();
    /**
     * Champs de texte contenant l'année du titre
     */
    private JTextField annee = new JTextField();
    /**
     * Champs de texte contenant l'artiste (si compilation)
     */
    private JTextField artiste = new JTextField();
    /**
     * la durée
     */
    private JTextField duree = new JTextField();
    /**
     * bouton ok
     */
    private JButton ok = new JButton(Language.getInstance().get("button.valider"));
    /**
     * bouton cancel
     */
    private JButton cancel = new JButton(Language.getInstance().get("button.annuler"));
    /**
     * La liste des titres de la face A
     */
    private JList<Titre> faceA = new MyJList<>();
    private JScrollPane faceAPane = new JScrollPane(faceA);
    /**
     * La liste des titres de la face B
     */
    private JList<Titre> faceB = new MyJList<>();
    private JScrollPane faceBPane = new JScrollPane(faceB);
    /**
     * Le JComboBox contenant l'état
     */
    private JComboBox<Cotation> etat = new MyJComboBox<>();
    private JComboBox<Taille> taille = new MyJComboBox<>();
    private JComboBox<Vitesse> vitesse = new MyJComboBox<>();
    private JComboBox<Canaux> canaux = new MyJComboBox<>();
    private JTextField tailleF = new JTextField();
    private JTextField vitesseF = new JTextField();
    private SuggestionComboBox2 couleur;
    /**
     * Le disque
     */
    private Disque disque = null;
    /**
     * L'album
     */
    private Album album;
    /**
     * Le controller
     */
    private Controller controller;
    private ArrayList<Line> lines = new ArrayList<Line>();
    private Titre selectedTitre = null;

    /**
     * Creates a new instance of DisqueWindow
     */
    public DisqueWindow(Controller controller, Album album) {
        super(Language.getInstance().get("disc.window.new.title"));
        MainWindow.getInstance().setEnabled(false);
        this.controller = controller;
        this.album = album;
        setIconImage(Icons.getInstance().icon.getImage());

        this.setSize(535, 610); // 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();

        if (album.getSupport() == Support.schellack.getId()) {
            vitesse.setSelectedItem(Vitesse.vitesse78);
        }

        setVisible(true);
        repaint();
        nom.grabFocus();
    }

    /**
     * Creates a new instance of DisqueWindow
     *
     * @param disque le disque a éditer
     */
    public DisqueWindow(Controller controller, Disque disque, Album album) {
        super(Language.getInstance().get("disc.window.edit.title"));
        MainWindow.getInstance().setEnabled(false);
        this.controller = controller;
        this.album = album;
        this.disque = disque;

        setIconImage(Icons.getInstance().icon.getImage());


        try {
            Titre[] faceATitres = new Titre[disque.getFaceA().size()];
            for (int i = 0; i < faceATitres.length; i++) {
                faceATitres[i] = disque.getFaceA().get(i).clone();
            }
            faceA.setListData(faceATitres);

            Titre[] faceBTitres = new Titre[disque.getFaceB().size()];
            for (int i = 0; i < faceBTitres.length; i++) {
                faceBTitres[i] = disque.getFaceB().get(i).clone();
            }
            faceB.setListData(faceBTitres);
        } catch (CloneNotSupportedException ex) {
            VinylManagerLogger.log(ex);
        }

        this.setSize(535, 610); // 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();

        boolean etatset = false;
        for (Cotation c : Cotation.cotations) {
            if (c.equals(disque.getEtat())) {
                etat.setSelectedItem(c);
                etatset = true;
                break;
            }
        }
        if (!etatset) {
            etat.setSelectedItem(Cotation.vide);
        }

        if (album.getSupport() == Support.schellack.getId() && disque.getVitesse() == null) {
            disque.setVitesse(Vitesse.vitesse78.getId());
        }
        vitesse.setSelectedItem(Vitesse.getVitesse(disque.getVitesse()));
        taille.setSelectedItem(Taille.getTaille(disque.getTaille()));
        canaux.setSelectedItem(Canaux.getCanaux(disque.getCanaux()));
        couleur.setText(disque.getCouleur());



        setVisible(true);
        nom.grabFocus();
    }

    /**
     * Ajoute les éléments dans la fenêtre
     */
    private void putElements() {
        JLabel numL = new JLabel(Language.getInstance().get("name.numero.piste"));
        JLabel nomL = new JLabel(Language.getInstance().get("name.titre"));
        JLabel anneeL = new JLabel(Language.getInstance().get("name.annee"));
        JLabel artisteL = new JLabel(Language.getInstance().get("name.artiste"));
        JLabel dureeL = new JLabel(Language.getInstance().get("name.duree"));
        JLabel faceAL = new JLabel(Language.getInstance().get("name.faceA"));
        JLabel faceBL = new JLabel(Language.getInstance().get("name.faceB"));
        JLabel etatL = new JLabel(Language.getInstance().get("name.etat"));
        JLabel vitesseL = new JLabel(Language.getInstance().get("name.vitesse"));
        JLabel tailleL = new JLabel(Language.getInstance().get("name.taille"));
        JLabel canauxL = new JLabel(Language.getInstance().get("name.canaux"));
        JLabel couleurL = new JLabel(Language.getInstance().get("name.couleur"));
        Container c = this.getContentPane();
        c.setLayout(null);
        c.setSize(535, 580);

        tailleL.setBounds(5, 15, 120, 15);
        c.add(tailleL);
        for (Taille t : Taille.values()) {
            taille.addItem(t);
        }
        taille.setBounds(125, 10, 120, 25);
        tailleF.setBounds(125, 10, 120, 25);

        vitesseL.setBounds(280, 15, 120, 15);
        c.add(vitesseL);
        for (Vitesse v : Vitesse.values()) {
            vitesse.addItem(v);
        }
        vitesse.setBounds(340, 10, 120, 25);
        vitesseF.setBounds(340, 10, 120, 25);


        etatL.setBounds(5, 45, 120, 15);
        c.add(etatL);
        for (Cotation cot : Cotation.cotations) {
            etat.addItem(cot);
        }
        etat.setBounds(125, 40, 120, 25);
        c.add(etat);

        Set<String> allColors = new HashSet<>();
        for (Album alb : Data.getInstance().getCollection().getAlbums()) {
            for (Disque d : alb.getDisques()) {
                if (d.getCouleur() != null && !d.getCouleur().isEmpty()) {
                    allColors.add(d.getCouleur());
                }
            }
        }
        couleur = new SuggestionComboBox2(new ArrayList<>(allColors));
        
        couleurL.setBounds(280, 45, 120, 15);
        c.add(couleurL);
        couleur.setBounds(340, 40, 120, 25);
        couleur.setSize(120, 25, 150);
        c.add(couleur);

        canauxL.setBounds(5, 75, 120, 15);
        c.add(canauxL);
        for (Canaux can : Canaux.values()) {
            canaux.addItem(can);
        }
        canaux.setBounds(125, 70, 120, 25);
        c.add(canaux);



        PopupMenuListener popupListener = new PopupMenuListener() {
            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
            }

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                repaint();
            }

            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {
            }
        };

        etat.addPopupMenuListener(popupListener);
        taille.addPopupMenuListener(popupListener);
        vitesse.addPopupMenuListener(popupListener);
        canaux.addPopupMenuListener(popupListener);

        searchTitles.setBounds(125, 100, 220, 25);
        searchTitles.addActionListener(this);
        searchTitles.setToolTipText(Language.getInstance().get("window.search.tooltip"));
        c.add(searchTitles);

        addLine(3, 2, 505, 2);
        addLine(3, 2, 3, 135);
        addLine(3, 135, 505, 135);
        addLine(505, 2, 505, 135);

        numL.setBounds(5, 150, 120, 15);
        c.add(numL);
        num.setBounds(125, 145, 50, 25);
        num.setToolTipText(Language.getInstance().get("window.disc.num.tooltip"));
        c.add(num);

        nomL.setBounds(225, 150, 60, 15);
        c.add(nomL);
        nom.setBounds(280, 145, 220, 25);
        c.add(nom);

        artisteL.setBounds(225, 180, 60, 15);
        c.add(artisteL);
        artiste.setBounds(280, 175, 220, 25);
        c.add(artiste);

        artiste.setEditable(album.getCompliation());
        artiste.setEnabled(album.getCompliation());
        if (!album.getCompliation()) {
            artiste.setToolTipText(Language.getInstance().get("window.disc.artist.tooltip"));
        }

        anneeL.setBounds(5, 210, 60, 15);
        c.add(anneeL);
        annee.setBounds(125, 205, 50, 25);
        annee.setToolTipText(Language.getInstance().get("window.disc.annee.tooltip"));
        c.add(annee);

        dureeL.setBounds(225, 210, 120, 15);
        c.add(dureeL);
        duree.setBounds(280, 205, 50, 25);
        duree.setToolTipText(Language.getInstance().get("window.disc.duration.tooltip"));
        c.add(duree);

        addLine(3, 135, 3, 238);
        addLine(3, 238, 505, 238);
        addLine(505, 135, 505, 238);

        ListSelectionListener lsl = new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                Object source = e.getSource();
                if (source == faceA && !faceA.isSelectionEmpty()) {
                    faceB.clearSelection();
                    selectedTitre = (Titre) faceA.getSelectedValue();

                    nom.setText(selectedTitre.getNom());
                    num.setText(selectedTitre.getNum() + "");
                    duree.setText(getDureeString(selectedTitre.getDuree()));
                    annee.setText(selectedTitre.getAnnee());
                    artiste.setText(selectedTitre.getArtiste());
                }
                if (source == faceB && !faceB.isSelectionEmpty()) {
                    faceA.clearSelection();
                    selectedTitre = (Titre) faceB.getSelectedValue();

                    nom.setText(selectedTitre.getNom());
                    num.setText(selectedTitre.getNum() + "");
                    duree.setText(getDureeString(selectedTitre.getDuree()));
                    annee.setText(selectedTitre.getAnnee());
                    artiste.setText(selectedTitre.getArtiste());
                }

            }
        };

        faceAL.setBounds(5, 320, 50, 15);
        c.add(faceAL);
        faceAPane.setBounds(50, 315, 200, 200);
        c.add(faceAPane);
        faceAPane.setBorder(new LineBorder(Color.BLACK, 1));
        faceA.addListSelectionListener(lsl);
        faceA.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {

                if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
                    int index = faceA.locationToIndex(e.getPoint());
                    if (index >= 0) {
                        faceA.clearSelection();

                        remove(faceA, index);
                    }
                }
                if (SwingUtilities.isRightMouseButton(e)) {
                    int index = faceA.locationToIndex(e.getPoint());
                    if (index <= faceA.getModel().getSize()) {
                        final Titre t = (Titre) faceA.getModel().getElementAt(index);
                        faceA.setSelectedIndex(index);
                        final JPopupMenu popup = new JPopupMenu();
                        JMenuItem lyrics = new JMenuItem(Language.getInstance().get("search.lyrics.edit").replace("%1", t.getNom()));
                        lyrics.addActionListener(new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                new LyricsWindow(DisqueWindow.this, album, t);
                                popup.setVisible(false);
                            }
                        });
                        popup.add(lyrics);

                        if (t.getLinkedFilePath() != null) {
                            JMenuItem removeLinked = new JMenuItem(Language.getInstance().get("linked.file.del").replace("%1", t.getNom()));
                            removeLinked.addActionListener(new ActionListener() {
                                @Override
                                public void actionPerformed(ActionEvent e) {
                                    t.setLinkedFilePath(null);
                                }
                            });

                            JMenuItem openLinked = new JMenuItem(Language.getInstance().get("linked.file.open").replace("%1", t.getNom()));
                            openLinked.addActionListener(new ActionListener() {
                                @Override
                                public void actionPerformed(ActionEvent e) {
                                    try {
                                        Tools.openFile(t.getLinkedFilePath());
                                    } catch (VinylManagerException ex) {
                                        VinylManagerLogger.log(ex);
                                        new ErrorWindow(DisqueWindow.this, ex.getMessage(), ex);
                                    }
                                }
                            });
                            popup.add(openLinked);
                            popup.add(removeLinked);
                        } else {
                            JMenuItem addLinked = new JMenuItem(Language.getInstance().get("linked.file.add").replace("%1", t.getNom()));
                            addLinked.addActionListener(new ActionListener() {
                                @Override
                                public void actionPerformed(ActionEvent e) {
                                    addFileToTitre(t);
                                }
                            });
                            popup.add(addLinked);
                        }

                        popup.setVisible(true);
                        popup.show(e.getComponent(), e.getX(), e.getY());
                    }
                }
            }
        });


        emptyFace1.setBounds(15, 345, 32, 32);
        c.add(emptyFace1);
        emptyFace1.addActionListener(this);

        faceBL.setBounds(255, 320, 50, 15);
        c.add(faceBL);
        faceBPane.setBounds(300, 315, 200, 200);
        c.add(faceBPane);
        faceBPane.setBorder(new LineBorder(Color.BLACK, 1));
        faceB.addListSelectionListener(lsl);

        faceB.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
                    int index = faceB.locationToIndex(e.getPoint());
                    if (index >= 0) {
                        faceB.clearSelection();
                        remove(faceB, index);
                    }
                }
                if (SwingUtilities.isRightMouseButton(e)) {
                    int index = faceB.locationToIndex(e.getPoint());
                    if (index <= faceB.getModel().getSize()) {
                        final Titre t = (Titre) faceB.getModel().getElementAt(index);
                        faceB.setSelectedIndex(index);
                        final JPopupMenu popup = new JPopupMenu();

                        JMenuItem lyrics = new JMenuItem(Language.getInstance().get("search.lyrics.edit").replace("%1", t.getNom()));
                        lyrics.addActionListener(new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                new LyricsWindow(DisqueWindow.this, album, t);
                                popup.setVisible(false);
                            }
                        });
                        popup.add(lyrics);

                        if (t.getLinkedFilePath() != null) {
                            JMenuItem removeLinked = new JMenuItem(Language.getInstance().get("linked.file.del").replace("%1", t.getNom()));
                            removeLinked.addActionListener(new ActionListener() {
                                @Override
                                public void actionPerformed(ActionEvent e) {
                                    t.setLinkedFilePath(null);
                                }
                            });

                            JMenuItem openLinked = new JMenuItem(Language.getInstance().get("linked.file.open").replace("%1", t.getNom()));
                            openLinked.addActionListener(new ActionListener() {
                                @Override
                                public void actionPerformed(ActionEvent e) {
                                    try {
                                        Tools.openFile(t.getLinkedFilePath());
                                    } catch (VinylManagerException ex) {
                                        VinylManagerLogger.log(ex);
                                        new ErrorWindow(DisqueWindow.this, ex.getMessage(), ex);
                                    }
                                }
                            });
                            popup.add(openLinked);
                            popup.add(removeLinked);
                        } else {
                            JMenuItem addLinked = new JMenuItem(Language.getInstance().get("linked.file.add").replace("%1", t.getNom()));
                            addLinked.addActionListener(new ActionListener() {
                                @Override
                                public void actionPerformed(ActionEvent e) {
                                    addFileToTitre(t);
                                }
                            });
                            popup.add(addLinked);
                        }
                        popup.setVisible(true);
                        popup.show(e.getComponent(), e.getX(), e.getY());
                    }
                }
            }
        });
        emptyFace2.setBounds(265, 345, 32, 32);
        c.add(emptyFace2);
        emptyFace2.addActionListener(this);

        ok.setBounds(150, 525, 100, 25);
        ok.addActionListener(this);
        c.add(ok);

        cancel.setBounds(300, 525, 100, 25);
        cancel.addActionListener(this);
        c.add(cancel);

        addFace1.setBounds(125, 255, 50, 50);
        addFace1.addActionListener(this);
        addFace1.setToolTipText(Language.getInstance().get("button.add.face.1.tooltip"));
        c.add(addFace1);

        addFace2.setBounds(375, 255, 50, 50);
        addFace2.addActionListener(this);
        addFace2.setToolTipText(Language.getInstance().get("button.add.face.2.tooltip"));
        c.add(addFace2);



        KeyListener kl = new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getModifiersEx()== KeyEvent.CTRL_DOWN_MASK && e.getKeyCode() == KeyEvent.VK_ENTER) {
                    addFace2();
                }
                if (e.getModifiersEx() == 0 && e.getKeyCode() == KeyEvent.VK_ENTER) {
                    addFace1();
                }
            }
        };

        nom.addKeyListener(kl);
        num.addKeyListener(kl);
        duree.addKeyListener(kl);
        artiste.addKeyListener(kl);
        annee.addKeyListener(kl);

        Support support = Support.getSupport(album.getSupport());
        
        if (support == Support.vinyl) {
            c.add(taille);
            c.add(vitesse);
        } else if (support == Support.schellack) {
            c.add(tailleF);
            tailleF.setText(support.getName());
            tailleF.setEditable(false);
            c.add(vitesse);            
        } else {
            c.add(tailleF);
            tailleF.setText(support.getName());
            tailleF.setEditable(false);
            c.add(vitesseF);
            vitesseF.setText(support.getName());
            vitesseF.setEditable(false);
        }
    }

    private void addFileToTitre(Titre t) {

        setEnabled(false);
        JFileChooser fc = new JFileChooser(Preferences.getInstance().get(Preferences.PATH_TRACKFILE, System.getProperty("user.home")));
        fc.setDialogTitle(Language.getInstance().get("open.dialog.title"));
        fc.setMultiSelectionEnabled(false);
        fc.setAcceptAllFileFilterUsed(false);
        int res = fc.showOpenDialog(this);
        setEnabled(true);
        if (res == JFileChooser.APPROVE_OPTION) {
            File f = fc.getSelectedFile();
            if (f.exists()) {
                t.setLinkedFilePath(f.getAbsolutePath());
                Preferences.getInstance().set(Preferences.PATH_TRACKFILE, f.getParentFile().getAbsolutePath());
            } else {
                new ErrorWindow(this, Language.getInstance().get("error.file.not.exists").replace("%1", f.getAbsolutePath()));
            }
        }
        toFront();

    }

    /**
     * Appelé quand un action a été faite
     *
     * @param e l'action
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source == addFace1) {
            addFace1();
        }
        if (source == addFace2) {
            addFace2();
        }
        if (source == emptyFace1) {
            faceA.setListData(new Titre[]{});
            faceB.clearSelection();
            nom.grabFocus();
            selectedTitre = null;
        }
        if (source == emptyFace2) {
            faceB.setListData(new Titre[]{});
            faceA.clearSelection();
            nom.grabFocus();
            selectedTitre = null;
        }

        if (source == cancel) {
            this.dispose();
            MainWindow.getInstance().toFront();
            MainWindow.getInstance().setEnabled(true);
        }

        if (source == ok) {
            boolean insert = false;
            if (disque == null) {
                disque = new Disque();
                insert = true;
            }
            disque.setFaceA(getTitres(faceA));
            disque.setFaceB(getTitres(faceB));
            disque.setEtat(((Cotation) etat.getSelectedItem()).getValeur());
            disque.setCouleur(couleur.getText());

            Support support = Support.getSupport(album.getSupport());
            if (support == Support.vinyl) {
                disque.setTaille(((Taille) taille.getSelectedItem()).getId());
                disque.setVitesse(((Vitesse) vitesse.getSelectedItem()).getId());
            } else if (support == Support.schellack) {
                disque.setTaille(null);
                disque.setVitesse(((Vitesse) vitesse.getSelectedItem()).getId());
            } else {
                disque.setTaille(null);
                disque.setVitesse(null);
            }

            disque.setCanaux(((Canaux) canaux.getSelectedItem()).getId());

            if (insert) {
                controller.addDisque(album, disque);
            }
            if (!insert) {
                controller.editDisque(album, disque);
            }
            this.dispose();
            MainWindow.getInstance().toFront();
            MainWindow.getInstance().setEnabled(true);
        }
        if (source == searchTitles) {
            new SearchTracksWindow(this, album).display();
        }

    }

    /**
     * Met à jour les pistes avec la release.
     *
     * @param allFounds les faces trouvées.
     */
    public void setRelease(List<List<Titre>> allFounds) {
        if (allFounds.size() <= 2) {
            if (allFounds.size() > 0) {
                faceA.setListData(allFounds.get(0).toArray(new Titre[0]));
            }
            if (allFounds.size() > 1) {
                faceB.setListData(allFounds.get(1).toArray(new Titre[0]));
            }
        } else {
            if (JOptionPane.showConfirmDialog(this, Language.getInstance().get("search.track.multiple.disc"), Language.getInstance().get("search.track.multiple.disc.title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
                for (int i = 0; i < ((int)Math.ceil(allFounds.size() / 2.0)); i++) {
                    Disque d = new Disque();
                    d.setFaceA(allFounds.get(i*2));
                    d.setFaceB(allFounds.get(1+i*2));
                    d.setEtat(((Cotation) etat.getSelectedItem()).getValeur());
                    d.setCouleur(couleur.getText());
                    Support support = Support.getSupport(album.getSupport());
                    if (support == Support.vinyl) {
                        d.setTaille(((Taille) taille.getSelectedItem()).getId());
                        d.setVitesse(((Vitesse) vitesse.getSelectedItem()).getId());
                    } else if (support == Support.schellack) {
                        d.setTaille(null);
                        d.setVitesse(((Vitesse) vitesse.getSelectedItem()).getId());
                    } else {
                        d.setTaille(null);
                        d.setVitesse(null);
                    }
                    d.setCanaux(((Canaux) canaux.getSelectedItem()).getId());
                    controller.addDisque(album, d);
                }
                this.dispose();
                MainWindow.getInstance().toFront();
                MainWindow.getInstance().setEnabled(true);
            }
        }
    }

    /**
     * Ajoute un titre à la face A
     */
    private void addFace1() {
        List<Titre> faceATitres = getTitres(faceA);
        Titre t;
        if (selectedTitre != null) {
            try {
                t = selectedTitre.clone();
            } catch (CloneNotSupportedException ex) {
                t = new Titre();
            }
        } else {
            t = new Titre();
        }
        try {
            if (num.getText() == null || num.getText().trim().equals("")) {
                int numiter = 1;
                boolean encore = true;
                while (encore) {
                    encore = false;
                    for (Titre tt : faceATitres) {
                        if (tt.getNum() == numiter) {
                            encore = true;
                        }
                    }
                    if (encore) {
                        numiter++;
                    }
                }
                t.setNum(numiter);
            } else {
                try {
                    t.setNum(Integer.parseInt(num.getText()));
                    int idxToRemove = -1;
                    for (int i = 0; i < faceATitres.size(); i++) {
                        Titre tt = faceATitres.get(i);
                        if (tt.getNum() == t.getNum()) {
                            idxToRemove = i;
                            break;
                        }
                    }
                    if (idxToRemove >= 0) {
                        faceATitres.remove(idxToRemove);
                    }
                } catch (Exception ex) {
                    VinylManagerLogger.log(ex);
                    new ErrorWindow(this, Language.getInstance().get("error.disc.add.num.int"), ex);
                    return;
                }
            }

            try {
                t.setDuree(Tools.getDuree(duree.getText()));
            } catch (VinylManagerException ex) {
                VinylManagerLogger.log("error.disc.add.duree.int", ex);
                new ErrorWindow(this, Language.getInstance().get("error.disc.add.duree.int"), ex);
                return;
            }
            if (nom.getText() == null || nom.getText().trim().equals("")) {
                new ErrorWindow(this, Language.getInstance().get("error.disc.no.titre"));
                return;
            }
            t.setNom(nom.getText());
            t.setAnnee(annee.getText());

            if (album.getCompliation()) {
                t.setArtiste(artiste.getText());
            } else {
                t.setArtiste("");
            }
            faceATitres.add(t);
            faceATitres = sort(faceATitres);
            faceA.setListData(faceATitres.toArray(new Titre[0]));
            num.setText("");
            nom.setText("");
            artiste.setText("");
            duree.setText("");
            annee.setText("");
            faceA.clearSelection();
            faceB.clearSelection();
            nom.grabFocus();
            selectedTitre = null;
        } catch (Exception ex) {
            VinylManagerLogger.log(ex);
            new ErrorWindow(this, Language.getInstance().get("error.disc.add"), ex);
        }

    }

    /**
     * Ajoute un titre à la face B
     */
    private void addFace2() {
        List<Titre> faceBTitres = getTitres(faceB);
        Titre t;
        if (selectedTitre != null) {
            try {
                t = selectedTitre.clone();
            } catch (CloneNotSupportedException ex) {
                t = new Titre();
            }
        } else {
            t = new Titre();
        }
        try {
            if (num.getText() == null || num.getText().trim().equals("")) {
                int num = 1;
                boolean encore = true;
                while (encore) {
                    encore = false;
                    for (Titre tt : faceBTitres) {
                        if (tt.getNum() == num) {
                            encore = true;
                        }
                    }
                    if (encore) {
                        num++;
                    }
                }
                t.setNum(num);
            } else {
                try {
                    t.setNum(Integer.parseInt(num.getText()));
                    int idxToRemove = -1;
                    for (int i = 0; i < faceBTitres.size(); i++) {
                        Titre tt = faceBTitres.get(i);
                        if (tt.getNum() == t.getNum()) {
                            idxToRemove = i;
                            break;
                        }
                    }
                    if (idxToRemove >= 0) {
                        faceBTitres.remove(idxToRemove);
                    }
                } catch (Exception ex) {
                    VinylManagerLogger.log(ex);
                    new ErrorWindow(this, Language.getInstance().get("error.disc.add.num.int"), ex);
                    return;
                }
            }

            try {
                t.setDuree(Tools.getDuree(duree.getText()));
            } catch (VinylManagerException ex) {
                VinylManagerLogger.log("error.disc.add.duree.int", ex);
                new ErrorWindow(this, Language.getInstance().get("error.disc.add.duree.int"), ex);
                return;
            }
            if (nom.getText() == null || nom.getText().trim().equals("")) {
                new ErrorWindow(this, Language.getInstance().get("error.disc.no.titre"));
                return;
            }
            t.setNom(nom.getText());
            t.setAnnee(annee.getText());

            if (album.getCompliation()) {
                t.setArtiste(artiste.getText());
            } else {
                t.setArtiste("");
            }
            faceBTitres.add(t);
            faceBTitres = sort(faceBTitres);
            faceB.setListData(faceBTitres.toArray(new Titre[0]));
            num.setText("");
            nom.setText("");
            artiste.setText("");
            duree.setText("");
            annee.setText("");
            faceA.clearSelection();
            faceB.clearSelection();
            nom.grabFocus();
            selectedTitre = null;
        } catch (Exception ex) {
            VinylManagerLogger.log(ex);
            new ErrorWindow(this, Language.getInstance().get("error.disc.add"), ex);
        }
    }

    /**
     * Renvoie sous forme de String
     *
     * @return L'objet sous forme de String
     */
    private String getDureeString(int dureeInt) {
        if (dureeInt != 0) {
            int min = dureeInt / 60;
            int sec = dureeInt % 60;
            String secS = sec < 10 ? "0" + sec : "" + sec;
            return min + ":" + secS;
        } else {
            return "0";
        }
    }

    /**
     * Trie une liste de titre
     *
     * @param toSort la liste à trier
     * @return la liste triée
     */
    public List<Titre> sort(List<Titre> toSort) {
        if (toSort == null || toSort.size() <= 1) {
            return toSort;
        }
        List<Titre> l1 = new ArrayList<>();
        List<Titre> l2 = new ArrayList<>();
        int i = 0;
        while (i < toSort.size() / 2) {
            l1.add(toSort.get(i));
            i++;
        }
        while (i < toSort.size()) {
            l2.add(toSort.get(i));
            i++;
        }
        return merge(sort(l1), sort(l2));
    }

    /**
     * Merge 2 listes de titres
     *
     * @return la liste mergée
     * @param l2 la seconde liste
     * @param l1 la première liste
     */
    public List<Titre> merge(List<Titre> l1, List<Titre> l2) {
        int i = 0;
        int j = 0;
        List<Titre> ret = new ArrayList<>();
        while (i < l1.size() && j < l2.size()) {
            if (l1.get(i).getNum() < l2.get(j).getNum()) {
                ret.add(l1.get(i));
                i++;
            } else {
                ret.add(l2.get(j));
                j++;
            }
        }
        while (i < l1.size()) {
            ret.add(l1.get(i));
            i++;
        }
        while (j < l2.size()) {
            ret.add(l2.get(j));
            j++;
        }
        return ret;
    }

    private void addLine(int x1, int y1, int x2, int y2) {
        this.lines.add(new Line(x1, y1, x2, y2));
    }

    @Override
    public void paint(Graphics g) {
        super.paintComponents(g);
        Graphics2D g2 = (Graphics2D) getContentPane().getGraphics();
        for (Line r : lines) {
            g2.drawLine(r.getX1(), r.getY1(), r.getX2(), r.getY2());
        }
    }

    private void remove(JList<Titre> list, int index) {
        List<Titre> after = new ArrayList<>();
        for (int i = 0; i < list.getModel().getSize(); i++) {
            if (i != index) {
                after.add(list.getModel().getElementAt(i));
            }
        }
        list.setListData(after.toArray(new Titre[0]));
    }

    private List<Titre> getTitres(JList<Titre> list) {
        List<Titre> ret = new ArrayList<>();
        for (int i = 0; i < list.getModel().getSize(); i++) {
            ret.add(list.getModel().getElementAt(i));
        }
        return ret;
    }
}
