package de.duehl.swing.ui.selector;

/*
 * Copyright 2016 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

import de.duehl.swing.ui.GuiTools;
import de.duehl.swing.ui.buttons.JobButton;

/**
 * Diese Klasse stellt eine kleine Oberfläche zum Starten von unterschiedlichen
 * Programmen dar.
 *
 * @version 1.01     2015-11-10
 * @author Christian Dühl
 */

public class Selector {

    /** Lokation des Selectors auf dem Bildschirm. */
    private static final Point LOCATION = new Point(100, 75);

    /** Frame auf dem die Oberfläche dargestellt wird. */
    private final JFrame frame;

    /** Anzahl der nebeneinander angezeigten Job-Button im Grid. */
    private final int gridWidth;

    /** Icon für das Programm. */
    private final Image programImage;

    /**
     * Konstruktor.
     *
     * @param gridWidth
     *            Anzahl der nebeneinander angezeigten Job-Button im Grid.
     */
    public Selector(final int gridWidth) {
        this(gridWidth, null);
    }

    /**
     * Konstruktor.
     *
     * @param gridWidth
     *            Anzahl der nebeneinander angezeigten Job-Button im Grid.
     * @param programImage
     *            Icon für das Programm.
     */
    public Selector(final int gridWidth, final Image programImage) {
        this.gridWidth = gridWidth;
        this.programImage = programImage;

        GuiTools.setNiceLayoutManager();
        frame = new JFrame();
    }

    /**
     * Baut die Gui auf.
     *
     * @param startPoints
     *            Liste mit den zu startenden Anwendungen.
     */
    public void createGui(final List<StartPoint> startPoints) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createGuiInternal(startPoints);
            }
        });
    }

    /**
     * Baut die Gui im EDT auf.
     *
     * @param startPoints
     *            Liste mit den zu startenden Anwendungen.
     */
    private void createGuiInternal(final List<StartPoint> startPoints) {
        //GuiTools.setNiceLayoutManager();

        frame.setLayout(new BorderLayout());
        frame.setTitle("Welches Programm möchten Sie starten?");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        if (null != programImage) {
            frame.setIconImage(programImage);
        }

        JPanel panel = new JPanel();
        frame.add(panel, BorderLayout.CENTER);
        panel.setLayout(new GridLayout(0, gridWidth, 10, 10));
        panel.setBorder(new EmptyBorder(20, 20, 20, 20));

        for (StartPoint startPoint : startPoints) {
            panel.add(createStartButton(startPoint));
        }

        frame.setLocation(LOCATION);
        frame.pack();
    }

    /**
     * Erzeugt einen Schalter zum starten der Anwendung.
     *
     * @param startPoint
     *            Informationen zur Anwendung.
     * @return Erzeugte Komponente.
     */
    private Component createStartButton(final StartPoint startPoint) {
        JButton button = createButton(startPoint.getDescription());
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                close();
                new Thread(startPoint.getRunnable()).start();
            }
        });
        return button;
    }

    /** Schließt diese Oberfläche. */
    private void close() {
        frame.setVisible(false);
        frame.dispose();
    }

    /** Erzeugt einen Button mit zentriertem HTML. */
    private JButton createButton(final String message) {
        return new JobButton("<html><center>" + message + "</center></html>");
    }

    /**
     * Zeigt den Frame oder versteckt ihn.
     *
     * @param visible
     *            true: wird gezeigt.
     */
    public void setVisible(final boolean visible) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                frame.setVisible(visible);
            }
        });
    }

    /** Gibt die Position des Selectors zurück. */
    public Point getLocation() {
        return LOCATION;
    }

}
