/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2006/10/06, 14:56
!  AUTHOR(S): KOGA, Junichiro
!  File : WorkFuncPanel.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;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

import org.apache.log4j.Logger;

import ciss.phase_viewer.acviewer.ACVCaller;
import ciss.phase_viewer.acviewer.ACVData;
import ciss.phase_viewer.atomcoord.AtomCoords;
import ciss.phase_viewer.atomcoord.Cube2AtomCoords;
import ciss.phase_viewer.atomcoord.VolumetricData;
import ciss.phase_viewer.common.CoordsViewerBooter;
import ciss.phase_viewer.common.MyThread;
import ciss.phase_viewer.common.MyThreadListener;
import ciss.phase_viewer.common.StringConstants;
import ciss.phase_viewer.inputinterface.DataManager;
import ciss.phase_viewer.outputinterface.OutputParser;
import ciss.phase_viewer.outputinterface.OutputParserListener;
import ciss.phase_viewer.plugins.projectmanipulator.phase.PhaseConstants;
import ciss.phase_viewer.projectbrowser.ProjectInfo;
import ciss.phase_viewer.projectbrowser.ProjectManipulator;

/**
 * 仕事関数解析用のGUI
 */
public class WorkFuncPanel extends ProjectManipulator {
    private Logger logger = Logger.getLogger(WorkFuncPanel.class.getName());

    /** Creates a new instance of WorkFuncPanel */
    public WorkFuncPanel(ProjectInfo projectInfo) {
        super(projectInfo);
    }

    public void initializeProject() {
    }

    public void init() {
        removeAll();
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        add(new WorkFuncPanelPanel());
    }

    private String nfvlc = "nfvlc.data";
    private String nfcntn = "continue_bin_stm.data";

    private String vlcav = "nfvlcr_av.data";
    private String vlcr = "nfvlcr.cube";

    private File nfvlcFile;
    private File nfcntnFile;
    private File vlcavFile;
    private File vlcrFile;
    private OutputParser parser;

