/*
 * 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 shared;

import ilog.views.IlvManagerView;
import ilog.views.maps.IlvMapOutputStream;
import ilog.views.maps.IlvMapUtil;
import ilog.views.maps.raster.IlvRasterMappedBuffer;
import ilog.views.util.IlvImageUtil;
import ilog.views.util.waitcursor.IlvWaitCursorManager;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.Locale;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import plugins.AppletImportManager;
import plugins.ImportAction;
import plugins.ImportManager;
import plugins.LoadAnythingAction;
import plugins.LoadDataRunnable;
import plugins.StopButton;
import utils.IvlFileManager;

/**
 * Adds the import buttons to the base demo.
 */
public class MapBuilder extends BaseDemo {
        static JFrame frame;
        static {
            // set up the default map directory
                String local = IlvMapUtil.getString(MapBuilder.class,
                                "MapBuilder.LocalDirectory"); //$NON-NLS-1$
                boolean exists;
                try {
                        exists = new File(local).exists();
                } catch (AccessControlException e) {
                        exists = false;
                }
                if(exists)
                        ImportManager.setBaseMapDirectory(local);
                else
                        ImportManager.setBaseMapDirectory(IlvMapUtil.getString(MapBuilder.class,
                                        "MapBuilder.DistantDirectory")); //$NON-NLS-1$
           // make sure we use japanese fonts if they exist
                if (Locale.getDefault().getLanguage() == "ja") {  //$NON-NLS-1$
                    try {
                        Method m = GraphicsEnvironment.class.getMethod("preferLocaleFonts", (Class[])null); //$NON-NLS-1$
                        GraphicsEnvironment ge = GraphicsEnvironment
                            .getLocalGraphicsEnvironment();
                        m.invoke(ge,(Object[]) null);
                    } catch (Exception e) {
                        // too bad
                    }
                }
        }

        ArrayList allInstances = new ArrayList();
        // Class that starts import plug-in actions through reflection.       
        static class ImportActionFactory {
                final String className;

                ImportActionFactory(final String className) {
                        this.className = className;
                }

                /**
                 * @return Returns the className.
                 */
                public String getClassName() {
                        return className;
                }

                ImportAction getInstance(IlvManagerView view) {
                        ImportAction action = null;
                        try {
                                Class pluginClass = Class.forName(getClassName());
                                Constructor c = pluginClass
                                                .getConstructor(new Class[] { IlvManagerView.class });
                                action = (ImportAction) c.newInstance(new Object[] { view });
                        } catch (Exception e1) {
                                e1.printStackTrace();
                        }
                        return action;
                }
        }

        /**
         * Returns a table containing all the Import actions created.
         * 
         * @return Returns a table containing all the Import actions created.
         */
        public ImportAction[] getAllImportActions() {
                return (ImportAction[]) allInstances.toArray(new ImportAction[0]);
        }

        /**
         * Button or menu to import data.
         */
        protected JComponent importBtn;
    private LoadAnythingAction dropAction;

        /**
         * Returns a list of class names to be used as import actions in the import
         * menu.
         * 
         * @return the list of class names to be used as import actions in the import
         *         menu.
         */
        protected ArrayList getImportActionClassNames() {
                ArrayList list = new ArrayList();
        list.add("plugins.LoadAnythingAction"); //$NON-NLS-1$
                list.add("plugins.ShapeLoadAction");//$NON-NLS-1$
                list.add("plugins.TigerLoadAction");//$NON-NLS-1$
                list.add("plugins.MIDMIFLoadAction");//$NON-NLS-1$
                list.add("plugins.VMAPLoadAction");//$NON-NLS-1$
                list.add("plugins.GTopo30LoadAction");//$NON-NLS-1$
                list.add("plugins.GeotiffLoadAction");//$NON-NLS-1$
                list.add("plugins.USRPLoadAction");//$NON-NLS-1$
                list.add("plugins.ASRPLoadAction");//$NON-NLS-1$
                list.add("plugins.CADRGLoadAction");//$NON-NLS-1$
                list.add("plugins.BasicImageLoadAction");//$NON-NLS-1$
                list.add("plugins.DTEDAvgLoadAction"); //$NON-NLS-1$
                list.add("plugins.DTEDMinLoadAction"); //$NON-NLS-1$
                list.add("plugins.DTEDMaxLoadAction"); //$NON-NLS-1$
                list.add("plugins.DTEDLoadAction"); //$NON-NLS-1$
                list.add("plugins.DXFLoadAction");//$NON-NLS-1$
                list.add("plugins.KMLLoadAction");//$NON-NLS-1$
                list.add("plugins.S57LoadAction");//$NON-NLS-1$
                list.add("plugins.S57LoadCatalogAction");//$NON-NLS-1$
                list.add("plugins.DAFIFLoadAction");//$NON-NLS-1$
                list.add("plugins.IBMDB2LoadAction"); //$NON-NLS-1$
                list.add("plugins.IBMInformixLoadAction"); //$NON-NLS-1$        
                list.add("plugins.SDOLoadAction"); //$NON-NLS-1$
        list.add("plugins.WMSLoadAction"); //$NON-NLS-1$
        list.add("plugins.SVGLoadAction");//$NON-NLS-1$
                return list;
        }


