/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



import com.sun.star.reflection.ParamInfo;
import com.sun.star.reflection.XIdlMethod;
import com.sun.star.uno.TypeClass;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 * @author bc93774
 */
public class MethodParametersDialog extends JDialog{
    private javax.swing.JPanel jPnlParamContainer;
    private ParameterPanel[] m_aParameterPanels;
    private ParamInfo[] m_aParamInfo;
    private XIdlMethod m_xIdlMethod;
    private ActionListener oActionListener;
    private JButton jHelpButton = new JButton("Help");
    private JButton jOKButton = new JButton("Ok");
    private JButton jInvokeButton = new JButton("Invoke");
    private Object m_oReturnButton = null;
    private Object m_oUnoObject = null;
    private Object m_oUnoReturnObject = null;
    private JLabel jLblResult;
    private JPanel jResultPanel = null;
    private boolean bisdiposed = false;
    private XUnoMethodNode m_xUnoMethodNode;


    public MethodParametersDialog(XUnoMethodNode _xUnoMethodNode){
        m_xUnoMethodNode = _xUnoMethodNode;
        m_xIdlMethod = _xUnoMethodNode.getXIdlMethod();
        m_aParamInfo = m_xIdlMethod.getParameterInfos();
        m_oUnoObject = m_xUnoMethodNode.getUnoObject();
        Object[] m_aParameterObjects = new Object[m_aParamInfo.length];
    }


    public Vector getMethodObjects() {
        super.setModal(true);
        addBorderPanel(getContentPane(), BorderLayout.NORTH);
        addBorderPanel(getContentPane(), BorderLayout.WEST);
        addBorderPanel(getContentPane(), BorderLayout.EAST);
        jPnlParamContainer = new JPanel();
        jPnlParamContainer.setLayout(new javax.swing.BoxLayout(jPnlParamContainer, javax.swing.BoxLayout.Y_AXIS));
        JPanel jHeaderPanel = new JPanel(new BorderLayout());
        JLabel jLblHeader = new JLabel();
        jLblHeader.setText("Please insert the values for the given Parameters of the method '" + m_xIdlMethod.getName() + "'");
        jHeaderPanel.add(jLblHeader,BorderLayout.WEST);
        jPnlParamContainer.add(jHeaderPanel);

        m_aParameterPanels = new ParameterPanel[m_aParamInfo.length];
        for (int i = 0; i < m_aParameterPanels.length; i++){
            m_aParameterPanels[i] = new ParameterPanel(m_aParamInfo[i]);
            jPnlParamContainer.add(m_aParameterPanels[i]);
        }
        jPnlParamContainer.add(new ButtonPanel(), java.awt.BorderLayout.SOUTH);
        getContentPane().add(jPnlParamContainer, java.awt.BorderLayout.CENTER);
        pack();
        setLocation(350, 350);
        setTitle("Object Inspector - Parameter Values of '" + m_xIdlMethod.getName() + "'");
        super.setFocusable(true);
        super.setFocusableWindowState(true);
        super.requestFocus();
        m_aParameterPanels[0].getInputComponent().requestFocusInWindow();
		setVisible(true);
        if (!bisdiposed){
            Vector aMethodObjects = new Vector();
            for (int i = 0; i < m_aParameterPanels.length; i++){
                aMethodObjects.add(m_aParameterPanels[i].getValue());
            }
            aMethodObjects.add(m_oUnoReturnObject);
            return aMethodObjects;
        }
        else{
            return null;
        }
    }


    private void insertResultPanel(Exception _oInvocationException){
        boolean bAddPanel = false;
        if (jResultPanel == null){
            jResultPanel = new JPanel(new BorderLayout());
            bAddPanel = true;
        }
        else{
            jResultPanel.removeAll();
        }
        jLblResult = new JLabel();
        jLblResult.setMaximumSize(new java.awt.Dimension(getSize().width - 20, 57));
        if (_oInvocationException != null){
            jLblResult.setText("<html>Invoking the method cause an exception: <br>" + _oInvocationException.toString() + "</html>");
        }
        else{
            jLblResult.setText("<html>The invocation of the method did not produce any error</html>");
        }
        jResultPanel.add(jLblResult,BorderLayout.WEST);
        if (bAddPanel){
            int nPos = jPnlParamContainer.getComponentCount() - 1;
            jPnlParamContainer.add(jResultPanel, nPos);
        }
        super.pack();
        super.validate();
    }


    private Object[] getParameterValues(){
        Object[] oParameterValues = new Object[m_aParameterPanels.length];
        for (int i = 0; i < m_aParameterPanels.length; i++){
            oParameterValues[i] = m_aParameterPanels[i].getValue();
        }
        return oParameterValues;
    }


    private boolean isCompleted(){
        boolean bIsCompleted = true;
        for (int i = 0; i < m_aParameterPanels.length; i++){
            bIsCompleted = m_aParameterPanels[i].isCompleted();
            if (!bIsCompleted){
                break;
            }
        }
        return bIsCompleted;
    }


    private void addBorderPanel(java.awt.Container _jContainer, String _sLayout){
        JPanel jPnlBorder = new JPanel();
        jPnlBorder.setPreferredSize(new java.awt.Dimension(10, 10));
        _jContainer.add(jPnlBorder, _sLayout);
    }

    private void addGapPanel(java.awt.Container _jContainer){
        JPanel jPnlBorder = new JPanel();
        jPnlBorder.setPreferredSize(new java.awt.Dimension(10, 10));
        jPnlBorder.setMaximumSize(new java.awt.Dimension(10, 10));
        _jContainer.add(jPnlBorder);
    }


    private class ParameterPanel extends JPanel{
        private JComponent m_jComponent;
        private TypeClass m_aTypeClass = null;

