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

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

import org.apache.log4j.Logger;

import ciss.phase_viewer.input.InputWizard;
import ciss.phase_viewer.input.InputWizardController;
import ciss.phase_viewer.inputinterface.DataManager;
import ciss.phase_viewer.inputinterface.Input;
import ciss.phase_viewer.inputinterface.InputInterface;
import ciss.phase_viewer.inputinterface.InputInterfacePrimitiveEntry;
import ciss.phase_viewer.inputinterface.inputinterfacetable.InputInterfaceTable;
import ciss.phase_viewer.mainpanel.InternalFrameChase;
import ciss.phase_viewer.plugins.projectmanipulator.phase.PhaseConstants;
import ciss.phase_viewer.plugins.projectmanipulator.phase.preparationpanel.CmixPanelPanel;
import ciss.phase_viewer.plugins.projectmanipulator.phase.preparationpanel.SolverPanelPanel;

/**
 * 波動関数ソルバーと電荷密度混合法用のWizard
 * 
 * @author
 */
public class SolverAndCmixWiz implements InputWizard {
    private Logger logger = Logger.getLogger(SolverAndCmixWiz.class.getName());
    private JPanel panel;
    private InputInterface input;

    /** Creates a new instance of SolverAndCmixWiz */
    public SolverAndCmixWiz() {
    }

    public String process() {
        input.swapBlock(InputInterface.__ROOT__, "wavefunction_solver",
                inputFrom[combo.getSelectedIndex()]);
        input.swapBlock(InputInterface.__ROOT__, "charge_mixing",
                inputFrom[combo.getSelectedIndex()]);
        return "configured solver settings and cmix methods.";
    }

    public void setInput(Input input) {
        this.input = (InputInterface) input;
    }

    public boolean hasPrevious() {
        return true;
    }

    public boolean hasNext() {
        return true;
    }

    public boolean hasFinished() {
        return true;
    }

    public String getName() {
        return "solver and charge mixing";
    }

    public JPanel getGUI() {
        if (panel == null) {
            createGUI();
        }
        return panel;
    }

    private JComboBox combo;
    private String[] type = { "slow", "moderate", "fast" };

