/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on ----
!  AUTHOR(S): KOGA, Junichiro
!  File : BandPlPanel.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.plugins.projectmanipulator.phase.resultsviewerpanel.tools;

import java.awt.GridLayout;
import java.io.File;

import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

import org.apache.log4j.Logger;

import ciss.phase_viewer.common.ChaseFileChooser;
import ciss.phase_viewer.common.ChoicePanel;
import ciss.phase_viewer.common.ExternalProgramPanel;
import ciss.phase_viewer.common.InputPanel;
import ciss.phase_viewer.common.MyMessageBox;
import ciss.phase_viewer.common.Utils;
import ciss.phase_viewer.mainpanel.Desk;
import ciss.phase_viewer.settings.GlobalProperties;
import ciss.phase_viewer.settings.PropertiesManager;

public class BandPlPanel extends ExternalProgramPanel {
    private Logger logger = Logger.getLogger(BandPlPanel.class.getName());

    /** project directory */
    private String projdir;

    /** name of energy.data */
    private String energData = "nfenergy.data";

    /** name of kpoint.in */
    private String kpointIn = "bandkpt.in";

    private String kpointInDir;

    private InputPanel iperangemin;

    private InputPanel iperangemax;

    private InputPanel ipeinc;

    private ChoicePanel cpPlotType;

    private JCheckBox cbwithfermi;

    private JCheckBox cbcolor;

    private InputPanel ipwidth;

    private boolean kpointInExists = true;

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

    private MyMessageBox mbox = new MyMessageBox();

    /**
     * このパネルのタイトルを引数としたコンストラクター.
     * 
     * @param title
     *            このパネルの上部に表示される文字列を指定
     * @param dir
     *            作業ディレクトリー
     * @param energData
     *            対象となるF_ENERGファイルのファイル名
     */
    public BandPlPanel(String title, String dir, String energData) {
        super(title, new java.awt.Dimension(500, 200));
        this.kpointInDir = dir;
        this.projdir = dir;
        setCurrDir(projdir);
        this.energData = energData;

        if (!(new File(kpointInDir + System.getProperty("file.separator")
                + kpointIn)).exists()) {
            // allow user to select band_kpoint.in file
            Object[] init = { "specify input file", "quit" };
            int ret = JOptionPane.showInternalOptionDialog(Desk.getDesktop(),
                    "couldn't find input file for band_kpoint.pl!", "warning",
                    JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
                    null, init, init[0]);
            if (ret == JOptionPane.YES_OPTION) {
                ChaseFileChooser fdlg = new ChaseFileChooser(
                        ChaseFileChooser.base, true);
                fdlg.setDialogType(JFileChooser.CUSTOM_DIALOG);
                fdlg.setDialogTitle("Open");
                fdlg.setCurrentDirectory(new File(dir));
                fdlg.setFileSelectionMode(JFileChooser.FILES_ONLY);
                if (fdlg.showDialog(this, "open") != JFileChooser.APPROVE_OPTION) {
                    System.out
                            .println("no specification for bandkpoint.in ...");
                    return;
                } else {
                    String kpointInPath = fdlg.getSelectedFile()
                            .getAbsolutePath();
                    kpointIn = new File(kpointInPath).getName();
                    kpointInDir = new File(kpointInPath).getParent();
                }
            } else {
                logger.error("no specification for bandkpoint.in ...");
                kpointInExists = false;
                dispose();
            }
        }

    }

