/*
 * Copyright (C) 2009-2017 Alistair Neil <info@dazzleships.net>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package lib;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import javax.swing.JProgressBar;
import javax.swing.JTextArea;
import javax.swing.Timer;
import javax.swing.WindowConstants;

/**
 *
 * @author Alistair Neil, <info@dazzleships.net>
 */
public class InfoDialog extends javax.swing.JDialog {

    public static final int CANCEL_BUTTON = 0;
    public static final int CANCEL_WINDOW = 1;
    public static final int OK = 2;
    private Color fg = null;
    private final Frame parent;
    private String strButtClose;
    private String strTitle = "";
    private final Font fontDefault;
    private Timer tmrAutoClose;
    private Timer tmrButtonLock;

    /**
     * Creates new InfoDialog, for parent frame with modality modal
     *
     * @param parent
     */
    public InfoDialog(Frame parent) {
        super(parent, true);
        this.parent = parent;
        initComponents();
        jCheckBoxOption.setVisible(false);
        jProgressBar.setVisible(false);
        fg = jTextInfo.getForeground();
        fontDefault = jTextInfo.getFont();
        setContinueButtonText("Continue");
        setCancelButtonText("Cancel");
        setCloseButtonText("Close");
    }

    @Override
    public final Font getFont() {
        return jPanelMain.getFont();
    }

    /**
     * Convenience methods
     *
     * @param title
     */
    public final void createInfo(String title) {
        createInfo(title, null);
    }

    /**
     *
     * @param title
     * @param info
     */
    public final void createInfo(String title, String info) {
        super.setTitle(strTitle + " " + title);
        setModal(true);
        setCancelVisible(false);
        setContinueButtonText(strButtClose);
        jProgressBar.setVisible(false);
        FontMetrics fm = getFontMetrics(getFont());
        int width = fm.stringWidth(getTitle());
        if (width > getWidth()) {
            setSize(width, getHeight());
        }
        jTextInfo.setFont(fontDefault);
        jTextInfo.setForeground(fg);
        jTextInfo.setText("");
        if (info != null) {
            jTextInfo.setText(info);
        }
        jTextInfo.setCaretPosition(0);
        setLocationRelativeTo(parent);
    }

    /**
     * Set dialog title
     *
     * @param title
     */
    @Override
    public final void setTitle(String title) {
        strTitle = title;
        super.setTitle(strTitle);
    }

    /**
     *
     * @param title
     */
    public final void createWarn(String title) {
        createWarn(title, null);
    }

    /**
     * Create warning dialog
     *
     * @param title
     * @param info
     */
    public final void createWarn(String title, String info) {
        super.setTitle(strTitle + " " + title);
        setModal(true);
        setCancelVisible(true);
        jProgressBar.setVisible(false);
        FontMetrics fm = getFontMetrics(getFont());
        int width = fm.stringWidth(getTitle());
        if (width > getWidth()) {
            setSize(width, getHeight());
        }
        jTextInfo.setFont(fontDefault);
        jTextInfo.setForeground(fg);
        jTextInfo.setText("");
        if (info != null) {
            jTextInfo.setText(info);
        }
        setLocationRelativeTo(parent);
        jTextInfo.setCaretPosition(0);
    }

    /**
     * Create progress bar dialog
     *
     * @param title
     * @param info
     */
    public final void createProgress(String title, String info) {
        super.setTitle(strTitle + " " + title);
        setModal(true);
        setCancelVisible(true);
        jProgressBar.setVisible(true);
        FontMetrics fm = getFontMetrics(getFont());
        int width = fm.stringWidth(getTitle());
        if (width > getWidth()) {
            setSize(width, getHeight());
        }
        jTextInfo.setFont(fontDefault);
        jTextInfo.setForeground(fg);
        jTextInfo.setText("");
        if (info != null) {
            jTextInfo.setText(info);
        }
        setLocationRelativeTo(parent);
        jTextInfo.setCaretPosition(0);
    }

    /**
     * Overridable handle for a progress based task
     *
     * @param status
     * @param jpb
     */
    public void progressTask(int status, JProgressBar jpb) {
    }

    /**
     * Create error dialog
     *
     * @param title
     */
    public final void createError(String title) {
        createError(title, null);
    }

