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

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

import ciss.phase_viewer.common.ChaseFileChooser;
import ciss.phase_viewer.mainpanel.InternalFrameChase;

public class PropertyPanel extends InternalFrameChase {

    /** content pane */
    private Container cont;

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

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

    /** tabbed pane */
    private JTabbedPane tp;
    /** 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 tfperl = new JTextField(20);
    private JTextField tfbrowser = new JTextField(20);
    private JTextField tfBSV = new JTextField(20);

    /** the following are directories */
    private JTextField tfchasedir = new JTextField(20);
    private JTextField tfphasedir = 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 btnperl = new JButton("choose...");
    private JButton btnbrowser = new JButton("choose...");
    private JButton btnBSV = new JButton("chooser...");

    /** the following are directories */
    private JButton btnchasedir = new JButton("choose...");
    private JButton btnphasedir = new JButton("choose...");

    /** btn for the panel */
    private JButton btnsave;
    private JButton btnsaveclose;
    private JButton btnclose;

    /**
     * このGUIを作成し, 必要な情報を取得する. さらにアクションリスナーの配備などを行う.
     * 
     * @param parent
     *            親ウィンドウ
     */
    public PropertyPanel() {
        super("edit properties", true, true, true, true,
                new Dimension(360, 320));
        this.pm = PropertiesManager
                .getGlobalProperties(PropertiesManager.PROPERTIES_PVIEWER);

        tp = new JTabbedPane();
        tp.addTab("external program path", createPanelExternal());

        cont = getContentPane();
        cont.setLayout(new FlowLayout());

        cont.add(tp);
        cont.add(createButtonPanel());

        setTextFromPM();
        addListenersAll();
        revalidate();
    }

    /**
     * 指定のタブを選択状態にする.
     * 
     * @param tab
     *            選択状態にしたいタブの番号.
     */
    public void selectTab(int tab) {
        tp.setSelectedIndex(tab);
    }

    /**
     * 外部プログラム設定用パネルを取得する.
     * 
     * @return 設定用のパネル.
     */
    public JPanel getPanelExternal() {
        return this.createPanelExternal();
    }

    /**
     * PHASE-Viewerソフトウェア関連の設定用パネルを取得する.
     * 
     * @return 設定用のパネル.
     */
    public JPanel getPanelPHASEViewer() {
        return this.createPanelPHASEViewer();
    }

    /** create panel for external program path */
    private JPanel createPanelExternal() {
        JPanel pext = new JPanel();
        pext.setLayout(new BoxLayout(pext, BoxLayout.Y_AXIS));
        // pext.setLayout(new FlowLayout());

        pext.add(createTF(tfeditor, btneditor, "editor"));
        pext.add(createTF(tfgs, btngs, "gs"));

        pext.add(createTF(tfmpi, btnmpi, "mpirun"));

        if (pm == null) {
            pm = PropertiesManager
                    .getGlobalProperties(PropertiesManager.PROPERTIES_PVIEWER);
        }
        boolean mpiEnable = Boolean.valueOf(pm.getProperty("mpienable"))
                .booleanValue();
        tfmpi.setEnabled(mpiEnable);
        btnmpi.setEnabled(mpiEnable);

        // pext.add(createTF(tfemacs, btnemacs, "emacs"));
        // pext.add(createTF(tfperl, btnperl, "perl"));

        pext.add(createTF(tfbrowser, btnbrowser, "browser"));
        // pext.add(createTF(tfBSV, btnBSV, "BioStationViewer"));

        return pext;
    }

    /** create panel for PHASE-Viewer program path */
    private JPanel createPanelPHASEViewer() {
        JPanel pchase = new JPanel();
        pchase.setLayout(new BoxLayout(pchase, BoxLayout.Y_AXIS));
        // pchase.setLayout(new FlowLayout());

        pchase.add(createTF(tfchasedir, btnchasedir, "chase directory"));
        pchase.add(createTF(tfphasedir, btnphasedir, "phase directory"));

        pchase.add(Box.createVerticalStrut(180));

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

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

        return pchase;
    }

