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

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToolTip;
import javax.swing.border.TitledBorder;

import org.apache.log4j.Logger;

import ciss.phase_viewer.inputinterface.Input;
import ciss.phase_viewer.main.PluginLoader;
import ciss.phase_viewer.mainpanel.InternalFrameChase;

/**
 * 入力検査用GUI
 * 
 * @author
 */
public class InputCheckerGUI extends InternalFrameChase {
    private Logger logger = Logger.getLogger(InputCheckerGUI.class.getName());

    private Properties props;

    private Input input;

    private InputCheckerGUIsub[] guis;

    /**
     * @param props
     *            InputCheckerが並べてあるPropertiesファイル
     * @param input
     *            関連付けられているInputオブジェクト
     */
    public InputCheckerGUI(Properties props, Input input) {
        super("check inputfile : " + input.getFileName(), true, true, true,
                true, new Dimension(550, 400));
        this.props = props;
        this.input = input;
        init();
    }

    private void init() {
        JPanel pp = new JPanel();
        pp.setLayout(new BorderLayout());
        Vector vec = new Vector();
        Set keySet = props.keySet();
        Object[] arg = new Object[] { input };
        Object[] keys = keySet.toArray();
        Arrays.sort(keys);
        for (int i = 0; i < keys.length; i++) {
            InputChecker foo = (InputChecker) PluginLoader.instantiate(
                    props.getProperty(keys[i].toString()), null);
            foo.setInput(input);
            vec.addElement(foo);
        }

        JPanel p = new JPanel();
        p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));

        Vector foo = new Vector();
        for (int i = 0; i < vec.size(); i++) {
            InputChecker ic = (InputChecker) vec.get(i);
            InputCheckerGUIsub icg = new InputCheckerGUIsub(ic);
            p.add(icg);
            foo.add(icg);
        }

        guis = new InputCheckerGUIsub[foo.size()];
        foo.copyInto(guis);

        JScrollPane pane = new JScrollPane(p);
        Dimension siz = getSize();
        pane.setPreferredSize(new Dimension((int) (siz.width * 0.8),
                (int) (siz.height * 0.8)));
        pp.add(pane);

        getContentPane().add(pp, BorderLayout.NORTH);
        JPanel btns = getBtns();
        getContentPane().add(btns, BorderLayout.SOUTH);
    }

    private JPanel getBtns() {
        JPanel panel = new JPanel();
        // panel.setLayout(new BoxLayout(panel,BoxLayout.X_AXIS));
        JButton check = new JButton("check");
        JButton dismiss = new JButton("dismiss");

        panel.add(check);
        panel.add(dismiss);

        check.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                doCheck();
            }
        });

        dismiss.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                dispose();
            }
        });

        return panel;
    }

    private void doCheck() {
        updateGUI();
    }

    private void updateGUI() {
        for (int i = 0; i < guis.length; i++) {
            InputCheckerGUIsub gui = guis[i];
            gui.update();
        }
    }

    class InputCheckerGUIsub extends JPanel {
        private InputChecker checker;

        private Dimension dim = new Dimension(150, 50);

        InputCheckerGUIsub(InputChecker checker) {
            this.checker = checker;
            init();
        }

        InputChecker getAssociatedInputChecker() {
            return this.checker;
        }

        private void init() {
            GridBagConstraints gc = new GridBagConstraints();
            setLayout(new GridBagLayout());
            setBorder(new TitledBorder(checker.getName()));
            JPanel statePanel = getStatePanel();
            JPanel descriptPanel = getDescriptionPanel();
            JPanel msgPanel = getMessagePanel();
            JPanel fixbtnPanel = getFixBtn();

            gc.gridwidth = 1;
            gc.gridheight = 1;
            gc.weightx = 0;
            gc.weighty = 0;
            gc.fill = GridBagConstraints.BOTH;
            add(statePanel, gc);

            gc.gridheight = 2;
            gc.gridwidth = 2;
            add(descriptPanel, gc);

            gc.gridwidth = 2;
            gc.gridheight = 2;
            add(msgPanel, gc);

            gc.gridheight = 1;
            gc.gridwidth = 1;
            add(fixbtnPanel, gc);
        }

        private JLabel stateLabel;

        private JPanel getStatePanel() {
            JPanel p = new JPanel();
            p.setBorder(new TitledBorder("state"));
            stateLabel = new JLabel(InputChecker.STR_UN_CHECKED);
            stateLabel.setFont(new Font("Monospaced", Font.PLAIN, 12));
            p.add(stateLabel);
            return p;
        }

        private JPanel getDescriptionPanel() {
            JPanel descript = new JPanel();
            descript.setBorder(new TitledBorder("description"));
            JTextArea area = new JTextArea();
            area.setEditable(false);
            area.setText(checker.getDescription());
            area.setCaretPosition(0);
            JScrollPane pane = new JScrollPane();
            pane.setPreferredSize(dim);
            pane.getViewport().setView(area);
            descript.add(pane);
            return descript;
        }

        private JTextArea messageTextArea;

        private JPanel getMessagePanel() {
            JPanel ret = new JPanel();
            ret.setBorder(new TitledBorder("message"));
            messageTextArea = new JTextArea();
            messageTextArea.setEditable(false);
            JScrollPane pane = new JScrollPane();
            pane.setPreferredSize(dim);
            pane.getViewport().setView(messageTextArea);
            ret.add(pane);
            return ret;
        }

        private JButton fixButton;

        private JPanel getFixBtn() {
            JPanel ret = new JPanel();
            fixButton = new FixButton("fix it");
            fixButton.setEnabled(false);
            ret.add(fixButton);
            fixButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {
                    checker.fixInput();
                    update();
                }
            });
            return ret;
        }

        void update() {
            try {
                int state = checker.doCheck();
                messageTextArea.setText(checker.getMessage());
                messageTextArea.setCaretPosition(0);
                // int state = checker.getCurrentState();
                if (state == InputChecker.OK) {
                    stateLabel.setText(InputChecker.STR_OK);
                    stateLabel.setForeground(Color.BLUE);
                } else if (state == InputChecker.ERROR) {
                    stateLabel.setText(InputChecker.STR_ERROR);
                    stateLabel.setForeground(Color.RED);
                } else if (state == InputChecker.WARNING) {
                    stateLabel.setText(InputChecker.STR_WARNING);
                    stateLabel.setForeground(Color.GREEN);
                }
                boolean fix = (state == InputChecker.ERROR || state == InputChecker.WARNING)
                        && checker.isFixable();
                fixButton.setEnabled(fix);
                if (fix) {
                    fixButton.setToolTipText(checker.getCandidate());
                } else {
                    fixButton.setToolTipText("");
                }
            } catch (RuntimeException e) {
                e.printStackTrace();
            }
        }

    }

    class FixButton extends JButton {
        public FixButton(String text) {
            super(text);
        }

        public JToolTip createToolTip() {
            return new ciss.phase_viewer.pub.primitivegui.JMultiLineToolTip();
        }
    }

}