    /**
     * Create error dialog
     *
     * @param title
     * @param info
     */
    public final void createError(String title, String info) {
        super.setTitle(strTitle + " " + title);
        setModal(true);
        setCancelVisible(false);
        setContinueButtonText(strButtClose);
        jProgressBar.setVisible(false);
        FontMetrics fm = getFontMetrics(getFont());
        int width = fm.stringWidth(getTitle());
        if (width > getWidth()) {
            setSize(width, getHeight());
        }
        jTextInfo.setFont(fontDefault);
        jTextInfo.setForeground(fg);
        jTextInfo.setText("");
        if (info != null) {
            jTextInfo.setText(info);
        }
        setLocationRelativeTo(parent);
        jTextInfo.setCaretPosition(0);
    }

    public final void setTimeLock(final int secs) {
        jButtonCancel.setEnabled(false);
        jButtonContinue.setEnabled(false);
        this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        final String buttontext = jButtonCancel.getText();
        tmrButtonLock = new Timer(1000, new java.awt.event.ActionListener() {
            int localsecs = secs;

            @Override
            public void actionPerformed(ActionEvent e) {
                localsecs--;
                if (localsecs == 0) {
                    tmrButtonLock.stop();
                    jButtonCancel.setText(buttontext);
                    jButtonCancel.setEnabled(true);
                    jButtonContinue.setEnabled(true);
                } else {
                    jButtonCancel.setText(buttontext + " (" + localsecs + ")");
                }
            }
        });
        jButtonCancel.setText(buttontext + " (" + secs + ")");
        tmrButtonLock.start();
    }

    public final void setCloseButtonText(String text) {
        strButtClose = text;
    }

    public final void setCancelButtonText(String text) {
        jButtonCancel.setText(text);
    }

    public final void setContinueButtonText(String text) {
        jButtonContinue.setText(text);
    }

    public final void setCheckBoxText(String text) {
        jCheckBoxOption.setText(text);
    }

    /**
     * Enable/Disable Autoscrolling
     *
     * @param enabled
     */
    public final void setAutoScrollEnabled(boolean enabled) {
        jTextInfo.setAutoscrolls(enabled);
    }

    /**
     * Append text to the information area, Scrolling should be enabled
     *
     * @param text
     */
    public final void appendInfoText(String text) {
        jTextInfo.append(text);
        jTextInfo.setCaretPosition(jTextInfo.getText().length());
    }

    /**
     * Set whether the forms checkbox is enabled
     *
     * @param enabled
     */
    public final void setCheckBoxVisible(boolean enabled) {
        jCheckBoxOption.setVisible(enabled);
    }

    /**
     * Set check box selection status
     *
     * @param checked
     */
    public final void setCheckBoxEnabled(boolean checked) {
        jCheckBoxOption.setSelected(checked);
    }

    /**
     * Test to see if checkbox is selected
     *
     * @return boolean True if selected
     */
    public final boolean isCheckBoxSelected() {
        return jCheckBoxOption.isSelected();
    }

    /**
     * Set info font
     *
     * @param font
     * @param sizeoffset
     */
    public final void setFont(String font, int sizeoffset) {
        jTextInfo.setFont(new Font(font, jTextInfo.getFont().getStyle(),
                jTextInfo.getFont().getSize() + sizeoffset));
    }