    /** create panel for buttons */
    private JPanel createButtonPanel() {
        JPanel pbtn = new JPanel();
        pbtn.setLayout(new FlowLayout());

        btnsave = new JButton("save");
        btnsaveclose = new JButton("save & close");
        btnclose = new JButton("close");

        pbtn.add(btnsave);
        pbtn.add(btnsaveclose);
        pbtn.add(btnclose);

        return pbtn;
    }

    /**
     * パス設定用のテキストフィールドを作成する. テキストフィールドの他, ディレクトリーやファイルを
     * 選択するためのファイルチューザー起動用のボタンも配備される.
     * 
     * @param tf
     *            作成したいテキストフィールド.
     * @param btn
     *            ファイルチューザー起動用のボタン.
     * @param title
     *            この領域のタイトル.
     * @return テキストフィールドとボタンの配備されたパネル.
     */
    public JPanel createTF(JTextField tf, JButton btn, String title) {
        JPanel p = new JPanel();
        p.setBorder(new TitledBorder(title));
        p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
        p.add(tf);
        p.add(btn);
        tf.setEditable(true);
        tf.setBackground(Color.lightGray.brighter());
        return p;
    }

    /**
     * パス設定用のテキストフィールドを作成する. テキストフィールドのみ.
     * 
     * @param tf
     *            作成したいテキストフィールド.
     * @param title
     *            テキストフィールドに付加したいタイトル.
     * @return タイトル付きのテキストフィールドの配備されたパネル.
     */
    public JPanel createTFonly(JTextField tf, String title) {
        JPanel p = new JPanel();
        p.setBorder(new TitledBorder(title));
        p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
        p.add(tf);
        tf.setEditable(true);
        tf.setBackground(Color.lightGray.brighter());

        return p;
    }

    private void addListenersAll() {

        btnclose.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                dispose();
            }
        });

        btnsaveclose.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                saveProperties();
                dispose();
            }
        });

        btnsave.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                saveProperties();
                dispose();
            }
        });

        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);
            }
        });

        /*
         * btnperl.addActionListener(new ActionListener() { public void
         * actionPerformed(ActionEvent e) { bootFileChooser(tfperl, 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 void setTextFromPM() {
        tfeditor.setText(pm.getProperty("editor"));
        tfgs.setText(pm.getProperty("gs"));
        tfmpi.setText(pm.getProperty("mpirunpath"));
        tfperl.setText(pm.getProperty("perl"));
        tfbrowser.setText(pm.getProperty("browser"));

        tfphasedir.setText(pm.getProperty("phasedir"));
        tfchasedir.setText(System.getProperty("pviewer.home"));
        tfBSV.setText(pm.getProperty("BioStationViewer"));
    }

    private void saveProperties() {
        pm.setProperty("editor", tfeditor.getText());
        pm.setProperty("gs", tfgs.getText());
        pm.setProperty("mpirunpath", tfmpi.getText());
        pm.setProperty("perl", tfperl.getText());
        pm.setProperty("browser", tfbrowser.getText());
        pm.setProperty("phasedir", tfphasedir.getText());
        pm.setProperty("chasedir", tfchasedir.getText());
        pm.setProperty("BioStationViewer", tfBSV.getText());
        pm.storeProperty();
    }

    private void bootFileChooser(JTextField tf, int mode) {
        // InternalFileChooser fdlg = new InternalFileChooser();
        ChaseFileChooser fdlg = new ChaseFileChooser(ChaseFileChooser.path);
        fdlg.setDialogType(JFileChooser.CUSTOM_DIALOG);
        fdlg.setDialogTitle("choose");
        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(cont, "Select") != JFileChooser.APPROVE_OPTION) {
            return;
        }

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

    // public void approvedSelection(InternalFileChooser source) {
    // tf.setText(source.getSelectedFile().getAbsolutePath());
    // }

}
