/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on 2006/06/22, 17:57
!  AUTHOR(S): KOGA, Junichiro
!  File : NfEnfMonitor.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.file;

import java.awt.Dimension;
import java.util.Vector;

import org.jfree.chart.axis.AxisLocation;

import ciss.phase_viewer.file.ChaseFile;
import ciss.phase_viewer.file.SimpleMonitor;
import ciss.phase_viewer.graph.GraphPanel;
import ciss.phase_viewer.graph.SimpleChart;
import ciss.phase_viewer.graph.XYData;
import ciss.phase_viewer.projectbrowser.ProjectInfo;

/**
 * F_ENFファイルをモニターするクラス.
 * 
 * @author
 */
public class NfEnfMonitor extends SimpleMonitor {
    private org.apache.log4j.Logger logger = org.apache.log4j.Logger
            .getLogger(NfEnfMonitor.class.getName());

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

    /*
     * (non-Javadoc)
     * 
     * @see ciss.phase_viewer.file.SimpleMonitor#getFileToMonitor()
     */
    protected String getFileToMonitor() {
        return getChaseFile().getFileName();
    }

    public ChaseFile getChaseFile() {
        ChaseFile cf = projectInfo.getChaseFileManager().getFile("F_ENF");
        return cf;
    }

    private String chartTitle = "";

    /*
     * (non-Javadoc)
     * 
     * @see ciss.phase_viewer.file.SimpleMonitor#doGraph(java.lang.String[])
     */
    protected void doGraph(String[] lines) {
        if (lines == null || lines.length == 0)
            return;

        boolean md = false;
        Vector dataVector = new Vector();
        // etotal, 2: forcmx
        for (int i = 0; i < lines.length; i++) {
            logger.debug(lines[i]);
            String line = lines[i].trim();
            String[] ar = line.split("\\s+");
            try {
                Integer.parseInt(ar[0]);
            } catch (NumberFormatException e) {
                continue;
            }

            if (ar.length < 4)
                continue;

            if (ar.length > 4)
                md = true;

            if (!md) {
                try {
                    double[] tmp = new double[3];
                    tmp[0] = Double.parseDouble(ar[0]);
                    tmp[1] = Double.parseDouble(ar[2]);
                    tmp[2] = Double.parseDouble(ar[3]);
                    dataVector.add(tmp);
                } catch (NumberFormatException nfe) {
                    continue;
                }
            } else {
                try {
                    double[] tmp = new double[4];
                    tmp[0] = Double.parseDouble(ar[0]);
                    tmp[1] = Double.parseDouble(ar[2]);
                    tmp[2] = Double.parseDouble(ar[3]);
                    tmp[3] = Double.parseDouble(ar[4]);
                    dataVector.add(tmp);
                } catch (NumberFormatException nfe) {
                    continue;
                }
            }
        }

        if (dataVector.size() == 0 && !isGraphCreatable(textArea))
            return;

        if (!md) {
            if (xyData == null) {
                xyData = new XYData[2];
                xyData[0] = new XYData("energy");
                xyData[0].collectionIndex = 0;
                xyData[0].xAxisName = "iteration";
                xyData[0].xValType = XYData.INTEGER;
                xyData[0].yAxisName = "energy (hartree)";

                xyData[1] = new XYData("force");
                xyData[1].collectionIndex = 1;
                xyData[1].xAxisName = "iteration";
                xyData[1].xValType = XYData.INTEGER;
                xyData[1].yAxisName = "max. force (hartree/bohr)";
                xyData[1].yAxisLocation = AxisLocation.BOTTOM_OR_RIGHT;
                chartTitle = "structural optimization";
            }

            double[][] inidata = new double[dataVector.size()][];
            dataVector.copyInto(inidata);
            for (int i = 0; i < inidata.length; i++) {
                xyData[0].add(inidata[i][0], inidata[i][1]);
                xyData[1].add(inidata[i][0], inidata[i][2]);
            }

        } else {
            if (xyData == null) {
                xyData = new XYData[3];
                xyData[0] = new XYData("tot. energy");
                xyData[0].collectionIndex = 0;
                xyData[0].xAxisName = "iteration";
                xyData[0].yAxisName = "internal and total energy (hartree)";
                xyData[0].xValType = XYData.INTEGER;

                xyData[1] = new XYData("constant of motion");
                xyData[1].xValType = XYData.INTEGER;
                xyData[1].collectionIndex = 0;
                xyData[1].yAxisName = "internal and total energy (hartree)";

                xyData[2] = new XYData("kinetic energy");
                xyData[2].xValType = XYData.INTEGER;
                xyData[2].collectionIndex = 1;
                xyData[2].yAxisName = "kinetic energy (hartree)";
                xyData[2].yAxisLocation = AxisLocation.BOTTOM_OR_RIGHT;

                chartTitle = "molecular dynamics";
            }
            double[][] inidata = new double[dataVector.size()][];
            dataVector.copyInto(inidata);
            try {
                for (int i = 0; i < inidata.length; i++) {
                    xyData[0].add(inidata[i][0], inidata[i][1]);
                    xyData[1].add(inidata[i][0], inidata[i][3]);
                    xyData[2].add(inidata[i][0], inidata[i][2]);
                }
            } catch (ArrayIndexOutOfBoundsException aiob) {
                aiob.printStackTrace();
            }
        }

        if (!graph)
            return;

        if (graphPanel == null) {
            SimpleChart simpleChart = new SimpleChart(xyData);
            simpleChart.setSize(new Dimension(512, 400));
            simpleChart.setTitle("monitoring " + fileName);
            simpleChart.setChartTitle(chartTitle);
            simpleChart.setChartProgressListener(this);
            graphPanel = new GraphPanel(simpleChart);
            graphPanel.addInternalFrameListener(this);
        }
        if (!graphPanel.isVisible())
            graphPanel.setVisible(true);
    }

}