        /**
         * @param isApplet
         *          true to launch the map builder in applet mode.
         */
        public MapBuilder(final boolean isApplet) {
                super();
        // Make sure the swing construction is called in Swing event thread.
        ilog.views.util.swing.IlvSwingUtil.invokeAndWait(new Runnable() { public void run() {
                if(isApplet) {// do not try to write temporary files.
                        IlvRasterMappedBuffer
                                        .setDefaultMemoryPolicy(IlvRasterMappedBuffer.USE_MEMORY);
                }
                StopButton stop = new StopButton();
                Image image;
                try {
                        image = IlvImageUtil.getImageFromFile(MapBuilder.class,
                                        "/icons/stop_icon.gif");//$NON-NLS-1$
                        stop.setToolTipText(IlvMapUtil.getString(MapBuilder.class,
                                        "MapBuilder.StopTip")); //$NON-NLS-1$
                        stop.setIcon(new ImageIcon(image));
                        stop.setMargin(new Insets(2, 2, 2, 2));
                } catch (IOException e1) {
                        stop.setText("X"); //$NON-NLS-1$
                }
                stop.setSize(stop.getPreferredSize());
                view.add(stop);
                ArrayList actionNames = getImportActionClassNames();
                if(isApplet) {
                        // no exit and save/save as for applets.
                        exitBtn.setVisible(false);
                        saveAsBtn.setVisible(false);
                        saveBtn.setVisible(false);
                        exportBtn.setVisible(false);
                        mapBuilder.setEnabled(false);
                        actionNames.remove("plugins.VMAPLoadAction");// in 7.5, VMAP is not //$NON-NLS-1$
                                                                                                                                                                                                                // available through URLs
                                                                                                                                                                                                                // //$NON-NLS-1$
                        // we will use a sub menu instead of the file selection filter
                        // capabilities
                        JMenu subMenu = new JMenu(IlvMapUtil.getString(MapBuilder.class,
                                        "MapBuilder.Load"));//$NON-NLS-1$
                        final AppletImportManager manager = new AppletImportManager();
                        for (int ip = 0; ip < actionNames.size(); ip++) {
                                ImportActionFactory plugin = new ImportActionFactory(actionNames
                                                .get(ip).toString());
                                final ImportAction ia = plugin.getInstance(view);
                                if(ia == null || !ia.isAvailable())
                                        continue;
                                allInstances.add(ia);
                                ia.setPreferences(getPreferences());
                                ia.setStopButton(stop);
                                JMenuItem b = new JMenuItem(ia.getDescription()
                                                + IlvMapUtil.getString(MapBuilder.class, "MapBuilder.LoadEnd")); //$NON-NLS-1$
                                b.addActionListener(new ActionListener() {
                                        public void actionPerformed(ActionEvent e) {
                                                URL u = manager.chooseURL(MapBuilder.this, getView(), ia);
                                                if(u != null) {
                                                        LoadDataRunnable t = new LoadDataRunnable(ia, new URL[] { u });
                                                        t.start();
                                                }
                                        }
                                });
                                subMenu.add(b);
                        }
                        fileMenu.insert(subMenu, 0);
                        importBtn = subMenu;
                } else {
                        // Exporter
                        final ImportManager manager = new ImportManager();
                        for (int ip = 0; ip < actionNames.size(); ip++) {
                                ImportActionFactory plugin = new ImportActionFactory(actionNames
                                                .get(ip).toString());
                                final ImportAction i = plugin.getInstance(view);
                                if(!i.isAvailable())
                                        continue;
                                allInstances.add(i);
                i.setPreferences(getPreferences());
                                i.setStopButton(stop);
                                manager.addChoosableFileFilter(i);
                                manager.setIgnoreFilterChange(true);
                        }
                        manager.setIgnoreFilterChange(false);
                        JMenuItem b = new MBMenuItem("MapBuilder.Import", true); //$NON-NLS-1$
                        b.addActionListener(new ActionListener() {
                                public void actionPerformed(ActionEvent e) {
                                        manager.showOpenDialog(view);
                                }
                        });
                        fileMenu.insert(b, 1);
                        importBtn = b;
                }
        ImportAction[] list = getAllImportActions();
        for (int i = 0; i < list.length; i++) {
          if (list[i] instanceof LoadAnythingAction) {
            dropAction=(LoadAnythingAction)list[i];
            dropAction.setActions(list);
          }
        }
        }});// event thread runnable
        }

