/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */
package plugins;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.security.AccessControlException;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Properties;

import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileSystemView;
import javax.swing.filechooser.FileView;

import ilog.views.IlvManagerView;
import ilog.views.maps.IlvMapUtil;
import ilog.views.maps.datasource.IlvMapDataSource;
import ilog.views.swing.IlvThreadedActivityMonitor;
import ilog.views.swing.IlvThreadedActivityMonitorProperty;

/**
 * Generic import action for all formats.
 */
public abstract class ImportAction extends FileFilter {
  static String baseDirectory;
  static String LOADING = IlvMapUtil.getString(ImportAction.class, "ImportAction.LoadingTask"); //$NON-NLS-1$
  static String RENDERING = IlvMapUtil.getString(ImportAction.class, "ImportAction.RenderingTask"); //$NON-NLS-1$

  /**
   * @return the base map directory.
   */
  protected abstract String getSubDirectory();

  final private IlvThreadedActivityMonitor mon;
  private StopButton stopButton;
  final IlvManagerView view;
  private boolean available = true;
  private Properties preferences;

  /**
   * @param view
   */
  public ImportAction(IlvManagerView view) {
    this.view = view;
    this.mon = IlvThreadedActivityMonitorProperty.GetThreadedActivityMonitor(view.getManager());
  }

  /**
   * Returns the description to display in monitoring.
   * 
   * @param action
   *          action for the format.
   * @return the string to display.
   */
  public String getActivityDescription(String action) {
    return action + " " + getFormatName() + " "; //$NON-NLS-1$ //$NON-NLS-2$
  }

  /**
   * Should create an enumeration of data sources created for the file names
   * supplied.
   * 
   * @param fileNames
   *          files selected by the user.
   * @return an enumeration of data sources.
   * @throws IOException
   */
  public abstract Enumeration<IlvMapDataSource> getDataSources(String fileNames[]) throws IOException;

  /**
   * Should create an enumeration of data sources created for the URL supplied.
   * 
   * @param urls
   *          urls selected by the user.
   * @return an enumeration of data sources.
   * @throws IOException
   */
  public abstract Enumeration<IlvMapDataSource> getDataSources(URL urls[]) throws IOException;

  /**
   * This method should return the format name displayed in menus, selection
   * boxes and monitoring.
   * 
   * @return the format name.
   */
  public abstract String getFormatName();

  /**
   * @return Returns the stopButton.
   */
  public StopButton getStopButton() {
    return stopButton;
  }

  /**
   * @param stopButton
   *          The stopButton to set.
   */
  public void setStopButton(StopButton stopButton) {
    this.stopButton = stopButton;
  }

  /**
   * @return the accessory to use besides the file selector.
   */
  public abstract JComponent getAccessory();

  /**
   * @return the monitor used to set import advancement information.
   */
  public IlvThreadedActivityMonitor getMonitor() {
    return mon;
  }

  /**
   * Method to override to change file selection dialog selection mode.
   * 
   * @return JFileChooser.FILES_ONLY
   */
  public int getSelectionMode() {
    return JFileChooser.FILES_ONLY;
  }

  /**
   * Method to override to prevent multi selection of files.
   * 
   * @return true.
   */
  public boolean isMultiSelectionEnabled() {
    return true;
  }

  /**
   * Sets the advancement of the loading.
   * 
   * @param action
   *          sub-action name.
   * @param activityId
   *          identifies the threaded activity
   * @param percent
   *          percentage of import done.
   */
  public void setAdvancement(String action, Object activityId, int percent) {
    mon.updateActivityProgress(activityId, percent, getActivityDescription(action) + "(" + percent + "%)"); //$NON-NLS-1$//$NON-NLS-2$
  }

  /**
   * @return the view managed by the import action.
   */
  public IlvManagerView getView() {
    return view;
  }

  /**
   * @param file
   */
  public void selectedFileChanged(File file) {
    if (file == null) {
      /* do nothing. */}
  }

  /**
   * @param url
   */
  public void selectedURLChanged(URL url) {
    if (url == null) {
      /* do nothing. */}
  }

  /**
   * @param file
   */
  public void directoryChanged(File file) {
    if (file == null) {
      /* do nothing. */}
  }

  /**
   * @see javax.swing.filechooser.FileFilter#getDescription()
   */
  Override
  public String getDescription() {
    String exts[] = getExtensions();
    String extList = ""; //$NON-NLS-1$
    if (exts != null) {
      extList = " (";//$NON-NLS-1$
      for (int i = 0; i < exts.length; i++) {
        extList = extList + " *" + exts[i];//$NON-NLS-1$
      }
      extList = extList + ")";//$NON-NLS-1$
    }
    String pattern = IlvMapUtil.getString(ImportAction.class, "ImportAction.FileFilterSuffix"); //$NON-NLS-1$
    return MessageFormat.format(pattern, new Object[] { getFormatName(), extList });
  }

  /**
   * Checks if the file is either a directory or ends with the extensions.
   * 
   * @see #getExtensions()
   * @see javax.swing.filechooser.FileFilter#accept(java.io.File)
   */
  Override
  public boolean accept(File f) {
    try {
      if (f != null && f.isDirectory())
        return true;
    } catch (AccessControlException e) {
      // applets.
    }
    if (f == null)
      return false;
    String name = f.getName().toLowerCase();
    String extensions[] = getExtensions();
    for (int i = 0; i < extensions.length; i++) {
      if (name.endsWith(extensions[i])) {
        return true;
      }
    }
    return false;
  }

  /**
   * Returns the extension of files accepted by this action.
   * 
   * @return a table of string that accepted files names must end with.
   */

  public abstract String[] getExtensions();

  /**
   * @param selection
   *          list of selected files.
   * @return true to approve the selection.
   */
  public boolean approveSelection(File selection[]) {
    for (int i = 0; i < selection.length; i++) {
      if (!selection[i].exists())
        return false;
    }
    return true;
  }

  /**
   * Gives actions a possibility to change the file system view.
   * 
   * @return The <code>FileSystemView</code>
   */
  public FileSystemView getFileSystemView() {
    return null;
  }

  /**
   * Tells if the action is available
   * 
   * @return The action availability
   */
  public boolean isAvailable() {
    return available;
  }

  /**
   * Indicates whether the action is available
   * 
   * @param available
   *          true to allow action.
   */
  void setAvailable(boolean available) {
    this.available = available;
  }

  /**
   * Specifies the file view
   * 
   * @return A file view or null.
   */
  public FileView getFileView() {
    return null;
  }

  /**
   * Sets some properties that could impact the action.
   * 
   * @param preferences
   */
  public void setPreferences(Properties preferences) {
    this.preferences = preferences;
  }

  /**
   * returns the preferences
   * 
   * @return the preferences
   */
  protected Properties getPreferences() {
    return preferences;
  }

}