/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.ctecinf.swing;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

/**
 *
 * @author Cássio Conceição
 * @param <T>
 * @since 19/09/2018
 * @version 201809
 * @see http://ctecinf.com.br
 */
public abstract class PleaseWaitDialog<T> extends JDialog {

    private JProgressBar progressBar;

    static {
        setDefaultLookAndFeelDecorated(true);
    }

    public PleaseWaitDialog() {
        this(null);
    }

    public PleaseWaitDialog(Frame owner) {
        super(owner);
        init();
    }

    private void init() {

        if (getOwner() != null && !getOwner().isVisible()) {
            getOwner().setVisible(true);
        }

        try {
            progressBar = new JProgressBar();
            progressBar.setPreferredSize(new Dimension(210, 20));
        } catch (Exception ex) {
        }

        setTitle("Aguarde...");

        JPanel panel = new JPanel(new BorderLayout(10, 10));

        panel.add(new JPanel(), BorderLayout.NORTH);
        panel.add(new JPanel(), BorderLayout.SOUTH);
        panel.add(new JPanel(), BorderLayout.EAST);
        panel.add(new JPanel(), BorderLayout.WEST);

        panel.add(progressBar, BorderLayout.CENTER);

        add(panel);

        pack();
        setAlwaysOnTop(true);
        setAutoRequestFocus(true);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    /**
     * Título da janela
     *
     * @param title
     */
    public void title(String title) {
        setTitle(title);
    }

    /**
     * Percentual de progresso do processo
     *
     * @param perc
     */
    public void progress(int perc) {

        try {

            if (progressBar.isIndeterminate()) {
                progressBar.setIndeterminate(false);
                progressBar.setStringPainted(true);
            }

            progressBar.setValue(perc);

        } catch (Exception ex) {
        }
    }

    /**
     * Inicia o processo longo
     */
    public void start() {

        new Thread(() -> {
            try {
                progressBar.setIndeterminate(true);
                T obj = exec();
                PleaseWaitDialog.this.progress(100);
                PleaseWaitDialog.this.dispose();
                PleaseWaitDialog.this.end(obj);
            } catch (Exception ex) {
                PleaseWaitDialog.this.progress(100);
                PleaseWaitDialog.this.dispose();
                OptionPane.error(ex);
            }
        }).start();

    }

    /**
     * Implementar processo longo background
     *
     * @return
     * @throws java.lang.Exception
     */
    public abstract T exec() throws Exception;

    /**
     * Implementar finalização do processo longo
     *
     * @param result Objeto de retorno do método exec();
     * @throws java.lang.Exception
     */
    public abstract void end(T result) throws Exception;
}
