package be.msyben.vinylManager.gui;

import be.msyben.vinylManager.exceptions.VinylManagerException;
import be.msyben.vinylManager.gui.icon.Icons;
import be.msyben.vinylManager.interfaces.WaitListener;
import be.msyben.vinylManager.properties.Language;
import be.msyben.vinylManager.tools.Tools;
import be.msyben.vinylManager.tools.WaitThread;
import be.msyben.vinylManager.tools.internalEntities.ImageUrl;
import be.msyben.vinylManager.tools.lastfm.LastFmInterface;
import be.msyben.vinylManager.tools.log.VinylManagerLogger;
import be.msyben.vinylManager.tools.swing.NullLayout;
import java.awt.Color;
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.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.LineBorder;

/**
 * GUI permettant d'afficher les résultat de la recherche d'image pour en
 * introduire une dans l'interface.
 *
 * @author Mathieu Syben
 */
public final class SearchImageWindow extends JFrame {

    /**
     * uid
     */
    private static final long serialVersionUID = 73273446243l;

    /*
     * La fenêtre de l'album.
     */
    private AlbumWindow albumWindow;
    /**
     * Le thread d'attente
     */
    private WaitThread waitThread = new WaitThread();
    /**
     * Le ts du dernier clic sur un résultat.
     */
    private long lastClick = 0L;
    /**
     * La dernière sélection
     */
    private int lastSelection = -1;
    /**
     * Le scrollPanel avec les images.
     */
    private JScrollPane scrollPane;
    /**
     * La liste des images.
     */
    private List<ImageUrl> images = new ArrayList<ImageUrl>();
    /**
     * Le bouton valider
     */
    private JButton valider = new JButton(Language.getInstance().get("button.valider"));
    /**
     * L'artiste
     */
    private String artiste;
    /**
     * L'album
     */
    private String album;

    /**
     * Constructeur privé.
     */
    private SearchImageWindow() {
    }

    /**
     * Constructeur.
     *
     * @param albumWindow la fenêtre appelante.
     * @param artiste l'artiste
     * @param album l'album.
     */
    public SearchImageWindow(AlbumWindow albumWindowP, String artiste, String album) {
        super(Language.getInstance().get("search.image.title"));
        this.albumWindow = albumWindowP;
        this.artiste = artiste;
        this.album = album;

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

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

        waitThread.addWaitListener(new WaitListener() {
            @Override
            public void onCancel() {
                waitThread.arrete();
                close();
            }
        });
    }

    /**
     * Affiche
     */
    public void display() {
        if (albumWindow != null) {
            albumWindow.setEnabled(false);
        }
        waitThread.start();
        new Thread() {
            @Override
            public void run() {
                try {
                    if (waitThread.isRunning()) {
                        images = LastFmInterface.getImages(album, artiste);
                    }
                    if (waitThread.isRunning()) {
                        putElements();
                    }

                    if (waitThread.isRunning()) {
                        JPanel panel = new JPanel(new NullLayout(210 * images.size(), 210));
                        int i = 0;
                        final List<JLabel> labels = new ArrayList<JLabel>(images.size());
                        for (ImageUrl img : images) {
                            final JLabel ilml = new JLabel();
                            try {
                                ilml.setIcon(new ImageIcon(Tools.getReducedImage(img.getContenu())));
                                ilml.setHorizontalAlignment(JLabel.CENTER);
                                labels.add(ilml);
                                ilml.setSize(210, 210);
                                ilml.setBounds(i * 210, 0, 210, 210);
                                ilml.setBorder(new LineBorder(Color.black));
                                panel.add(ilml);
                                final int idx = i;

                                ilml.addMouseListener(new MouseAdapter() {
                                    @Override
                                    public void mouseClicked(MouseEvent e) {

                                        valider.setEnabled(true);

                                        long now = System.currentTimeMillis();
                                        int selection = idx;
                                        for (int j = 0; j < labels.size(); j++) {
                                            if (j == idx) {
                                                labels.get(j).setOpaque(true);
                                                labels.get(j).setBackground(Color.blue);
                                            } else {
                                                labels.get(j).setOpaque(false);
                                                labels.get(j).setBackground(null);
                                            }
                                        }
                                        if (selection == lastSelection && (now - lastClick < 500L)) {
                                            selection();
                                        }
                                        lastClick = now;
                                        lastSelection = selection;
                                    }
                                });
                            } catch (VinylManagerException ex) {
                                VinylManagerLogger.log(ex);
                            } finally {
                                i++;
                            }
                        }
                        scrollPane.setViewportView(panel);
                        if (images.size() > 2) {
                            scrollPane.setBounds(5, 15, 490, 230);
                        } else {
                            scrollPane.setBounds(5, 15, 490, 215);
                        }
                    }
                    if (waitThread.isRunning()) {
                        setVisible(true);
                        waitThread.arrete();
                    }

                } catch (VinylManagerException ex) {
                    VinylManagerLogger.log(ex);
                    if (waitThread.isRunning()) {
                        waitThread.arrete();
                        new ErrorWindow(albumWindow, Language.getInstance().get("search.image.error"), ex);
                        dispose();
                    }
                }
            }
        }.start();
    }

    /**
     * Construit la fenêtre et place les éléments.
     *
     * @param artiste le nom de l'artiste
     * @param album le nom de l'album
     */
    private void putElements() {
        JButton fermer = new JButton(Language.getInstance().get("button.fermer"));

        Container c = this.getContentPane();
        c.setLayout(null);
        c.setSize(500, 320);

        scrollPane = new JScrollPane();
        if (images.size() > 2) {
            scrollPane.setBounds(5, 15, 490, 230);
        } else {
            scrollPane.setBounds(5, 15, 490, 215);
        }


        valider.setBounds(100, 245, 100, 25);
        fermer.setBounds(300, 245, 100, 25);
        valider.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                selection();
            }
        });

        fermer.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                close();
            }
        });

        c.add(scrollPane);
        c.add(valider);
        valider.setEnabled(false);
        c.add(fermer);
        this.toFront();
    }

    /**
     * Sélection d'une image.
     */
    public void selection() {
        if (albumWindow != null) {
            if (lastSelection >= 0) {
                albumWindow.setImage(images.get(lastSelection));
            }
        }
        close();
    }

    /**
     * Ferme la fenêtre et rend la main à l'appelant.
     */
    private void close() {
        dispose();
        if (albumWindow != null) {
            albumWindow.setEnabled(true);
            albumWindow.toFront();
        }
    }
}
