/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.log4j.chainsaw.helper;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import java.util.Locale;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

/**
 * A collection of standard utility methods for use within Swing.
 * 
 * @author Paul Smith &lt;psmith@apache.org&gt;
 *
 */
public final class SwingHelper {
  /**
   * Centers the Component on screen.
   *
   * @param component
   */
  public static void centerOnScreen(Component component) {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    component.setLocation(
      (screenSize.width / 2) - (component.getWidth() / 2),
      (screenSize.height / 2) - (component.getHeight() / 2));
  }
  
  /**
   * This method configures a standard Cancel action, bound to the ESC key, to dispose of the dialog,
   * and sets the buttons action to be this action, and adds the action to the dialog's rootPane 
   * action map
   * @param dialog
   * @param cancelButton
   */
  public static void configureCancelForDialog(final JDialog dialog, JButton cancelButton) {
    String CANCEL_ACTION_KEY = "CANCEL_ACTION_KEY";
    int noModifiers = 0;
    KeyStroke escapeKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, noModifiers, false);
    InputMap inputMap = dialog.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
    inputMap.put(escapeKey, CANCEL_ACTION_KEY);
    
    Action closeAction = new AbstractAction("Cancel") {

      public void actionPerformed(ActionEvent arg0) {
        dialog.dispose();
      }};
    cancelButton.setAction(closeAction);
    dialog.getRootPane().getActionMap().put(CANCEL_ACTION_KEY, closeAction);
    
  }

  public static void invokeOnEDT(Runnable runnable) {
    if (EventQueue.isDispatchThread()) {
      runnable.run();
    } else {
      EventQueue.invokeLater(runnable);
    }
  }

  public static boolean isMacOSX() {
    return System.getProperty("os.name").toLowerCase(Locale.ENGLISH).startsWith("mac os x");
  }

  public static List<JButton> orderOKCancelButtons(JButton okButton, JButton cancelButton) {
    List<JButton> result = new ArrayList<>();
    if (isMacOSX()) {
      result.add(cancelButton);
      result.add(okButton);
    } else {
      result.add(okButton);
      result.add(cancelButton);
    }
    return result;
  }

  public static File promptForFile(Container parent, String defaultPath, String title, boolean loadDialog) {
        if (SwingHelper.isMacOSX()) {
            //use filedialog on mac
            Component root = SwingUtilities.getRoot(parent);
            Frame frame = null;
            if (root instanceof Frame) {
              frame = (Frame) root;
            }

            FileDialog fileDialog = new FileDialog(frame, title);
            fileDialog.setModal(true);
            fileDialog.setMode(loadDialog ? FileDialog.LOAD : FileDialog.SAVE);
            if (defaultPath != null) {
              fileDialog.setDirectory(defaultPath);
            }
            fileDialog.setVisible(true);
            String fileString = fileDialog.getFile();
            if (fileString == null) {
              return null;
            }
          if (fileDialog.getDirectory() != null) {
            return new File(fileDialog.getDirectory(), fileString);
          } else {
            return new File(fileString);
          }
          } else {

                JFileChooser chooser;
                if (defaultPath != null) {
                  chooser = new JFileChooser(defaultPath);
                } else {
                  chooser = new JFileChooser();
                }

                chooser.setDialogTitle(title);

                chooser.setAcceptAllFileFilterUsed(true);

                int i;
                if (loadDialog) {
                  i = chooser.showOpenDialog(parent);
                } else {
                  i = chooser.showSaveDialog(parent);
                }

                if (i != JFileChooser.APPROVE_OPTION) {
                    return null;
                }
            return chooser.getSelectedFile();
        }
    }
}
