/*
 * Licensed Materials - Property of Rogue Wave Software, Inc. 
 * © Copyright Rogue Wave Software, Inc. 2014, 2015 
 * © 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 ilog.views.maps.IlvMapUtil;
import ilog.views.maps.datasource.ibm.IlvDBAbstractConnectionPanel;
import ilog.views.maps.export.SDOConnectionPanel;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.HeadlessException;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.Field;

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

/**
 * A Non-modal JFileChooser configured when the loading action (as a file filter) changes.
 * When the selection is approved, it starts the background loading of the data.
 */
public class ImportManager extends JFileChooser {
  JDialog dialog;
  /**
   * Creates a JFileChooser configured when the loading action (as a file filter) changes.
   */
  public ImportManager() {
    //      JViews Bug Report 2005.197 
    setCurrentDirectory(new File(defaultDirectory));
    setAcceptAllFileFilterUsed(false);
    addPropertyChangeListener(FILE_FILTER_CHANGED_PROPERTY, new PropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent evt) {
        ImportAction action = getAction();
        if (action != null) {
          filterChange(action);
        }
      }
    });
    addPropertyChangeListener(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY, new PropertyChangeListener() {
     boolean skipThis;
     public void propertyChange(PropertyChangeEvent evt) {
        if(skipThis){
          return;
        }
        ImportAction action = getAction();
        if (action != null) {
          action.selectedFileChanged((File) evt.getNewValue());
          // with the "Load all formats" action, this can change the multi selection.
          // manage this by storing currently selected files, changing the flag and restoring the files.
          if (action.isMultiSelectionEnabled() != isMultiSelectionEnabled()) {
            skipThis=true;
            File[] files;
            if(isMultiSelectionEnabled()){
              files=getSelectedFiles();
            } else {
              files=new File[]{getSelectedFile()};
              // JV-2742
              if(files[0] == null){
                files=null;
              }
            }
            setMultiSelectionEnabled(action.isMultiSelectionEnabled());
            setSelectedFiles(files);
            skipThis=false;
          }
        }
      }
    });
    addPropertyChangeListener(JFileChooser.DIRECTORY_CHANGED_PROPERTY, new PropertyChangeListener() {
      public void propertyChange(PropertyChangeEvent evt) {
        ImportAction action = getAction();
        if (action != null) {
          action.directoryChanged((File) evt.getNewValue());
        }
      }
    });
  }

  File getDirectory(ImportAction action) {
    //JViews Bug Report 2005.197
    File f;
    f = new File(getCurrentDirectory(), action.getSubDirectory());
    if (!f.exists()) {
      f = new File(getCurrentDirectory().getParent(), action.getSubDirectory());
    }
    if (!f.exists()) {
      f = getCurrentDirectory();
    }
    return f;
  }

  ImportAction getAction() {
    FileFilter f = getFileFilter();
    if (f instanceof ImportAction) {
      return (ImportAction) f;
    }
    return null;
  }

  /**
   * @inheritDoc
   */
  public void setFileFilter(FileFilter filter) {
    if (!ignoreFilterChange) {
      super.setFileFilter(filter);
    }
  }

  void filterChange(ImportAction action) {
    JComponent accessory = action.getAccessory();
    FileSystemView view = action.getFileSystemView();
    Component buttonBar = null;
    if (getLayout() instanceof BorderLayout) {
      // JViews Bug Report 2005.182
      BorderLayout layout = (BorderLayout) getLayout();
      try {
        Field f = layout.getClass().getDeclaredField("north"); //$NON-NLS-1$
        f.setAccessible(true);
        buttonBar = (Component) f.get(layout);
        // in JDK 1.5, we could use: buttonBar=layout.getLayoutComponent(BorderLayout.NORTH);
      } catch (Throwable t) {
        // no such method in jdk 1.4
      }
    }
    if (view != null) {
      // hide top button bar
      if (buttonBar != null)
        buttonBar.setVisible(false);
      setFileSystemView(view);
    } else {
      if (buttonBar != null)
        buttonBar.setVisible(true);
      try {
        setCurrentDirectory(getDirectory(action));
      } catch (Throwable t) {
        //ignore
      }
      setFileSystemView(FileSystemView.getFileSystemView());
    }
    setAccessory(accessory);
    if (action instanceof SDOLoadAction) {
      SDOLoadAction sdoAction = (SDOLoadAction) action;
      SDOConnectionPanel panel = sdoAction.getSDOConnectionPanel();
      panel.setFileChooser(this);
    }
// Added by DWA for DB2 and Informix support
// DB2 and Informix load actions are subclasses of AbstractDBLoadAction 
    if (action instanceof AbstractDBLoadAction)         {
        AbstractDBLoadAction dbAction = (AbstractDBLoadAction) action;
        IlvDBAbstractConnectionPanel panel = dbAction.getDBConnectionPanel();
        panel.setFileChooser(this);
      }
    setMultiSelectionEnabled(action.isMultiSelectionEnabled());
    setFileSelectionMode(action.getSelectionMode());
    rescanCurrentDirectory();
    if (dialog != null) {
      dialog.pack();
    }
  }

  /**
   * shows a non modal file selection dialog
   * @see javax.swing.JFileChooser#showDialog(java.awt.Component, java.lang.String)
   */
  public int showDialog(Component parent, String approveButtonText) throws HeadlessException {
    dialog = createDialog(parent);
    // JViews Bug Report 2005.189
    dialog.setTitle(IlvMapUtil.getString(ImportManager.class, "ImportManager.DialogTitle")); //$NON-NLS-1$
    dialog.setModal(false);
    rescanCurrentDirectory();
    dialog.setVisible(true);
    return ERROR_OPTION;
  }

  /**
   * @see javax.swing.JFileChooser#cancelSelection()
   */
  public void cancelSelection() {
    if (dialog != null) {
      dialog.setVisible(false);
      dialog = null;
    }
    fireActionPerformed(CANCEL_SELECTION);
  }

  /**
   * @see javax.swing.JFileChooser#approveSelection()
   */
  public void approveSelection() {
    ImportAction action = getAction();
    if (action != null) {
      boolean ok = action.approveSelection(getSelectedFiles());
      if (!ok)
        return;
    }
    if (dialog != null) {
      dialog.setVisible(false);
      dialog = null;
    }
    fireActionPerformed(APPROVE_SELECTION);
    if (action != null) {
      openIt(action);
    }
  }

  void openIt(ImportAction action) {
    File[] files;
    if (action.isMultiSelectionEnabled()) {
      files = getSelectedFiles();
    } else {
      files = new File[] { getSelectedFile()};
    }
    String fileNames[] = new String[files.length];
    for (int i = 0; i < fileNames.length; i++) {
      fileNames[i] = files[i].getPath();
    }
    loadInBackground(action, fileNames);
  }

  private static String defaultDirectory = "."; //$NON-NLS-1$
  private boolean ignoreFilterChange;

  /**
   * Creates and starts loading the data sources in a background thread for the selected files.
   * @param action action starting the load.
   * @param fileNames files selected by the user.
   */
  public static void loadInBackground(ImportAction action, final String fileNames[]) {
    action.getMonitor().registerThreadedActivity(fileNames);
    action.getMonitor().updateActivityProgress(fileNames, 1, ImportAction.LOADING);
    LoadDataRunnable t = new LoadDataRunnable(action, fileNames);
    t.start();
  }

  /**
   * Sets the base (parent) map directory for all formats.
   * @param directory parent of all format subdirectories.
   */
  public static void setBaseMapDirectory(String directory) {
    defaultDirectory = directory;
  }

  /**
   * @param b
   */
  public void setIgnoreFilterChange(boolean b) {
    ignoreFilterChange = b;
  }

  /**
   * @inheritDoc
   */
  public FileView getFileView() {
    ImportAction action = getAction();
    if(action != null) {
      FileView v = action.getFileView();
      if(v != null)
        return v;
    }
    return super.getFileView();
  }

}