    private void createGUI() {
        combo = new JComboBox(type);
        combo.setSelectedIndex(1);
        JButton btn = new JButton("configure");
        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
        JPanel p1 = new JPanel();
        // p1.setBorder(new TitledBorder("solver and cmix type"));
        p1.add(combo);
        JPanel p2 = new JPanel();
        p2.add(btn);
        panel.add(p1);
        panel.add(p2);
        btn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    SubPanel pane = new SubPanel(inputFrom[combo
                            .getSelectedIndex()]);
                } catch (Exception exc) {
                    exc.printStackTrace();
                }
            }
        });
    }

    class SubPanel extends InternalFrameChase {
        private InputInterface inp;

        SubPanel(InputInterface inp) {
            super("configure solver and charge-mixing methods", true, true,
                    true, true, new Dimension(530, 530));
            this.inp = inp;
            JPanel foo = new JPanel();
            JTabbedPane pane = new JTabbedPane();
            JPanel psol = new JPanel();
            psol.setLayout(new BorderLayout());
            JPanel sol = new SolverPanelPanel(inp);
            psol.add(sol, BorderLayout.NORTH);
            JPanel cmix = new CmixPanelPanel(inp);
            JPanel pcmix = new JPanel();
            pcmix.setLayout(new BorderLayout());
            pcmix.add(cmix, BorderLayout.NORTH);
            pane.addTab("solver", psol);
            pane.addTab("charge mixing", pcmix);
            foo.add(pane);
            JButton btn = new JButton("OK");
            JPanel pbtn = new JPanel();
            pbtn.add(btn);
            getContentPane().setLayout(
                    new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
            getContentPane().add(foo);
            getContentPane().add(pbtn);
            btn.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    dispose();
                }
            });
        }
    }

    public String getDescription() {
        return "edit configurations for solvers and charge mixing methods.";
    }

    private boolean metallic = false;
    private boolean spin = false;
    int numCand = 3;
    private InputInterface[] inputFrom = new InputInterface[numCand];

    public void setProperties(HashMap properties) {
        try {
            metallic = new Boolean(properties.get("metallic").toString())
                    .booleanValue();
        } catch (Exception exc) {
        }
        try {
            spin = new Boolean(properties.get("spin").toString())
                    .booleanValue();
        } catch (Exception ex) {
        }
        java.net.URL definputFile = getClass()
                .getResource(
                        "/ciss/phase_viewer/plugins/projectmanipulator/phase/defaultSolverAndCmix.data");
        String definput = definputFile.getFile();
        logger.debug("definput: " + definput);
        for (int i = 0; i < numCand; i++) {
            DataManager man = new DataManager(definput,
                    PhaseConstants.TABLESPEC, false);
            man.parse();
            inputFrom[i] = man.getInputInterface();
            InputInterfaceTable solver = inputFrom[i]
                    .getInputInterfaceTable("wavefunction_solver.solvers");
            InputInterfaceTable cmix = inputFrom[i]
                    .getInputInterfaceTable("charge_mixing.mixing_methods");
            // if (metallic) {
            // int rmxsInd = cmix.getIndexFor("rmxs");
            // int rmxeInd = cmix.getIndexFor("rmxe");
            // Vector vec = cmix.getTableData();
            // String[] dat = (String[]) vec.get(0);
            // dat[rmxsInd] = "0.2";
            // dat[rmxeInd] = "0.2";
            // }
            if (spin) {
                int rmxsInd = cmix.getIndexFor("rmxs");
                int rmxeInd = cmix.getIndexFor("rmxe");
                Vector vec = cmix.getTableData();
                String[] dat = (String[]) vec.get(0);
                dat[rmxsInd] = "0.1";
                dat[rmxeInd] = "0.1";
            }
            configInitialSolAndCmix(inputFrom[i], i);
        }
    }

    private void configInitialSolAndCmix(InputInterface inp, int i) {
        InputInterfaceTable solver = inp
                .getInputInterfaceTable("wavefunction_solver.solvers");
        InputInterfaceTable cmix = inp
                .getInputInterfaceTable("charge_mixing.mixing_methods");
        String[] soldata = (String[]) solver.getTableData().get(0);
        String[] cmixdata = (String[]) cmix.getTableData().get(0);
        int solmethodind = solver.getIndexFor("sol");
        int till_nind = solver.getIndexFor("till_n");
        int cmixmethodind = cmix.getIndexFor("method");

        if (i == 0) {
            soldata[solmethodind] = "mddavidson";
            soldata[solver.getIndexFor("prec")] = "on";
            soldata[solver.getIndexFor("submat")] = "on";
        } else if (i == 1) {
            String[] rmm3 = { "rmm3", "-1", "on", "1", "on" };
            // String [] methodident =
            // {"sol","till_n","dts","dte","itr","var","prec","cmix","submat"};
            // String [] pulay = {"1","pulay",
            // cmixdata[cmix.getIndexFor("rmxs")],cmixdata[cmix.getIndexFor("rmxe")],
            // cmixdata[cmix.getIndexFor("itr")],cmixdata[cmix.getIndexFor("var")],
            // cmixdata[cmix.getIndexFor("prec")],cmixdata[cmix.getIndexFor("istr")],
            // cmixdata[cmix.getIndexFor("nbmix")],cmixdata[cmix.getIndexFor("update")]};
            soldata[till_nind] = "2";
            solver.replaceTableDataRow(rmm3, 1);
        } else if (i == 2) {
            String[] rmm3 = { "rmm3", "-1", "on", "1", "on" };
            // String [] methodident =
            // {"sol","till_n","dts","dte","itr","var","prec","cmix","submat"};
            // String [] pulay = {"1","pulay",
            // cmixdata[cmix.getIndexFor("rmxs")],cmixdata[cmix.getIndexFor("rmxe")],
            // cmixdata[cmix.getIndexFor("itr")],cmixdata[cmix.getIndexFor("var")],
            // cmixdata[cmix.getIndexFor("prec")],cmixdata[cmix.getIndexFor("istr")],
            // cmixdata[cmix.getIndexFor("nbmix")],cmixdata[cmix.getIndexFor("update")]};
            soldata[till_nind] = "2";
            solver.replaceTableDataRow(rmm3, 1);
            // cmix.replaceTableDataRow(pulay,1);
            InputInterfacePrimitiveEntry tormm = inp
                    .getInputInterfacePrimitiveEntry("wavefunction_solver.rmm.edelta_change_to_rmm");
            tormm.setValue("0.01");
        }
    }

    public void setParent(InputWizardController parent) {
    }

}