    /**
     * perlスクリプト実行用の文字列を作成するクラス. まずカレントディレクトリーの書き込み許可の有無を調べ,
     * 書き込める場合はパネルに入力された情報を元に実行用の文字列を作成する. この際, Windowsと他のOSで扱いが異なる点に注意.
     * Windowsの場合#!/usr/bin/perlなどとファイルの先頭に書いても executableにはならないようなので,
     * 直接perlインタープリターを 呼ぶことによって実現している.
     * 
     * @return 成功の場合真を返す. band.plが見つからない, などの事情がある場合は falseを返す.
     */
    public boolean createExeString() {
        // String exeString = getExeString();
        if (!kpointInExists) {
            return false;
        }

        GlobalProperties pm = PropertiesManager
                .getGlobalProperties(PropertiesManager.PROPERTIES_PVIEWER);
        String curDir = System.getProperty("user.dir");
        if (!(new File(curDir)).canWrite()) {
            mbox.setText("can't create tmp file ... check permission.");
            return false;
        }

        String bandpl = System.getProperty("pviewer.home") + FS
                + pm.getProperty("phasetoolsdir") + FS + "band.pl";
        logger.debug("bandpl: " + bandpl);
        if (!((new File(bandpl)).exists())) {
            exeString = "band.pl";
            mbox.setText("could not find band.pl");
            return false;
        }

        if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
            bandpl = "perl.exe " + Utils.getPathDQ(bandpl);
        }

        exeString = bandpl
                + " "
                + Utils.getPathDQ(projdir
                        + System.getProperty("file.separator") + energData)
                + " "
                + Utils.getPathDQ(kpointInDir
                        + System.getProperty("file.separator") + kpointIn)
                + " ";

        /* set options */
        String erangemin = iperangemin.getValue();
        String erangemax = iperangemax.getValue();
        String einc = ipeinc.getValue();
        String plotType = cpPlotType.getChoice();
        boolean fermi = cbwithfermi.isSelected();
        boolean color = cbcolor.isSelected();
        String width = ipwidth.getValue();

        if (erangemin.trim().length() != 0 && erangemax.trim().length() != 0) {
            exeString = exeString + " -erange=" + erangemin + "," + erangemax;
        }
        if (einc.trim().length() != 0) {
            exeString = exeString + " -einc=" + einc;
        }
        if (plotType.trim().length() != 0) {
            exeString = exeString + " -ptype=" + plotType;
        }
        if (fermi) {
            exeString = exeString + " -with_fermi";
        }
        if (width.trim().length() != 0) {
            exeString = exeString + " -width=" + width;
        }
        if (color) {
            exeString = exeString + " -color";
        }

        // System.out.println("exeString: "+exeString);

        // setExeString(exeString);
        logger.debug(exeString);
        return true;
    }

    /**
     * perlスクリプトを実行した後のポスト処理を行う. 具体的には, カレントディレクトリーにあるepsファイルを
     * プロジェクトディレクトリーへ移す操作を行う.
     */
    public void bootPostProcess() {
        // String moveToPath = projdir+FS+"band_structure.eps";
        // String epspath =
        // System.getProperty("user.dir")
        // + System.getProperty("file.separator")
        // + "band_structure.eps";
        // //System.out.println("epspath: "+epspath);
        // //System.out.println("moveto: "+projdir+"band_structure.eps");
        // if ( !epspath.trim().equalsIgnoreCase(moveToPath.trim()) ) {
        // ExternalProgramExecuter.remove(moveToPath);
        // }
        // try {
        // Thread.sleep(100);
        // } catch(Exception e) {
        // }
        //
        // ExternalProgramExecuter.move( epspath, moveToPath );
    }

    /**
     * このGUIの大元のパネルを作成するメソッド.
     * 
     * @return このパネルの各パーツを配備したJPanel.
     */
    public JPanel createMainPanel() {

        String[] strPlotType = { "lines", "solid_circles" };

        JPanel p = new JPanel();
        p.setLayout(new GridLayout(2, 4));
        p.setBorder(new TitledBorder("options"));

        iperangemin = new InputPanel("erange(min)", 0, 7);
        iperangemax = new InputPanel("erange(max)", 0, 7);
        ipeinc = new InputPanel("einc", 0, 7);
        // System.out.println("strPlotType: "+strPlotType[0]+" "
        // +strPlotType[1]);
        cpPlotType = new ChoicePanel("ptype", strPlotType);
        cbwithfermi = new JCheckBox("with_fermi");
        cbcolor = new JCheckBox("color");
        ipwidth = new InputPanel("width", 0, 7);

        p.add(iperangemin);
        p.add(iperangemax);
        p.add(ipeinc);
        p.add(cpPlotType);
        p.add(ipwidth);
        p.add(cbwithfermi);
        p.add(cbcolor);

        return p;
    }
}