    /**
     * Set the form auto close period in milliseconds
     *
     * @param millis
     */
    public final void setAutoClose(int millis) {
        tmrAutoClose = new Timer(millis, new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                tmrAutoClose.stop();
                doClose(CANCEL_WINDOW);
            }
        });
        tmrAutoClose.start();
    }

    public final JTextArea getTextArea() {
        return jTextInfo;
    }

    /**
     * @return the return status of this dialog - one of RET_OK or RET_CANCEL
     */
    public final int getReturnStatus() {
        return returnStatus;
    }

    /**
     * Set dialog message body
     *
     * @param text
     */
    public final void setInfoText(String text) {
        jTextInfo.setText(text);
    }

    /**
     * Set dialog message body, and font colour
     *
     * @param text
     * @param fgcolor
     */
    public final void setInfoText(String text, Color fgcolor) {
        jTextInfo.setForeground(fgcolor);
        jTextInfo.setText(text);
    }

    /**
     * Set whether Cancel button is enabled
     *
     * @param enabled
     */
    public final void setCancelEnabled(boolean enabled) {
        jButtonCancel.setEnabled(enabled);
    }

    /**
     * Set whether Cancel button is visible
     *
     * @param visible
     */
    public final void setCancelVisible(boolean visible) {
        jButtonCancel.setVisible(visible);
    }

    /**
     * Set whether Ok button is enabled
     *
     * @param enabled
     */
    public final void setAckEnabled(boolean enabled) {
        jButtonContinue.setEnabled(enabled);
    }

    /**
     * Set whether OK button is visible
     *
     * @param visible
     */
    public final void setAckVisible(boolean visible) {
        jButtonContinue.setVisible(visible);
    }

    public void setVisibleWithFocus(boolean visible) {
        super.setVisible(visible);
        this.requestFocus();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanelMain = new javax.swing.JPanel();
        jButtonCancel = new javax.swing.JButton();
        jCheckBoxOption = new javax.swing.JCheckBox();
        jButtonContinue = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTextInfo = new javax.swing.JTextArea();
        jProgressBar = new javax.swing.JProgressBar();

        setMinimumSize(new java.awt.Dimension(410, 165));
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                closeDialog(evt);
            }
        });

        jPanelMain.setFont(jPanelMain.getFont().deriveFont(jPanelMain.getFont().getStyle() | java.awt.Font.BOLD, jPanelMain.getFont().getSize()+2));
        jPanelMain.setOpaque(false);

        jButtonCancel.setText("Cancel");
        jButtonCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonCancelActionPerformed(evt);
            }
        });

        jCheckBoxOption.setText("Disable this notification.");

        jButtonContinue.setText("Continue");
        jButtonContinue.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonContinueActionPerformed(evt);
            }
        });

        jTextInfo.setEditable(false);
        jTextInfo.setColumns(20);
        jTextInfo.setLineWrap(true);
        jTextInfo.setRows(5);
        jTextInfo.setWrapStyleWord(true);
        jScrollPane2.setViewportView(jTextInfo);

        jProgressBar.setString("");
        jProgressBar.setStringPainted(true);

        javax.swing.GroupLayout jPanelMainLayout = new javax.swing.GroupLayout(jPanelMain);
        jPanelMain.setLayout(jPanelMainLayout);
        jPanelMainLayout.setHorizontalGroup(
            jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelMainLayout.createSequentialGroup()
                .addComponent(jCheckBoxOption)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 63, Short.MAX_VALUE)
                .addComponent(jButtonCancel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButtonContinue))
            .addComponent(jScrollPane2)
            .addComponent(jProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        jPanelMainLayout.setVerticalGroup(
            jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelMainLayout.createSequentialGroup()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 304, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jCheckBoxOption)
                    .addComponent(jButtonContinue)
                    .addComponent(jButtonCancel)))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanelMain, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanelMain, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents
    private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed
        doClose(CANCEL_BUTTON);
    }//GEN-LAST:event_jButtonCancelActionPerformed

    /**
     * Closes the dialog
     */
    private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
        if (tmrButtonLock == null || !tmrButtonLock.isRunning()) {
            doClose(CANCEL_WINDOW);
        }
    }//GEN-LAST:event_closeDialog

    private void jButtonContinueActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonContinueActionPerformed
        doClose(OK);
    }//GEN-LAST:event_jButtonContinueActionPerformed

    private void doClose(int retStatus) {
        if (jProgressBar.isVisible()) {
            progressTask(retStatus, jProgressBar);
            return;
        }
        if (tmrAutoClose != null) {
            tmrAutoClose.stop();
            tmrAutoClose = null;
        }
        if (tmrButtonLock != null) {
            tmrButtonLock.stop();
            tmrButtonLock = null;
        }
        returnStatus = retStatus;
        setVisible(false);
        dispose();
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonCancel;
    private javax.swing.JButton jButtonContinue;
    private javax.swing.JCheckBox jCheckBoxOption;
    private javax.swing.JPanel jPanelMain;
    private javax.swing.JProgressBar jProgressBar;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JTextArea jTextInfo;
    // End of variables declaration//GEN-END:variables
    private int returnStatus = CANCEL_BUTTON;
}
