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

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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.JScrollPane;
import javax.swing.border.TitledBorder;

import org.apache.log4j.Logger;

import ciss.phase_viewer.inputinterface.InputInterface;
import ciss.phase_viewer.inputinterface.InputInterfaceEntry;
import ciss.phase_viewer.inputinterface.InputInterfaceEntryChangeEvent;
import ciss.phase_viewer.inputinterface.InputInterfaceEntryChangeListener;
import ciss.phase_viewer.inputinterface.inputinterfacetable.InputInterfaceTable;
import ciss.phase_viewer.mainpanel.InternalFrameChase;
import ciss.phase_viewer.plugins.projectmanipulator.phase.PhaseInputItems;
import ciss.phase_viewer.primitiveguis.AddButton;
import ciss.phase_viewer.primitiveguis.ChoicePanelPhase;
import ciss.phase_viewer.primitiveguis.DeleteButton;
import ciss.phase_viewer.primitiveguis.InputPanelPhase;
import ciss.phase_viewer.primitiveguis.PhaseInputPanelInterface;
import ciss.phase_viewer.primitiveguis.tableforinputinterface.TableForInputInterface;
import ciss.phase_viewer.projectbrowser.ProjectInfo;

/**
 * PHASEで利用するプロジェクターを編集するためのGUI.
 * 
 * @author
 */
public class ProjectorEditor extends InternalFrameChase {
    private Logger logger = Logger.getLogger(ProjectorEditor.class.getName());
    private ProjectInfo projectInfo;
    private InputInterface inputInterface;

    /** Creates a new instance of ProjectorEditor */
    public ProjectorEditor(ProjectInfo projectInfo) {
        super("configure projectors", true, true, true, true, new Dimension(
                450, 400));
        this.projectInfo = projectInfo;
        if (this.projectInfo == null)
            logger.error("project info is null!!!!");
        this.inputInterface = this.projectInfo.getInputInterface();
        JPanel p = new JPanel();
        ProjE pre = new ProjE(inputInterface);
        p.add(pre);
        getContentPane().add(p);
    }

    class ProjE extends PhaseInputItems {
        ProjE(InputInterface inputInterface) {
            super(inputInterface);
        }

