/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2006/03/06, 16:44
!  AUTHOR(S): KOGA, Junichiro
!  File : ChaseInitializer.java
!  
!  Contact address :  Phase System Consortium
!                     E-mail: phase_system@nims.go.jp URL https://azuma.nims.go.jp
!
!
!   Since 2002, this program set had been intensively developed as a part of the following 
!  national projects supported by the Ministry of Education, Culture, Sports, Science and
!  Technology (MEXT) of Japan; "Frontier Simulation Software for Industrial Science
!  (FSIS)" from 2002 to 2005, "Revolutionary Simulation Software (RSS21)" from 2006 to
!  2008. "Research and Development of Innovative Simulation Software (RISS)" from 2008
!  to 2013. These projects is lead by the Center for Research on Innovative Simulation 
!  Software (CISS), the Institute of Industrial Science (IIS), the University of Tokyo.
!   Since 2013, this program set has been further developed centering on PHASE System
!  Consortium. 
!   The activity of development of this program set has been supervised by Takahisa Ohno.
!
!=======================================================================
 */

package ciss.phase_viewer.mainpanel;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import org.apache.log4j.Logger;

import ciss.phase_viewer.settings.GlobalProperties;
import ciss.phase_viewer.settings.PropertiesManager;
import ciss.phase_viewer.ssh.hosts.HostInfo;
import ciss.phase_viewer.ssh.hosts.HostList;

/**
 * プログラム初回起動時に設定などを行うGUI. InternalFrame用のDesktopを構築する前に設定する必要のある項目もあるのでJFrameだ.
 * 
 * @author
 */
public class ChaseInitializer extends FrameChase {
    private Logger logger = Logger.getLogger(ChaseInitializer.class.getName());
    private ChaseGUI chase;
    private String initBaseDir = System.getProperty("user.home")
            + System.getProperty("file.separator") + "phase-viewer-projects";

    /** Creates a new instance of ChaseInitializer */
    public ChaseInitializer(ChaseGUI chase) {
        super("initial configuration", new Dimension(400, 400));
        this.chase = chase;
        init();
    }

    private Container container;
    private JTextField text;
    private JButton btn;
    private JCheckBox loadSample = new JCheckBox("load samples");
    private JCheckBox overwriteSettings = new JCheckBox(
            "overwrite existing settings");

