/* Copyright (C) 2022 Free Software Foundation

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 3 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, see <http://www.gnu.org/licenses>.  */


package org.gprofng.mpmt.progress;

import org.gprofng.mpmt.AnLocale;
import org.gprofng.mpmt.AnWindow;
import org.gprofng.mpmt.guitesting.GUITesting;
import org.gprofng.mpmt.util.gui.AnUtility;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class ProgressPanel extends JPanel implements MouseListener {

  private Cursor currentCursor;
  private InternalHandle internalHandle;

  public ProgressPanel() {
    initComponents();
    label.setFont(label.getFont().deriveFont(Font.PLAIN));
    progressBar.setIndeterminate(true);
    progressBar.setFont(
        progressBar.getFont().deriveFont((float) progressBar.getFont().getSize() - 2));
    Dimension dim;
    dim = progressBar.getPreferredSize();
    dim.height = 14;
    progressBar.setPreferredSize(dim);
    dim = new Dimension(0, 22);
    verticalFiller.setPreferredSize(dim);
    label.addMouseListener(this);
    progressBar.addMouseListener(this);
    cancelButton.addMouseListener(this);
    cancelButton.setToolTipText(AnLocale.getString("Click to cancel task..."));
    //        cancelButton.setEnabled(false);
    setOpaque(false);
  }

  /**
   * Create a progress ui handle for a long lasting task.
   *
   * @param allowToCancel either null, if the task cannot be cancelled or an instance of {@link
   *     org.openide.util.Cancellable} that will be called when user triggers cancel of the task.
   * @param displayName to be shown in the progress UI
   * @return an instance of {@link org.netbeans.api.progress.ProgressHandle}, initialized but not
   *     started.
   */
  public ProgressHandle createHandle(CancelContext cancelContext) {
    return new ProgressHandle(internalHandle = new InternalHandle(this, cancelContext));
  }

  public ProgressHandle createHandle() {
    return createHandle(null);
  }

  protected void progress(String message, int workunit) {
    String txt = message;
    if (txt != null) {
      int len = txt.length();
      if (len > 0) {
        if (len > 45) {
          txt = txt.substring(0, 45) + "...";
        }
        label.setText(txt);
        label.setToolTipText(message);
        progressBar.setToolTipText(message);
      }
    }
    if (workunit > 0) {
      progressBar.setValue(workunit);
    }
  }

  protected void toDeterminate(int workunits, int xxx) {
    progressBar.setIndeterminate(false);
    progressBar.setMinimum(0);
    progressBar.setMaximum(workunits);
    progressBar.setStringPainted(true);
  }

  protected void toIndeterminate() {
    progressBar.setIndeterminate(true);
    progressBar.setStringPainted(false);
  }

  @Override
  public void setVisible(boolean b) {
    if (GUITesting.getInstance().isRunningUnderGUITesting()) {
      super.setVisible(b);
    } else {
      label.setVisible(b);
      progressBar.setVisible(b);
      cancelButton.setVisible(b);
    }
  }

  @Override
  public void mouseEntered(MouseEvent e) {
    currentCursor = getCursor();
    setCursor(Cursor.getDefaultCursor());
  }

  @Override
  public void mouseExited(MouseEvent e) {
    setCursor(currentCursor);
  }

  @Override
  public void mouseReleased(MouseEvent e) {}

  @Override
  public void mousePressed(MouseEvent e) {}

  @Override
  public void mouseClicked(MouseEvent e) {}

  /**
   * 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.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {
    java.awt.GridBagConstraints gridBagConstraints;

    label = new javax.swing.JLabel();
    progressBar = new javax.swing.JProgressBar();
    cancelButton = new javax.swing.JButton();
    verticalFiller =
        new javax.swing.Box.Filler(
            new java.awt.Dimension(0, 0),
            new java.awt.Dimension(0, 0),
            new java.awt.Dimension(0, 0));

    setLayout(new java.awt.GridBagLayout());
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    add(label, gridBagConstraints);

    progressBar.setPreferredSize(new java.awt.Dimension(70, 16));
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 1;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.ipadx = 138;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 0);
    add(progressBar, gridBagConstraints);

    cancelButton.setIcon(
        new javax.swing.ImageIcon(
            getClass().getResource("/org/gprofng/mpmt/icons/cancelProcess.png")));
    cancelButton.setBorderPainted(false);
    cancelButton.setContentAreaFilled(false);
    cancelButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
    cancelButton.addActionListener(
        new java.awt.event.ActionListener() {
          public void actionPerformed(java.awt.event.ActionEvent evt) {
            cancelButtonActionPerformed(evt);
          }
        });
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 2;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
    gridBagConstraints.insets = new java.awt.Insets(2, 0, 0, 0);
    add(cancelButton, gridBagConstraints);
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 3;
    gridBagConstraints.gridy = 0;
    add(verticalFiller, gridBagConstraints);
  } // </editor-fold>//GEN-END:initComponents

  private void cancelButtonActionPerformed(
      java.awt.event.ActionEvent evt) { // GEN-FIRST:event_cancelButtonActionPerformed
    final CancelContext cancelContext = internalHandle.getCancelContext();
    if (cancelContext == null) {
      return;
    }
    String msg =
        cancelContext.getTaskName()
            + "\n"
            + AnLocale.getString("Are you sure you want to cancel this task?");
    JOptionPane optionPane =
        new JOptionPane(msg, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
    optionPane.setFont(optionPane.getFont().deriveFont(Font.PLAIN));
    JDialog dialog =
        optionPane.createDialog(
            AnWindow.getInstance().getFrame(), AnLocale.getString("Cancel Task"));
    disableYesButtonAndChangeFont(optionPane); // FIXUP: hack
    dialog.setVisible(true);
    Object selectedValue = optionPane.getValue();
    if (selectedValue != null && selectedValue instanceof Integer) {
      int ret = ((Integer) selectedValue).intValue();
      if (ret == JOptionPane.YES_OPTION) {
        AnUtility.dispatchOnAWorkerThread(
            new Runnable() {
              @Override
              public void run() {
                cancelContext.getCancellable().cancel();
              }
            },
            "CancelTaskThread");
      }
    }
  } // GEN-LAST:event_cancelButtonActionPerformed

  private void disableYesButtonAndChangeFont(JComponent component) {
    for (Component comp : component.getComponents()) {
      if (comp instanceof JComponent) {
        JComponent childComp = (JComponent) comp;
        if (childComp instanceof JButton || childComp instanceof JLabel) {
          childComp.setFont(childComp.getFont().deriveFont(Font.PLAIN));
          //                    if (childComp instanceof JButton) {
          //                        JButton button = (JButton)childComp;
          //                        if (button.getText().equals("Yes")) {
          //                            button.setEnabled(false); // FIXUP: remove to enable
          // cancelling of tasks.....
          //                        }
          //                    }
        }
        disableYesButtonAndChangeFont((JComponent) childComp);
      }
    }
  }

  protected void setCancelButtonEnabled(boolean enable) {
    cancelButton.setEnabled(enable);
  }
  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JButton cancelButton;
  private javax.swing.JLabel label;
  private javax.swing.JProgressBar progressBar;
  private javax.swing.Box.Filler verticalFiller;
  // End of variables declaration//GEN-END:variables
}