        public void setCurrentFile(String fileName) {
                super.setCurrentFile(fileName);
                updateTitle();
        }

        public void setModified(boolean modified) {
                super.setModified(modified);
                updateTitle();
        }

        /**
         * Updates the title of the frame with appropriate current file name and
         * modified state.
         */
        protected void updateTitle() {
                String f = ((getCurrentFile() == null) ? "" : " " + getCurrentFile()) //$NON-NLS-1$//$NON-NLS-2$
                                + ((isModified()) ? IlvMapUtil.getString(MapBuilder.class,
                                                "MapBuilder.ModifiedMap") : ""); //$NON-NLS-1$ //$NON-NLS-2$
                if(frame != null) // Applet
                        frame
                                        .setTitle(IlvMapUtil.getString(MapBuilder.class, "MapBuilder.Title") + f); //$NON-NLS-1$
        }

        /**
         * Main method
         * 
         * @param args
         *          (ignored)
         */
        public static void main(String[] args) {
      BaseDemo.showSplashScreen();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                        final MapBuilder applet = new MapBuilder(false);
                        frame = new JFrame(IlvMapUtil.getString(MapBuilder.class,
                                        "MapBuilder.Title")); //$NON-NLS-1$    
                        // JViews Bug Report 2005.189
                        try {
                                frame.setIconImage(IlvImageUtil.getImageFromFile(BaseDemo.class,
                                                "/icons/default_frame_icon.gif")); //$NON-NLS-1$
                        } catch (IOException e1) {
                                // ignore.
                        }
                        applet.getPreviewButton().addActionListener(new ActionListener() {
                                public void actionPerformed(ActionEvent ev) {
                                        applet.getPrintingController().printPreview(frame);
                                }
                        });
                        // Action to open the setup dialog box.
                        applet.getSetupButton().addActionListener(new ActionListener() {
                                public void actionPerformed(ActionEvent ev) {
                                        applet.getPrintingController().setupDialog(frame, true, true);
                                }
                        });
                        // Action to print the document.
                        applet.getPrintButton().addActionListener(new ActionListener() {
                                public void actionPerformed(ActionEvent ev) {
                                        try {
                                                applet.getPrintingController().print(true);
                                        } catch (Exception e) {
                                                /* ignore exceptions */
                                        }
                                }
                        });
                        frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
                        frame.addWindowListener(new WindowAdapter() {
                                public void windowClosing(WindowEvent e) {
                                        applet.exitApplication();
                                }
                        });
                        frame.getContentPane().add(applet);
                        IlvWaitCursorManager.init(); // will push an event queue and fix the dual
                                                                                                                                                // screen mode problem for 3D
                                frame.pack();
                                frame.setVisible(true);
                        }
                });
        }
      public void dropFile(File f) {
        if (f.getName().toLowerCase().endsWith(IlvMapOutputStream.getFileSuffix())) { 
          IvlFileManager.LoadIvlActionListener loader = new IvlFileManager.LoadIvlActionListener(this);
          loader.doLoad(f);
        } else if(dropAction!=null){
          dropAction.dropFile(f);
        }
      }

}