    private void init() {
        container = getContentPane();
        container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));

        container.add(baseDirPanel());
        container.add(createPanelExternal());
        loadSample.setSelected(true);
        overwriteSettings.setSelected(true);
        JPanel psamp = new JPanel();
        psamp.setBorder(new TitledBorder("samples"));
        psamp.add(loadSample);
        container.add(psamp);
        container.add(overwriteSettings);
        container.add(buttons());
        pack();

        int scrx = ChaseGUI.getScreenWidth();
        int scry = ChaseGUI.getScreenHeight();
        int centerx = (int) (scrx / 2 - getSize().width / 2);
        int centery = (int) (scry / 2 - getSize().height / 2);
        setLocation(centerx, centery);

        setVisible(true);
        requestFocus();
    }

    private JPanel buttons() {
        JPanel pbtn = new JPanel();
        JButton ok = new JButton("ok");
        pbtn.add(ok);

        ok.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                doInitialization();
                chase.setLoadSample(loadSample.isSelected());
                setVisible(false);
                gp.storeProperty();
                dispose();
            }
        });

        return pbtn;
    }

    private String baseDir;

    private JPanel baseDirPanel() {
        JPanel p = new JPanel();
        p.add(new PathSelector(initBaseDir, "base directory",
                new PathSelectorAction() {
                    void doIt(String text) {
                        baseDir = text;
                        if (baseDir == null || baseDir.trim().length() == 0) {
                            logger.error("invalid base directory... using default.");
                            baseDir = initBaseDir;
                        }
                        HostInfo localHost = HostList.getHostList()
                                .getHostInfo("localhost");
                        localHost.setProperty("basedir", baseDir);
                        if (!new File(baseDir).mkdirs()) {
                            logger.error("failed to create initial root project directory...");
                        }
                        HostList.getHostList().save();
                    }
                }));
        return p;
    }

    private String getGSPath(String os) {
        if (!os.startsWith("windows")) {
            return "gs";
        }
        File[] root = File.listRoots();
        for (int i = 0; i < root.length; i++) {
            if (root[i].getAbsolutePath().toLowerCase().startsWith("a:")) {
                continue;
            }
            File[] foo = root[i].listFiles(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.equalsIgnoreCase("program files");
                }
            });

            if (foo == null || foo.length == 0) {
                continue;
            }

            File[] gsdir = foo[0].listFiles(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.equalsIgnoreCase("gs");
                }
            });

            if (gsdir == null || gsdir.length == 0) {
                gsdir = root[i].listFiles(new FilenameFilter() {
                    public boolean accept(File dir, String name) {
                        return name.equalsIgnoreCase("gs");
                    }
                });
                if (gsdir == null || gsdir.length == 0) {
                    continue;
                }
            }
            File[] gssubdir = gsdir[0].listFiles(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.startsWith("gs");
                }
            });
            if (gssubdir == null || gsdir.length == 0) {
                continue;
            }
            String ret = gssubdir[gssubdir.length - 1]
                    + System.getProperty("file.separator") + "bin"
                    + System.getProperty("file.separator") + "gswin32c.exe";
            if (new File(ret).exists()) {
                return ret;
            }
            String ret64 = gssubdir[gssubdir.length - 1]
                    + System.getProperty("file.separator") + "bin"
                    + System.getProperty("file.separator") + "gswin64c.exe";
            if (new File(ret64).exists())
                return ret64;
        }
        return "";
    }

    private GlobalProperties gp = PropertiesManager
            .getGlobalProperties(PropertiesManager.PROPERTIES_PVIEWER);

    private JPanel createPanelExternal() {
        JPanel pext = new JPanel();
        pext.setLayout(new BoxLayout(pext, BoxLayout.Y_AXIS));
        // pext.setLayout(new FlowLayout());

        String editor = gp.getProperty("editor");
        String gs = gp.getProperty("gs");

        String os = System.getProperty("os.name").toLowerCase();
        if (os.startsWith("windows")) {
            editor = "NOTEPAD";
        } else {
            editor = "emacs";
        }
        gs = getGSPath(os);

        pext.add(new PathSelector(editor, "external editor",
                new PathSelectorAction() {
                    void doIt(String text) {
                        if (text != null && text.trim().length() != 0) {
                            gp.setProperty("editor", text);
                            gp.storeProperty();
                        }
                    }
                }, false));

        pext.add(new PathSelector(gs, "ghostscript", new PathSelectorAction() {
            void doIt(String text) {
                if (text != null && text.trim().length() != 0) {
                    gp.setProperty("gs", text);
                    gp.storeProperty();
                }
            }
        }, false));

        return pext;
    }

    private void doInitialization() {
        for (int i = 0; i < pathSelectors.size(); i++) {
            PathSelector selector = (PathSelector) pathSelectors.get(i);
            selector.doAction();
        }
        if (overwriteSettings.isSelected())
            Chase.generateDefaultDotChaseDir(true);
        Thread th = new Thread(new PPCopier());
        th.start();
        //
        // String ppdir =
        // System.getProperty("pviewer.home")+System.getProperty("file.separator")+"pp";
        // File dataDir = new
        // File(baseDir+System.getProperty("file.separator")+"data");
        // if ( dataDir.mkdirs() ) {
        // ciss.phase_viewer.common.Utils.copyDir(new File(ppdir),dataDir);
        // File ppdirFile = new
        // File(dataDir.getAbsolutePath()+System.getProperty("file.separator")+"pp");
        // ppdirFile.renameTo(new
        // File(dataDir.getAbsolutePath()+System.getProperty("file.separator")+"pseudopotential"));
        // }
    }

    class PPCopier implements Runnable {
        private JProgressBar bar;
        private File tmppseudoFile;
        private String ppdir;
        private JFrame fr;
        private javax.swing.Timer timer;

        public void run() {
            ppdir = System.getProperty("pviewer.home")
                    + System.getProperty("file.separator") + "pp";
            File dataDir = new File(baseDir
                    + System.getProperty("file.separator") + "data");
            if (dataDir.mkdirs()) {
                progressBar();
                File pseudoFile = new File(dataDir.getAbsolutePath()
                        + System.getProperty("file.separator")
                        + "pseudopotential");
                tmppseudoFile = new File(dataDir.getAbsolutePath()
                        + System.getProperty("file.separator") + "pp");
                ciss.phase_viewer.common.Utils
                        .copyDir(new File(ppdir), dataDir);
                File ppdirFile = new File(dataDir.getAbsolutePath()
                        + System.getProperty("file.separator") + "pp");
                ppdirFile.renameTo(pseudoFile);
            }
            if (fr != null) {
                fr.setVisible(false);
                fr.dispose();
            }
            chase.init();
            timer.stop();
        }

        private void progressBar() {
            int numpp = new File(ppdir).listFiles().length;
            bar = new JProgressBar(0, numpp);
            bar.setValue(0);
            bar.setStringPainted(true);
            bar.setPreferredSize(new Dimension(300, 20));
            fr = new JFrame();
            fr.setTitle("copying PseudoPotential files...");
            fr.getContentPane().add(bar);
            fr.pack();
            int scrx = ChaseGUI.getScreenWidth();
            int scry = ChaseGUI.getScreenHeight();
            int centerx = (int) (scrx / 2 - fr.getSize().width / 2);
            int centery = (int) (scry / 2 - fr.getSize().height / 2);
            fr.setLocation(centerx, centery);
            fr.setVisible(true);
            timer = new javax.swing.Timer(0, new ActionListener() {
                public void actionPerformed(ActionEvent ae) {
                    update();
                }
            });
            timer.start();
        }

        private void update() {
            if (tmppseudoFile.exists()) {
                File[] files = tmppseudoFile.listFiles();
                if (files != null) {
                    bar.setValue(files.length);
                }
            }
        }
    }

    private Vector pathSelectors = new Vector();

    class PathSelector extends JPanel {
        private JTextField textField = new JTextField(30);
        private JButton jButton = new JButton("choose...");
        private PathSelectorAction action;
        private boolean dir = true;
        private String title;
        private String initPath;

        PathSelector(String initPath, String title, PathSelectorAction action,
                boolean dir) {
            this.dir = dir;
            this.initPath = initPath;
            this.title = title;
            this.action = action;
            init();
        }

        PathSelector(String initPath, String title, PathSelectorAction action) {
            this.action = action;
            this.initPath = initPath;
            this.title = title;
            init();
        }

        private void init() {
            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
            setBorder(new TitledBorder(title));
            textField.setText(initPath);
            add(textField);
            add(jButton);
            jButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ae) {
                    JFileChooser chooser = new JFileChooser();
                    chooser.setDialogType(JFileChooser.OPEN_DIALOG);
                    if (dir) {
                        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                    } else {
                        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
                    }
                    if (chooser.showDialog(container, "open") != JFileChooser.APPROVE_OPTION) {
                        return;
                    }
                    textField.setText(chooser.getSelectedFile()
                            .getAbsolutePath());
                }
            });
            pathSelectors.addElement(this);
        }

        void doAction() {
            action.doIt(textField.getText());
        }

    }

    abstract class PathSelectorAction {
        abstract void doIt(String text);
    }

}