        public void createGUI() {
            JPanel pproj = new JPanel();
            pproj.setLayout(new BoxLayout(pproj, BoxLayout.Y_AXIS));

            String[] dummyArray = new String[] { "" };
            JPanel pprojector_list = new JPanel();
            pprojector_list.setBorder(new TitledBorder("projector list"));
            pprojector_list.setLayout(new BoxLayout(pprojector_list,
                    BoxLayout.Y_AXIS));
            String[] spec_projector_list = new String[] { "accuracy.projector_list.projectors" };
            TableForInputInterface projector_list_table = new TableForInputInterface(
                    spec_projector_list, inputInterface, this);
            JScrollPane scr_projector_list = new JScrollPane();
            scr_projector_list.getViewport().setView(
                    projector_list_table.getPanel());
            scr_projector_list.setPreferredSize(new Dimension(400, 100));
            pprojector_list.add(scr_projector_list);

            // InputPanelPhase ippno = new
            // InputPanelPhase(dummyArray,inputInterface,"no.",InputPanelPhase.NONE,5);
            InputPanelPhase ippgroup = new InputPanelPhase(dummyArray,
                    inputInterface, "group", InputPanelPhase.NONE, 5);
            InputPanelPhase ippradius = new InputPanelPhase(dummyArray,
                    inputInterface, "radius", InputPanelPhase.NONE, 5);
            ChoicePanelPhase cppl = new ChoicePanelPhase(dummyArray,
                    inputInterface, "l (0: s, 1:p, 2:d, 3: f)", new String[] {
                            "0", "1", "2", "3" });
            ChoicePanelPhase cppt = new ChoicePanelPhase(dummyArray,
                    inputInterface, "t (1 or 2)", new String[] { "1", "2" });
            JPanel p_new_projector1 = new JPanel();
            p_new_projector1.setBorder(new TitledBorder("new projector"));
            p_new_projector1.setLayout(new GridLayout(1, 3));
            // p_new_projector1.add(ippno);
            p_new_projector1.add(ippgroup);
            p_new_projector1.add(ippradius);
            p_new_projector1.add(cppl);
            p_new_projector1.add(cppt);

            PhaseInputPanelInterface[] projector_list_guis = { null, ippgroup,
                    ippradius, cppl, cppt };
            AddButton add_projector_list = new AddButton(projector_list_table,
                    projector_list_guis, this);
            DeleteButton delete_projector_list = new DeleteButton(
                    projector_list_table, this);
            JButton projector_list_from_file = new JButton("from file");
            projector_list_from_file.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ae) {
                    fromFile("accuracy.projector_list", "projectors");
                }
            });

            JPanel p_new_projector = new JPanel();
            p_new_projector.setLayout(new BoxLayout(p_new_projector,
                    BoxLayout.X_AXIS));
            p_new_projector.add(add_projector_list);
            p_new_projector.add(delete_projector_list);
            p_new_projector.add(projector_list_from_file);

            JPanel p_assign = new JPanel();
            p_assign.setLayout(new BoxLayout(p_assign, BoxLayout.Y_AXIS));
            p_assign.setLayout(new GridBagLayout());
            GridBagConstraints gc = new GridBagConstraints();
            gc.fill = GridBagConstraints.HORIZONTAL;
            gc.gridwidth = GridBagConstraints.REMAINDER;
            gc.weightx = 1.0;
            p_assign.setBorder(new TitledBorder("assign projector"));

            inputInterface.selectRoot();
            inputInterface.selectBlock("accuracy.projector_list.projectors");
            InputInterfaceTable tableproj = inputInterface.getTable();
            Vector projData = tableproj.getTableData();
            int grind = tableproj.getIndexFor("group");
            Vector distinctGroups = new Vector();

            int[] gr = getDistinctGroups();
            String[] ele = getElements();
            for (int i = 0; i < ele.length; i++) {
                PA pa = new PA(ele[i], gr);
                inputInterface.addInputInterfaceEntryChangeListener(pa);
                gc.gridx = 0;
                gc.gridy = i;
                p_assign.add(pa, gc);
            }

            inputInterface.selectRoot();
            JScrollPane scp = new JScrollPane(p_assign);
            scp.setPreferredSize(new Dimension(400, 100));
            pproj.add(pprojector_list);
            pproj.add(p_new_projector1);
            pproj.add(p_new_projector);
            pproj.add(scp);

            JButton dismiss = new JButton("dismiss");
            dismiss.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    dispose();
                }
            });
            pproj.add(dismiss);

            add(pproj);
        }

        private int[] getDistinctGroups() {
            inputInterface.selectRoot();
            inputInterface.selectBlock("accuracy.projector_list.projectors");
            InputInterfaceTable tableproj = inputInterface.getTable();
            Vector projData = tableproj.getTableData();
            int grind = tableproj.getIndexFor("group");
            Vector distinctGroups = new Vector();
            for (int i = 0; i < projData.size(); i++) {
                try {
                    Integer inte = new Integer(
                            Integer.parseInt(((String[]) projData.get(i))[grind]));
                    if (distinctGroups.indexOf(inte) < 0)
                        distinctGroups.add(inte);
                } catch (Exception exc) {
                }
            }
            int[] gr = new int[distinctGroups.size() + 1];
            gr[0] = 0;
            for (int i = 0; i < distinctGroups.size(); i++) {
                gr[i + 1] = ((Integer) distinctGroups.get(i)).intValue();
            }
            inputInterface.selectRoot();
            return gr;
        }

        private String[] getElements() {
            inputInterface.selectRoot();
            inputInterface.selectBlock("structure.element_list");
            InputInterfaceTable tableelem = inputInterface.getTable();
            Vector eleData = tableelem.getTableData();
            int grind = tableelem.getIndexFor("element");
            String[] ret = new String[eleData.size()];
            for (int i = 0; i < ret.length; i++) {
                ret[i] = ((String[]) eleData.get(i))[grind];
            }
            inputInterface.selectRoot();
            return ret;
        }

        class PA extends JPanel implements InputInterfaceEntryChangeListener {
            private JLabel element;
            private JComboBox projGroup;
            private String elemName;

            PA(String elemName, int[] groupCandidate) {
                setLayout(new GridLayout(1, 2));
                element = new JLabel(elemName);
                this.elemName = elemName;
                String[] groups = new String[groupCandidate.length];
                for (int i = 0; i < groups.length; i++) {
                    groups[i] = String.valueOf(groupCandidate[i]);
                }
                JPanel jg = new JPanel();
                projGroup = new JComboBox(groups);
                jg.add(projGroup);
                add(element);
                add(projGroup);
                int proj = getProjGroup(elemName);
                projGroup.setSelectedItem(String.valueOf(proj));
                projGroup.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        applyProj();
                    }
                });
            }

            private int getProjGroup(String elementName) {
                int ret = 0;
                inputInterface.selectRoot();
                inputInterface.selectBlock("structure.atom_list.atoms");
                InputInterfaceTable tableatom = inputInterface.getTable();
                Vector atdata = tableatom.getTableData();
                int ind = tableatom.getIndexFor("element");
                int ind_proj = tableatom.getIndexFor("proj_group");
                if (ind_proj >= 0) {
                    for (int i = 0; i < atdata.size(); i++) {
                        String[] dat = (String[]) atdata.get(i);
                        if (dat[ind].equalsIgnoreCase(elementName)) {
                            try {
                                ret = Integer.parseInt(dat[ind_proj]);
                                break;
                            } catch (Exception exc) {
                            }
                        }
                    }
                }
                inputInterface.selectRoot();
                return ret;
            }

            private void applyProj() {
                if (projGroup.getSelectedItem() == null)
                    return;
                inputInterface.selectRoot();
                inputInterface.selectBlock("structure.atom_list.atoms");
                InputInterfaceTable tableatom = inputInterface.getTable();
                Vector atdata = tableatom.getTableData();
                int ind = tableatom.getIndexFor("element");
                int ind_proj = tableatom.getIndexFor("proj_group");
                String[] idents = tableatom.getColumnIdentifiers();
                int numcol = idents.length;
                for (int i = 0; i < atdata.size(); i++) {
                    String[] data = (String[]) atdata.get(i);
                    if (data[ind].equalsIgnoreCase(elemName)) {
                        String[] foo = new String[data.length];
                        for (int j = 0; j < data.length; j++)
                            foo[j] = data[j];
                        foo[ind_proj] = projGroup.getSelectedItem().toString();
                        tableatom.replaceTableDataRow(foo, i);
                    }
                }
                inputInterface.selectRoot();
            }

            public void inputInterfaceEntryChanged(
                    InputInterfaceEntryChangeEvent e) {
                if (e.getSource() == this
                        || e.getEntry().getEntryType() != InputInterfaceEntry.TABLE
                        || !e.getTag().equalsIgnoreCase(
                                "accuracy.projector_list.projectors"))
                    return;
                ActionListener[] al = projGroup.getActionListeners();
                Object o = projGroup.getSelectedItem();
                for (int i = 0; i < al.length; i++)
                    projGroup.removeActionListener(al[i]);
                int[] gr = getDistinctGroups();
                projGroup.removeAllItems();
                String[] groups = new String[gr.length];
                for (int i = 0; i < groups.length; i++) {
                    groups[i] = String.valueOf(gr[i]);
                    projGroup.addItem(groups[i]);
                }
                projGroup.setSelectedItem(o);
                for (int i = 0; i < al.length; i++)
                    projGroup.addActionListener(al[i]);
            }

            public void inputInterfaceInitializing() {
            }

            public void inputInterfaceInitialized() {
            }
        }
    }

}
