/*
!=======================================================================
!
!  PROGRAM  PHASE-Viewer  (PHASE-Viewer 2014.01 ver.3.3.0)
!
!  Created on ----
!  AUTHOR(S): KOGA, Junichiro
!  File : ACVEditors.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.viewer.prefs.prefseditor;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

import org.apache.log4j.Logger;

import say.swing.JFontChooser;
import ciss.phase_viewer.acviewer.ConfigDataManager;
import ciss.phase_viewer.acviewer.J3DDataManager;
import ciss.phase_viewer.acviewer.MainPanel;
import ciss.phase_viewer.atomcoord.AtomCoords;
import ciss.phase_viewer.common.ChoicePanel;
import ciss.phase_viewer.common.ConstParameters;
import ciss.phase_viewer.common.ElementDef;
import ciss.phase_viewer.common.ElementInfo;
import ciss.phase_viewer.common.InputPanel;
import ciss.phase_viewer.common.TaggedString;
import ciss.phase_viewer.primitiveguis.ColorButton;

public abstract class ACVEditors extends JPanel {
    private static Logger logger = Logger.getLogger(ACVEditors.class.getName());
    protected MainPanel mp;
    protected J3DDataManager mACVD;
    protected ConfigDataManager mCD;
    protected AtomCoords coords;

    protected DecimalFormat formater = ConstParameters.formater;

    protected double[][] Cell;

    protected double[][] Dpos;
    protected String[] elements;
    protected TaggedString[][] auxils;

    protected int NumEl;
    protected int NumAt;
    protected int NumAllAtoms; // 原子をマスクしてもデクリメントしない.

    public ACVEditors(MainPanel mp) {
        super();
        logger.debug("initializing ACVEditors ...");
        this.mp = mp;
        this.mACVD = mp.getJ3DDataManager();
        this.mCD = mp.getCD();
        this.coords = mCD.getAtomCoords();

        this.getData();

        this.createGUI();
        this.setDataToPanel();
    }

    protected void getData() {
        NumEl = mACVD.getElement().length;
        NumAt = mCD.getNumAt();
        NumAllAtoms = NumAt;
        logger.debug("NumEl, NumAt: " + NumEl + " " + NumAt);

        elements = mCD.getElements();
        Cell = mCD.getCell();
        Dpos = mCD.getPos();
        auxils = mCD.getAuxils();
    }

    protected abstract void createGUI();

    protected abstract void setDataToPanel();

    protected abstract void setDataToRepository();

    protected abstract String getTitle();
}

class PrefsEditor extends ACVEditors {
    private static Logger logger = Logger
            .getLogger(PrefsEditor.class.getName());

    private InputPanel bondfactor_ip;
    private InputPanel bondwidth_ip;

    private JCheckBox checklightbond;

    private JCheckBox drawcell_cb;
    private JCheckBox cell_is_wire;
    private InputPanel cellwidth_ip;
    private InputPanel scale_ip;
    private InputPanel scaleatom_ip;
    private InputPanel numnodesatom_ip;
    private InputPanel numnodesbond_ip;
    private InputPanel numnodescell_ip;

    private JCheckBox axis_cb;
    private JCheckBox label_cb;
    private InputPanel labeloffset_ip;

    private JCheckBox legend_cb;
    private JCheckBox mobile_cb;

    private ChoicePanel mobile_cp;

    private JButton btnFont;
    private ColorButton btnFontColor;

    private JComboBox atomRender;

    protected PrefsEditor(MainPanel mp) {
        super(mp);
    }

    private ColorButton cbbgcolor;
    private ColorButton cbbondcolor;
    private ColorButton cbcellcolor;

    protected void createGUI() {
        JPanel p = this;
        p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));

        JPanel pfont = new JPanel();
        pfont.setBorder(new TitledBorder("font"));
        btnFont = new JButton("choose...");
        btnFont.setFont(mACVD.getFont());
        pfont.add(btnFont);
        btnFontColor = new ColorButton("color");
        btnFontColor.setColor3f(mACVD.getFontColor());
        pfont.add(btnFontColor);

        JPanel pbgcolor = new JPanel();
        pbgcolor.setBorder(new TitledBorder("background color"));
        cbbgcolor = new ColorButton("choose...");
        pbgcolor.add(cbbgcolor);

        JPanel prender = new JPanel();
        prender.setBorder(new TitledBorder("render atoms by..."));
        atomRender = new JComboBox(J3DDataManager.ATOM_RENDERING_METHODS);
        prender.add(atomRender);

        JPanel pfirst = new JPanel();
        pfirst.setLayout(new BoxLayout(pfirst, BoxLayout.X_AXIS));
        pfirst.add(pfont);
        pfirst.add(pbgcolor);
        pfirst.add(prender);

        p.add(pfirst);

        cbbondcolor = new ColorButton("choose...");
        JPanel pbondcolor = new JPanel();
        pbondcolor.setBorder(new TitledBorder("bond color"));
        pbondcolor.add(cbbondcolor);

        checklightbond = new JCheckBox("");
        JPanel plightbond = new JPanel();
        plightbond.setBorder(new TitledBorder("use wire"));
        plightbond.add(checklightbond);

        JPanel pbond = new JPanel();
        JPanel pbondother = new JPanel();
        pbondother.setLayout(new GridLayout(1, 4));
        pbondother.setBorder(new TitledBorder("bond properties"));

        bondfactor_ip = new InputPanel("bond factor", 0, 7, true);
        bondwidth_ip = new InputPanel("bond width", 0, 7, true);

        pbondother.add(bondfactor_ip);
        pbondother.add(bondwidth_ip);
        pbondother.add(pbondcolor);
        pbondother.add(plightbond);

        p.add(pbondother);

        JPanel pcellandscale = new JPanel();
        pcellandscale.setLayout(new BoxLayout(pcellandscale, BoxLayout.X_AXIS));

        JPanel pcellother = new JPanel();
        pcellother.setLayout(new BoxLayout(pcellother, BoxLayout.X_AXIS));
        pcellother.setBorder(new TitledBorder("cell properties"));

        drawcell_cb = new JCheckBox("draw cell");
        cell_is_wire = new JCheckBox("use wire");
        cellwidth_ip = new InputPanel("cell width", 0, 5, true);

        cbcellcolor = new ColorButton("choose...");
        JPanel pcellcolor = new JPanel();
        pcellcolor.setBorder(new TitledBorder("cell color"));
        pcellcolor.add(cbcellcolor);

        pcellother.add(drawcell_cb);
        pcellother.add(cell_is_wire);
        pcellother.add(cellwidth_ip);
        pcellother.add(pcellcolor);

        pcellandscale.add(pcellother);

        JPanel pscale = new JPanel();
        pscale.setLayout(new GridLayout(1, 2));
        pscale.setBorder(new TitledBorder("scale"));
        scale_ip = new InputPanel("scale (system)", 0, 5, true);
        scaleatom_ip = new InputPanel("scale (atoms)", 0, 5, true);
        pscale.add(scale_ip);
        pscale.add(scaleatom_ip);

        pcellandscale.add(pscale);

        p.add(pcellandscale);

        JPanel pres = new JPanel();
        pres.setLayout(new GridLayout(1, 3));
        pres.setBorder(new TitledBorder("resolution"));
        numnodesatom_ip = new InputPanel("resolution (atom)", 0, 7, true);
        numnodesbond_ip = new InputPanel("resolution (bond)", 0, 7, true);
        numnodescell_ip = new InputPanel("resolution (cell)", 0, 7, true);
        pres.add(numnodesatom_ip);
        pres.add(numnodesbond_ip);
        pres.add(numnodescell_ip);

        p.add(pres);

        JPanel plabel = new JPanel();
        plabel.setLayout(new GridLayout(2, 2));
        plabel.setBorder(new TitledBorder("auxiliary info"));
        axis_cb = new JCheckBox("draw axis");
        plabel.add(axis_cb);
        label_cb = new JCheckBox("draw label");
        JPanel plabel_label = new JPanel();
        plabel_label.setLayout(new BoxLayout(plabel_label, BoxLayout.X_AXIS));
        plabel_label.add(label_cb);
        labeloffset_ip = new InputPanel("label offset", 0, 7, true);
        plabel_label.add(labeloffset_ip);
        plabel.add(plabel_label);
        legend_cb = new JCheckBox("draw legend");
        plabel.add(legend_cb);
        mobile_cb = new JCheckBox("mobility");
        String[] mobile_choice = { "darker", "brighter" };
        mobile_cp = new ChoicePanel("show mobile atoms", mobile_choice);
        JPanel pmobile = new JPanel();
        pmobile.setLayout(new BoxLayout(pmobile, BoxLayout.X_AXIS));
        pmobile.add(mobile_cb);
        pmobile.add(mobile_cp);
        plabel.add(pmobile);

        p.add(plabel);

        btnFont.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                mACVD.setFont(chooseFont());
                btnFont.setFont(mACVD.getFont());
            }
        });

        label_cb.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                labeloffset_ip.m_value.setEnabled(label_cb.isSelected());
            }
        });

        drawcell_cb.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                cell_is_wire.setEnabled(drawcell_cb.isSelected());
                cellwidth_ip.m_value.setEnabled(drawcell_cb.isSelected());
                cbcellcolor.setEnabled(drawcell_cb.isSelected());
            }
        });

        mobile_cb.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                mobile_cp.m_choice.setEnabled(mobile_cb.isSelected());
            }
        });

    }

    private Font chooseFont() {
        JFontChooser fontChooser = new JFontChooser();
        fontChooser.setSelectedFont(mACVD.getFont());
        int result = fontChooser.showDialog(this);
        if (result == JFontChooser.OK_OPTION) {
            Font choosedFont = fontChooser.getSelectedFont();
            return choosedFont;
        }
        return mACVD.getFont();
    }

    protected String getTitle() {
        return "Appearance";
    }

    protected void setDataToPanel() {
        cbbgcolor.setColorf(mACVD.getBgColor()[0], mACVD.getBgColor()[1],
                mACVD.getBgColor()[2]);
        cbbondcolor.setColorf(mACVD.getBondColor()[0], mACVD.getBondColor()[1],
                mACVD.getBondColor()[2]);

        bondfactor_ip.setValue(Double.toString(mACVD.getBondFactor()));
        bondwidth_ip.setValue(Double.toString(mACVD.getBondWidth()));
        checklightbond.setSelected(mACVD.getUseWireForBond());
        scale_ip.setValue(Float.toString(mACVD.getScale()));
        scaleatom_ip.setValue(Float.toString(mACVD.getScaleAtom()));

        numnodesatom_ip.setValue(Integer.toString(mACVD.getNumNodesAtom()));
        numnodesbond_ip.setValue(Integer.toString(mACVD.getNumNodesBond()));
        numnodescell_ip.setValue(Integer.toString(mACVD.getNumNodesCell()));

        drawcell_cb.setSelected(mACVD.getDrawCell());
        cell_is_wire.setSelected(mACVD.getUseWireForCell());
        cellwidth_ip.setValue(Float.toString(mACVD.getCellWidth()));
        cellwidth_ip.m_value.setEnabled(drawcell_cb.isSelected());
        cbcellcolor.setEnabled(drawcell_cb.isSelected());

        cbcellcolor.setColorf(mACVD.getCellColor()[0], mACVD.getCellColor()[1],
                mACVD.getCellColor()[2]);

        axis_cb.setSelected(mACVD.getAxis());
        label_cb.setSelected(mACVD.getText());
        labeloffset_ip.setValue(Integer.toString(mACVD.getLabelOffset()));
        labeloffset_ip.m_value.setEnabled(label_cb.isSelected());
        legend_cb.setSelected(mACVD.getLegend());
        mobile_cb.setSelected(mACVD.getMobile());
        if (mACVD.getMobilityDisplayMode() <= 1) {
            mobile_cp.m_choice.setSelectedIndex(mACVD.getMobilityDisplayMode());
        } else {
            mobile_cp.m_choice.setSelectedIndex(0);
        }
        mobile_cp.m_choice.setEnabled(mobile_cb.isSelected());

        atomRender.setSelectedItem(mACVD.getAtomRenderingMethod());
    }

    protected void setDataToRepository() {
        Color bgcolor = cbbgcolor.getColor();
        mACVD.setBgColor((float) bgcolor.getRed() / 255.f,
                (float) bgcolor.getGreen() / 255.f,
                (float) bgcolor.getBlue() / 255.f);

        Color bondcolor = cbbondcolor.getColor();
        mACVD.setBondColor((float) bondcolor.getRed() / 255.f,
                (float) bondcolor.getGreen() / 255.f,
                (float) bondcolor.getBlue() / 255.f);

        mACVD.setBondFactor(Double.parseDouble(bondfactor_ip.getValue()));
        mACVD.setBondWidth(Double.parseDouble(bondwidth_ip.getValue()));
        mACVD.setUseWireForBond(checklightbond.isSelected());

        mACVD.setScale(Float.parseFloat(scale_ip.getValue()));
        mACVD.setScaleAtom(Float.parseFloat(scaleatom_ip.getValue()));

        mACVD.setNumNodesAtom(Integer.parseInt(numnodesatom_ip.getValue()));
        mACVD.setNumNodesBond(Integer.parseInt(numnodesbond_ip.getValue()));
        mACVD.setNumNodesCell(Integer.parseInt(numnodescell_ip.getValue()));

        mACVD.setDrawCell(drawcell_cb.isSelected());
        mACVD.setCellWidth(Float.parseFloat(cellwidth_ip.getValue()));

        Color cellcolor = cbcellcolor.getColor();
        mACVD.setCellColor((float) cellcolor.getRed() / 255.f,
                (float) cellcolor.getGreen() / 255.f,
                (float) cellcolor.getBlue() / 255.f);

        mACVD.setAxis(axis_cb.isSelected());
        mACVD.setText(label_cb.isSelected());
        mACVD.setLabelOffset(Integer.parseInt(labeloffset_ip.getValue()));
        mACVD.setLegend(legend_cb.isSelected());
        mACVD.setMobile(mobile_cb.isSelected());
        mACVD.setMobilityDisplayMode(mobile_cp.m_choice.getSelectedIndex());

        mACVD.setAtomRenderingMethod(atomRender.getSelectedItem().toString());
        mACVD.setUseWireForCell(cell_is_wire.isSelected());

        mACVD.setFontColor(btnFontColor.getColor3f());
    }

}

class ElementEditor extends ACVEditors {
    private double[] dcovrad;
    private float[] frad;
    private float[][] fcolor;
    private boolean[] hbond;
    private double[] hbondRad;
    private ChoicePanel element_cp;

    private JButton btnelementcolor;
    private InputPanel covrad_ip;
    private InputPanel atsize_ip;

    private InputPanel hbondmax_ip;

    protected ElementEditor(MainPanel mp) {
        super(mp);
    }

    private ElementDef[] def;

    protected void createGUI() {
        dcovrad = new double[NumEl];
        frad = new float[NumEl];
        fcolor = new float[NumEl][3];
        hbond = new boolean[NumEl];
        hbondRad = new double[NumEl];
        ElementInfo einfo = mACVD.getEInfo();
        def = einfo.getElementDef();
        for (int i = 0; i < def.length; i++) {
            hbond[i] = def[i].hasHbond();
            if (hbond[i]) {
                hbondRad[i] = def[i].getMaxHbondDistance();
            } else {
                hbondRad[i] = 0.0;
            }
        }

        for (int i = 0; i < NumEl; i++) {
            dcovrad[i] = mACVD.getCovRad()[i];
            frad[i] = mACVD.getRad()[i];
            for (int j = 0; j < 3; j++) {
                fcolor[i][j] = mACVD.getColor()[i][j];
            }
        }

        String space = new String();
        space = "                 ";
        String[] element_symbol = new String[NumEl];
        for (int i = 0; i < NumEl; i++) {
            element_symbol[i] = mp.getJ3DDataManager().getElement()[i] + space;
        }
        element_symbol = mp.getJ3DDataManager().getElement();

        JPanel pelement = this;
        pelement.setLayout(new BoxLayout(pelement, BoxLayout.Y_AXIS));

        JPanel psymbol = new JPanel();
        psymbol.setLayout(new GridLayout(1, 1, 1, 1));
        // psymbol.setBorder(new TitledBorder("choose element"));
        element_cp = new ChoicePanel("element", element_symbol);
        psymbol.add(element_cp);

        JPanel patomcolor = new JPanel();
        patomcolor.setBorder(new TitledBorder("atom color"));
        btnelementcolor = new JButton("choose ...");
        patomcolor.add(btnelementcolor);

        JPanel prad = new JPanel();
        prad.setLayout(new GridLayout(1, 4));
        // prad.setBorder(new TitledBorder("element properties"));
        covrad_ip = new InputPanel("covalent radius", 0, 7, true);
        atsize_ip = new InputPanel("atomic radius", 0, 7, true);
        hbondmax_ip = new InputPanel("H bond", 0, 7, true);
        prad.add(covrad_ip);
        prad.add(hbondmax_ip);
        prad.add(atsize_ip);
        prad.add(patomcolor);

        pelement.add(psymbol);
        pelement.add(prad);

        element_cp.m_choice.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < NumEl; i++) {
                    if (element_cp.getChoice().equals(mACVD.getElement()[i])) {
                        covrad_ip.setValue(Double.toString(mACVD.getCovRad()[i]));
                        atsize_ip.setValue(Float.toString(mACVD.getRad()[i]));
                        btnelementcolor.setBackground(new Color(mACVD
                                .getColor()[i][0], mACVD.getColor()[i][1],
                                mACVD.getColor()[i][2]));
                        hbondmax_ip.setValue(String.valueOf(def[i]
                                .getMaxHbondDistance()));
                    }
                }
            }
        });

        covrad_ip.m_value.addCaretListener(new CaretListener() {
            public void caretUpdate(CaretEvent ce) {
                double cov = 0;
                try {
                    cov = Double.parseDouble(covrad_ip.getValue());
                    mACVD.setCovRad(cov, element_cp.m_choice.getSelectedIndex());
                } catch (Exception e) {
                }
            }
        });

        atsize_ip.m_value.addCaretListener(new CaretListener() {
            public void caretUpdate(CaretEvent ce) {
                float radiu = 0f;
                try {
                    radiu = Float.parseFloat(atsize_ip.getValue());
                    mACVD.setRad(radiu, element_cp.m_choice.getSelectedIndex());
                } catch (Exception e) {
                }
            }
        });

        hbondmax_ip.m_value.addCaretListener(new CaretListener() {
            public void caretUpdate(CaretEvent e) {
                String str = hbondmax_ip.getValue();
                try {
                    double dv = Double.parseDouble(str);
                    def[element_cp.m_choice.getSelectedIndex()]
                            .setMaxHbondDistance(dv);
                } catch (Exception exc) {
                }
            }
        });

        btnelementcolor.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Color elementColor = Color.GRAY;
                JColorChooser colorchooser = new JColorChooser();
                Color color = colorchooser.showDialog(mp, "Choose",
                        elementColor);
                if (color != null) {
                    elementColor = color;
                    btnelementcolor.setBackground(elementColor);
                    float[] foo = new float[] {
                            (float) elementColor.getRed() / 255.f,
                            (float) elementColor.getGreen() / 255.f,
                            (float) elementColor.getBlue() / 255.f };
                    mACVD.setColor(foo, element_cp.m_choice.getSelectedIndex());
                }
            }
        });
        element_cp.setChoice(mACVD.getElement()[0]);
    }

    protected String getTitle() {
        return "element";
    }

    protected void setDataToPanel() {
    }

    protected void setDataToRepository() {
    }

}