        public ParameterPanel(ParamInfo _aParamInfo){
            JTextField jTextField = new JTextField();
            JComboBox jComboBox = new JComboBox();
            m_aTypeClass =  _aParamInfo.aType.getTypeClass();
            setLayout(new java.awt.BorderLayout());
            addBorderPanel(this, BorderLayout.NORTH);
            addBorderPanel(this, BorderLayout.SOUTH);
            JPanel jPnlCenter1 = new javax.swing.JPanel();
            jPnlCenter1.setLayout(new javax.swing.BoxLayout(jPnlCenter1, javax.swing.BoxLayout.X_AXIS));
            JLabel jLabel1 = new JLabel();
            jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
            String sParamText = _aParamInfo.aName + " (" + _aParamInfo.aType.getName() +")";
            jLabel1.setText(sParamText);
            jPnlCenter1.add(jLabel1);
            addGapPanel(jPnlCenter1);
            switch (m_aTypeClass.getValue()){
                case TypeClass.BOOLEAN_value:
                    jComboBox.setBackground(new java.awt.Color(255, 255, 255));
                    jComboBox.setPreferredSize(new java.awt.Dimension(50, 19));
                    jComboBox.addItem("True");
                    jComboBox.addItem("False");
                    jComboBox.addKeyListener(new UpdateUIAdapter());
                    jPnlCenter1.add(jComboBox);
                    m_jComponent = jComboBox;
                    break;
                case TypeClass.BYTE_value:
                case TypeClass.CHAR_value:
                case TypeClass.DOUBLE_value:
                case TypeClass.ENUM_value:
                case TypeClass.FLOAT_value:
                case TypeClass.HYPER_value:
                case TypeClass.LONG_value:
                case TypeClass.SHORT_value:
                case TypeClass.STRING_value:
                case TypeClass.UNSIGNED_HYPER_value:
                case TypeClass.UNSIGNED_LONG_value:
                case TypeClass.UNSIGNED_SHORT_value:
                    jTextField.setPreferredSize(new java.awt.Dimension(50, 19));
                    jTextField.addKeyListener(new UpdateUIAdapter());
                    jPnlCenter1.add(jTextField);
                    m_jComponent = jTextField;
                    break;
                default:
                    System.out.println("Type " + m_aTypeClass.getValue() + " not yet defined in 'ParameterPanel()'");
            }
            add(jPnlCenter1, java.awt.BorderLayout.CENTER);
            JPanel jPnlEast = new JPanel();
            add(jPnlEast, BorderLayout.EAST);
        }

        private JComponent getInputComponent(){
            return m_jComponent;
        }

        public Object getValue(){
            Object oReturn = null;
            if (m_jComponent instanceof JTextField){
                String sText = ((JTextField) m_jComponent).getText();
                oReturn = Introspector.getIntrospector().getValueOfText(m_aTypeClass, sText);
            }
            else{
                JComboBox jComboBox = ((JComboBox) m_jComponent);
                oReturn =  Boolean.valueOf(jComboBox.getSelectedIndex() == 0);
            }
            return oReturn;
        }


        public boolean isCompleted(){
            if (m_jComponent instanceof JTextField){
                return !((JTextField) m_jComponent).getText().equals("");
            }
            else{
                return true;
            }
        }
    }


    private class UpdateUIAdapter extends KeyAdapter{
        public void keyReleased(KeyEvent e){
            boolean bIsCompleted = isCompleted();
            jOKButton.setEnabled(bIsCompleted);
            jInvokeButton.setEnabled(bIsCompleted);
            if (jLblResult != null){
                jLblResult.setEnabled(false);
                jLblResult.invalidate();
            }
        }
    }



    private class ButtonPanel extends JPanel{
        public ButtonPanel(){
            super();
            setLayout(new BorderLayout());
            addBorderPanel(this, BorderLayout.NORTH);
            addBorderPanel(this, BorderLayout.SOUTH);
            JPanel jPnlBottomCenter = new JPanel();
            jPnlBottomCenter.setLayout(new javax.swing.BoxLayout(jPnlBottomCenter, javax.swing.BoxLayout.X_AXIS));
            jHelpButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    oActionListener.actionPerformed(e);
                }
            });
            jHelpButton.setEnabled(oActionListener != null);
            jPnlBottomCenter.add(jHelpButton);
            addGapPanel(jPnlBottomCenter);
            jOKButton.setEnabled(false);
            jOKButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    invokeParameterMethod();
                    dispose();
                }
            });
            jOKButton.setEnabled(isCompleted());
            jInvokeButton.setEnabled(isCompleted());
            jInvokeButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    invokeParameterMethod();
                }
            });

            jPnlBottomCenter.add(jOKButton);
            addGapPanel(jPnlBottomCenter);
            jPnlBottomCenter.add(jInvokeButton);
            addGapPanel(jPnlBottomCenter);
            JButton jCancelButton = new JButton("Cancel");
            jCancelButton.setFocusCycleRoot(true);
            jCancelButton.setFocusPainted(true);
            jCancelButton.addActionListener(new ActionListener(){
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    bisdiposed = true;
                    dispose();
                }
            });

            jPnlBottomCenter.add(jCancelButton);
            add(jPnlBottomCenter);
        }
    }


    public void addActionListener(ActionListener _oActionListener){
        oActionListener = _oActionListener;
        jHelpButton.setEnabled(oActionListener != null);
    }


    public void invokeParameterMethod(){
    try{
        Object[] oParameters = getParameterValues();
        m_oUnoReturnObject = m_xUnoMethodNode.invoke(m_oUnoObject, oParameters);
        insertResultPanel(null);
    } catch (Exception ex) {
        insertResultPanel(ex);
        m_oUnoReturnObject = null;
    }}

}
