/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on ----
!  AUTHOR(S): KOGA, Junichiro
!  File : InstallerPanel.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.install;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

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

import ciss.phase_viewer.common.MyMessageBox;
import ciss.phase_viewer.settings.PropertyPanel;

class InstallerPanel extends JFrame {

    /** file choose mode */
    private final int FILE = 0;
    private final int DIRECTORY = 1;

    private int[] x = { 380, 380, 0 };
    private int[] y = { 280, 330, 0 };
    private int count = 0;

    /** file separator */
    private String FS = System.getProperty("file.separator");

    /** osname */
    private String osName = System.getProperty("os.name");

    /** java */
    private String javapath = System.getProperty("java.home") + FS + "bin" + FS
            + "java";

    /** location of original phase-viewer.ini */
    private String chaseiniini = System.getProperty("user.dir") + FS
            + "install_files" + FS;

    /**
     * the installer
     * 
     * @uml.property name="installer"
     * @uml.associationEnd multiplicity="(0 1)"
     */
    private Installer installer;

    /** content pane */
    private Container container;

    /**
     * message box
     * 
     * @uml.property name="mbox"
     * @uml.associationEnd multiplicity="(0 1)"
     */
    private MyMessageBox mbox = new MyMessageBox();

    /**
     * 'property panel' object
     * 
     * @uml.property name="propertyPanel"
     * @uml.associationEnd multiplicity="(0 1)"
     */
    private PropertyPanel propertyPanel;

    /** property */
    private Properties prop = new Properties();

    /** text fields for editing program paths */
    private JTextField tfeditor = new JTextField(20);
    private JTextField tfgs = new JTextField(20);
    private JTextField tfemacs = new JTextField(20);
    private JTextField tfmpi = new JTextField(20);
    private JTextField tfbrowser = new JTextField(20);
    private JTextField tfBSV = new JTextField(20);

    /** buttons for selecting paths */
    private JButton btneditor = new JButton("choose...");
    private JButton btngs = new JButton("choose...");
    private JButton btnemacs = new JButton("choose...");
    private JButton btnmpi = new JButton("choose...");
    private JButton btnbrowser = new JButton("choose...");
    private JButton btnBSV = new JButton("chooser...");

    private boolean mpiEnable = true;

    /** for install options panel */
    private JButton btnrc = new JButton("choose...");
    private JButton btnjava = new JButton("choose...");
    private JButton btnjavaopt = new JButton("choose...");

    private JTextField tfrc = new JTextField(20);
    private JTextField tfjava = new JTextField(20);
    private JTextField tfjavaopt = new JTextField(20);

    /** buttons for buttons panel */
    private JButton btnprev = new JButton("previous");
    private JButton btnnext = new JButton("next");
    private JButton btncancel = new JButton("cancel");

    /** use gui or not */
    private boolean guiEnabled = false;

    private String chaseDir = (new File(System.getProperty("user.dir")))
            .getParent();

    /** strings for `properties' */
    private String editor = new String();
    private String gs = new String();
    private String browser = new String();
    private String mpirunpath = new String();
    private String BSV = new String();
    private String chasedir = chaseDir;

    protected InstallerPanel() {
        super("Welcome to chase-3pt installer application");
        createInstallerGUI();
    }

    protected InstallerPanel(Installer installer) {
        super("Welcome to chase-3pt installer application");
        this.installer = installer;
        System.out.println("system: " + osName);
        if (osName.toLowerCase().trim().startsWith("windows")) {
            javapath += ".exe";
        }
        createInstallerGUI();
    }

    protected InstallerPanel(Installer installer, boolean guiEnabled) {
        super("Welcome to chase-3pt installer application");
        this.installer = installer;
        this.guiEnabled = guiEnabled;

        System.out.println("system: " + osName);
        if (osName.toLowerCase().trim().startsWith("windows")) {
            javapath += ".exe";
        }
        createInstallerGUI();
    }

    private void createInstallerGUI() {
        propertyPanel = new PropertyPanel();
        container = this.getContentPane();
        container.setLayout(new FlowLayout());

        container.add(createInstallOptionsPanel());
        container.add(createButtonPanel());

        osName = osName.toLowerCase().trim();
        if (osName.startsWith("windows")) {
            chaseiniini += "phase-viewer_win32.ini";
        } else if (osName.startsWith("mac")) {
            chaseiniini += "phase-viewer_OSX.ini";
        } else if (osName.startsWith("linux")) {
            chaseiniini += "phase-viewer_linux.ini";
        } else {
            chaseiniini += "phase-viewer_generic.ini";
        }

        try {
            System.out.println("load property file: " + chaseiniini);
            prop.load(new FileInputStream(chaseiniini));
        } catch (IOException ioe) {
            ioe.printStackTrace();
            mbox.setText("couldn't find phase-viewer.ini", !guiEnabled);
            mbox.setText("installation failed", !guiEnabled);
            System.exit(0);
        }

        if (guiEnabled) {
            this.addActionListeners();
            this.setSize(x[0], y[0]);
            this.setInitialText();
            this.setVisible(true);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        } else {
            this.setInitialText();
            count = 2;
            this.redraw();
        }
    }

    private void setInitialText() {

        editor = prop.getProperty("editor");
        if (editor != null) {
            tfeditor.setText(editor);
        }

        gs = prop.getProperty("gs");
        if (gs != null) {
            tfgs.setText(gs);
        }

        mpirunpath = prop.getProperty("mpirunpath");
        if (mpirunpath != null) {
            tfmpi.setText(mpirunpath);
        }

        browser = prop.getProperty("browser");
        if (browser != null) {
            tfbrowser.setText(browser);
        }

        BSV = prop.getProperty("BioStationViewer");
        if (BSV != null) {
            tfBSV.setText(BSV);
        }

        tfrc.setText(chaseDir + FS + "bin");
        tfjava.setText(javapath);

        mpiEnable = Boolean.valueOf(prop.getProperty("mpienable").trim())
                .booleanValue();

    }