    class WorkFuncPanelPanel extends JPanel implements ACVCaller,
            OutputParserListener, MyThreadListener {
        WorkFuncPanelPanel() {
            setLayout(new BorderLayout());
            nfvlcFile = new File(projectInfo.getProjectDirectory() + FS + nfvlc);
            nfcntnFile = new File(projectInfo.getProjectDirectory() + FS
                    + nfcntn);
            vlcavFile = new File(projectInfo.getProjectDirectory() + FS + vlcav);
            vlcrFile = new File(projectInfo.getProjectDirectory() + FS + vlcr);
            init();

            if (vlcavFile.exists()) {
                if (parser == null) {
                    parser = projectInfo.getOutputInterface().getParser(
                            "F_VLCRAV", this);
                }
                parser.setParsed(false);
                parser.doParse();
            }
        }

        private JPanel pres;

        private void addVLCAVPanel() {
            pres.add(createVLCAVPanel());
        }

        private void init() {
            removeAll();
            try {
                JPanel pp = new JPanel();
                pp.add(createRunWFPanel());
                add(pp, BorderLayout.NORTH);
                pres = new JPanel();
                pres.setLayout(new BoxLayout(pres, BoxLayout.Y_AXIS));
                JPanel p = new JPanel();
                p.add(createViewVLCRPanel());
                pres.add(p);
                // pres.add(createVLCAVPanel());
                add(pres, BorderLayout.CENTER);

                revalidate();
            } catch (Exception exc) {
                exc.printStackTrace();
            }
        }

        private JComboBox axisCombo;

        public void done() {
            logger.info("... done.");
            init();
            if (vlcavFile.exists()) {
                if (parser == null) {
                    parser = projectInfo.getOutputInterface().getParser(
                            "F_VLCRAV", this);
                }
                parser.setParsed(false);
                parser.doParse();
            }
        }

        private String[] axisChoice = { "               x               ",
                "               y               ",
                "               z               " };
        private JComboBox spinCombo;
        private String[] spinChoice = { "1", "2" };
        private JButton runWFButton;

        private JPanel createRunWFPanel() {
            JPanel ret = new JPanel();
            ret.setBorder(new TitledBorder("run the 'workfunc' program"));
            ret.setLayout(new BoxLayout(ret, BoxLayout.X_AXIS));
            axisCombo = new JComboBox(axisChoice);
            spinCombo = new JComboBox(spinChoice);
            runWFButton = new JButton("run");
            JPanel paxis = new JPanel();
            paxis.setLayout(new BoxLayout(paxis, BoxLayout.X_AXIS));
            paxis.setBorder(new TitledBorder("select axis"));
            JPanel pspin = new JPanel();
            pspin.setLayout(new BoxLayout(pspin, BoxLayout.X_AXIS));
            pspin.setBorder(new TitledBorder("spin"));
            paxis.add(axisCombo);
            ret.add(paxis);
            ret.add(runWFButton);

            axisCombo.setSelectedIndex(2);
            spinCombo.setSelectedIndex(0);
            runWFButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    runWF();
                }
            });

            if (!(nfvlcFile.exists() && nfcntnFile.exists())) {
                axisCombo.setEnabled(false);
                spinCombo.setEnabled(false);
                runWFButton.setEnabled(false);
            }
            return ret;
        }

        private JPanel createViewVLCRPanel() {
            JPanel ret = new JPanel();
            if (!vlcrFile.exists() || vlcrFile.length() == 0L)
                return ret;
            ret.setLayout(new GridLayout());
            ret.setBorder(new TitledBorder("local potential"));
            JLabel label = new JLabel(
                    "local potential file : nfvlcr.cube      ");
            ret.add(label);
            JButton view = new JButton("view");
            ret.add(view);
            view.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    bootViewer();
                }
            });
            return ret;
        }

        private void bootViewer() {
            Cube2AtomCoords c2a = new Cube2AtomCoords(
                    vlcrFile.getAbsolutePath());
            AtomCoords coords = c2a.getAtomCoords();
            coords.getChargeDensity().setInterpolationScheme(
                    VolumetricData.LINEAR);
            Vector vec = new Vector();
            vec.addElement(coords);

            DataManager manager = new DataManager("foo",
                    PhaseConstants.TABLESPEC, false);
            manager.parse();
            ACVData acvdata = new ACVData(this, vec,
                    projectInfo.getProjectDirectory(),
                    manager.getInputInterface(), StringConstants.phase_atom_tag);
            acvdata.setFileName(vlcrFile.getAbsolutePath());
            CoordsViewerBooter cvb = new CoordsViewerBooter(acvdata, 0);
            cvb.boot();
        }

        private JPanel createVLCAVPanel() {
            if (!vlcavFile.exists() || vlcavFile.length() == 0L)
                return new JPanel();
            JPanel p = new JPanel();
            p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
            JPanel pdata = projectInfo.getOutputInterface().getDataPanel(
                    "F_VLCRAV");
            p.add(pdata);
            return p;
        }

        public void save(AtomCoords coords) {
        }

        public void parseFinished() {
            addVLCAVPanel();
        }

        private void runWF() {
            logger.info("running the 'workfunc' program");
            // String wfPath =
            // System.getProperty("pviewer.home")+FS+"bin"+FS+"wf";
            String wfPath = System.getProperty("pviewer.home") + FS + "bin"
                    + FS + "workfunc";
            if (System.getProperty("os.name").toLowerCase()
                    .startsWith("windows")) {
                wfPath += ".exe";
            }
            if (!new File(wfPath).exists()) {
                logger.error("'workfunc' program not found.");
                logger.error("put it under PHASE_VIEWER_HOME/bin");
                return;
            }
            int intaxis = axisCombo.getSelectedIndex();
            int intspin = spinCombo.getSelectedIndex();
            try {
                // PrintWriter writer = new PrintWriter(new
                // FileWriter(projectInfo.getProjectDirectory()+FS+"nfwfinp.data"));
                // String write = String.valueOf("-z "+intaxis+1);
                // //+" "+String.valueOf(intspin+1);
                wfPath = wfPath + " -z " + String.valueOf(intaxis + 1);
                // writer.println(write);
                // writer.flush();
                // writer.close();
            } catch (Exception exc) {
                exc.printStackTrace();
                logger.error("failed creation of input file for the worcfunc program.");
                return;
            }
            MyThread mt = new MyThread(wfPath, this, new File(
                    projectInfo.getProjectDirectory()));
        }

    }

}