    private JPanel createInstallOptionsPanel() {
        JPanel p = new JPanel();
        p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
        p.setBorder(new TitledBorder("install options"));
        p.add(propertyPanel.createTF(tfrc, btnrc, "rc path"));
        p.add(propertyPanel.createTF(tfjava, btnjava, "java path"));
        tfjavaopt.setPreferredSize(new Dimension(100, 27));
        p.add(propertyPanel.createTFonly(tfjavaopt,
                "java options (e.g. -Xmx256m)"));
        return p;
    }

    private JPanel createPanelExternal() {
        JPanel p = new JPanel();
        p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
        p.setBorder(new TitledBorder(
                "external program path (you may set these later)"));
        p.add(propertyPanel.createTF(tfeditor, btneditor, "editor"));
        p.add(propertyPanel.createTF(tfgs, btngs, "gs"));
        p.add(propertyPanel.createTF(tfmpi, btnmpi, "mpirun"));
        if (!mpiEnable) {
            tfmpi.setEnabled(false);
            btnmpi.setEnabled(false);
        }
        p.add(propertyPanel.createTF(tfbrowser, btnbrowser, "browser"));
        // p.add(propertyPanel.createTF(tfBSV, btnBSV, "BioStationViewer"));

        return p;
    }

    private void addActionListeners() {

        btnnext.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                count++;
                redraw();
            }
        });

        btnprev.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                count--;
                redraw();
            }
        });

        btncancel.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
                mbox.setText("installation canceled", !guiEnabled);
                System.exit(0);
            }
        });

        btnrc.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                bootFileChooser(tfrc, DIRECTORY);
            }
        });

        btnjava.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                bootFileChooser(tfjava, FILE);
            }
        });

        btneditor.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                bootFileChooser(tfeditor, FILE);
            }
        });

        btngs.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                bootFileChooser(tfgs, FILE);
            }
        });

        btnmpi.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                bootFileChooser(tfmpi, FILE);
            }
        });

        btnbrowser.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                bootFileChooser(tfbrowser, FILE);
            }
        });

        btnBSV.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                bootFileChooser(tfBSV, FILE);
            }
        });
    }

    private JPanel createButtonPanel() {
        JPanel p = new JPanel();
        p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));

        if (count == 0) {
            btnprev.setEnabled(false);
        } else {
            btnprev.setEnabled(true);
        }
        if (count == 1) {
            btnnext.setText("Install");
        } else {
            btnnext.setText("next");
        }

        p.add(btnprev);
        p.add(btnnext);
        p.add(btncancel);

        return p;
    }

    private void redraw() {
        container.removeAll();
        setVisible(false);
        setSize(x[count], y[count]);
        if (count == 0) {
            container.add(createInstallOptionsPanel());
            container.add(createButtonPanel());
            setVisible(true);
        } else if (count == 1) {
            container.add(createPanelExternal());
            container.add(createButtonPanel());
            setVisible(true);
        } else if (count == 2) {
            installer.setRC(tfrc.getText().trim());
            installer.setJava(tfjava.getText().trim());
            installer.setJavaOpts(tfjavaopt.getText().trim());
            this.createProp();
            installer.setProperties(prop);
            installer.startInstall();
        }
        if (count <= 0) {
            btnprev.setEnabled(false);
            count = 0;
        } else if (count >= 1) {
            btnprev.setEnabled(true);
        }
    }

    private void createProp() {

        if (guiEnabled) {
            prop.setProperty("editor", tfeditor.getText().trim());
            prop.setProperty("gs", tfgs.getText().trim());
            prop.setProperty("java", tfjava.getText().trim());
            prop.setProperty("browser", tfbrowser.getText().trim());
            prop.setProperty("mpirunpath", tfmpi.getText().trim());
            prop.setProperty("BioStationViewer", tfBSV.getText().trim());
            prop.setProperty("chasedir", chaseDir);
        } else {
            prop.setProperty("editor", editor);
            prop.setProperty("gs", gs);
            prop.setProperty("java", javapath);
            prop.setProperty("browser", browser);
            prop.setProperty("mpirunpath", mpirunpath);
            prop.setProperty("BioStationViewer", BSV);
            prop.setProperty("chasedir", chaseDir);
        }

        if (osName.toLowerCase().trim().startsWith("windows")) {
            prop.setProperty("taskmgr", "TASKMGR.EXE");
        }
    }

    private void bootFileChooser(JTextField tf, int mode) {
        JFileChooser fdlg = new JFileChooser();
        fdlg.setDialogType(JFileChooser.CUSTOM_DIALOG);
        fdlg.setDialogTitle("choose");
        fdlg.setCurrentDirectory(new File(System.getProperty("user.dir")));
        if (mode == FILE) {
            fdlg.setFileSelectionMode(JFileChooser.FILES_ONLY);
        } else if (mode == DIRECTORY) {
            fdlg.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        } else {
            System.out.println("wrong specification of mode");
            return;
        }
        if (fdlg.showDialog(container, "Select") != JFileChooser.APPROVE_OPTION) {
            return;
        }

        tf.setText(fdlg.getSelectedFile().getAbsolutePath());
    }

    public static void main(String[] args) {
        InstallerPanel panel = new InstallerPanel();
    }

}
