/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.tools.beans;

import java.util.*;

import javax.swing.*;

import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;

/**
 * Reusable visual component for editing expressions.
 */
public class ExpressionPanel extends JPanel {
    protected Expression expression;
    protected ClassDescriptor descriptor;
    private JButton ivjAndButton = null;
    private JComboBox ivjAttributeCombo = null;
    private JLabel ivjAttributeLabel = null;
    private JButton ivjClearButton = null;
    private JTree ivjExpressionTree = null;
    private JScrollPane ivjExpressionTreeScroll = null;
    private JButton ivjNotBuuton = null;
    private JComboBox ivjOperatorCombo = null;
    private JLabel ivjOperatorLabel = null;
    private JButton ivjOrButton = null;
    private JToolBar ivjToolBar = null;
    private JLabel ivjValueLabel = null;
    private JTextField ivjValueText = null;
    IvjEventHandler ivjEventHandler = new IvjEventHandler();

    /**
     * Constructor
     */
    public ExpressionPanel() {
        super();
        initialize();
    }

    /**
     * ExpressionPanel constructor comment.
     * @param layout java.awt.LayoutManager
     */
    public ExpressionPanel(java.awt.LayoutManager layout) {
        super(layout);
    }

    /**
     * ExpressionPanel constructor comment.
     * @param layout java.awt.LayoutManager
     * @param isDoubleBuffered boolean
     */
    public ExpressionPanel(java.awt.LayoutManager layout,
                           boolean isDoubleBuffered) {
        super(layout, isDoubleBuffered);
    }

    /**
     * ExpressionPanel constructor comment.
     * @param isDoubleBuffered boolean
     */
    public ExpressionPanel(boolean isDoubleBuffered) {
        super(isDoubleBuffered);
    }

    public void andExpression() {
        Expression newExpression = buildExpressionNode();
        if (newExpression == null) {
            return;
        }

        if (getExpression() == null) {
            setExpression(newExpression);
        } else {
            setExpression(getExpression().and(newExpression));
        }
    }

    public Expression buildExpressionNode() {
        ExpressionBuilder builder;
        if (getExpression() == null) {
            builder = new ExpressionBuilder();
        } else {
            builder = getExpression().getBuilder();
        }

        String attribute = (String)getAttributeCombo().getSelectedItem();
        if (attribute == null) {
            return null;
        }
        String operator = (String)getOperatorCombo().getSelectedItem();
        String method = ExpressionNode.getMethod(operator);
        String value = getValueText().getText();
        Class[] types = new Class[1];
        types[0] = Object.class;
        Object[] arguments = new Object[1];
        arguments[0] = value;
        Expression queryKey = builder.get(attribute);
        try {
            return (Expression)queryKey.getClass().getMethod(method,
                                                             types).invoke(queryKey,
                                                                           arguments);
        } catch (Exception exception) {
            try {
                types[0] = String.class;
                return (Expression)queryKey.getClass().getMethod(method,
                                                                 types).invoke(queryKey,
                                                                               arguments);
            } catch (Exception e) {
                handleException(e);
                return null;
            }
        }
    }

    public void clearExpression() {
        setExpression(null);
    }

    /**
     * connEtoC1:  (OrButton.action.actionPerformed(java.awt.event.ActionEvent) --> ExpressionPanel.orExpression()V)
     * @param arg1 java.awt.event.ActionEvent
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connEtoC1(java.awt.event.ActionEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.orExpression();
            // user code begin {2}
            // user code end
        } catch (java.lang.Throwable ivjExc) {
            // user code begin {3}
            // user code end
            handleException(ivjExc);
        }
    }

    /**
     * connEtoC2:  (AndButton.action.actionPerformed(java.awt.event.ActionEvent) --> ExpressionPanel.andExpression()V)
     * @param arg1 java.awt.event.ActionEvent
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connEtoC2(java.awt.event.ActionEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.andExpression();
            // user code begin {2}
            // user code end
        } catch (java.lang.Throwable ivjExc) {
            // user code begin {3}
            // user code end
            handleException(ivjExc);
        }
    }

    /**
     * connEtoC3:  (NotBuuton.action.actionPerformed(java.awt.event.ActionEvent) --> ExpressionPanel.notExpression()V)
     * @param arg1 java.awt.event.ActionEvent
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connEtoC3(java.awt.event.ActionEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.notExpression();
            // user code begin {2}
            // user code end
        } catch (java.lang.Throwable ivjExc) {
            // user code begin {3}
            // user code end
            handleException(ivjExc);
        }
    }

    /**
     * connEtoC4:  (ClearButton.action.actionPerformed(java.awt.event.ActionEvent) --> ExpressionPanel.clearExpression()V)
     * @param arg1 java.awt.event.ActionEvent
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    void connEtoC4(java.awt.event.ActionEvent arg1) {
        try {
            // user code begin {1}
            // user code end
            this.clearExpression();
            // user code begin {2}
            // user code end
        } catch (java.lang.Throwable ivjExc) {
            // user code begin {3}
            // user code end
            handleException(ivjExc);
        }
    }

    /**
     * Return the AddButton property value.
     * @return javax.swing.JButton
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JButton getAndButton() {
        if (ivjAndButton == null) {
            try {
                ivjAndButton = new javax.swing.JButton();
                ivjAndButton.setName("AndButton");
                ivjAndButton.setText("And");
                ivjAndButton.setBackground(java.awt.SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjAndButton;
    }

    /**
     * Return the AttributeCombo property value.
     * @return javax.swing.JComboBox
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JComboBox getAttributeCombo() {
        if (ivjAttributeCombo == null) {
            try {
                ivjAttributeCombo = new javax.swing.JComboBox();
                ivjAttributeCombo.setName("AttributeCombo");
                ivjAttributeCombo.setBackground(java.awt.SystemColor.window);
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjAttributeCombo;
    }

    /**
     * Return the AttributeLabel property value.
     * @return javax.swing.JLabel
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JLabel getAttributeLabel() {
        if (ivjAttributeLabel == null) {
            try {
                ivjAttributeLabel = new javax.swing.JLabel();
                ivjAttributeLabel.setName("AttributeLabel");
                ivjAttributeLabel.setText("Attribute:");
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjAttributeLabel;
    }

    /**
     * Return the RemoveButton property value.
     * @return javax.swing.JButton
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JButton getClearButton() {
        if (ivjClearButton == null) {
            try {
                ivjClearButton = new javax.swing.JButton();
                ivjClearButton.setName("ClearButton");
                ivjClearButton.setText("Clear");
                ivjClearButton.setBackground(java.awt.SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjClearButton;
    }

    public ClassDescriptor getDescriptor() {
        return descriptor;
    }

    public Expression getExpression() {
        return expression;
    }

    /**
     * Return the ExpressionTree property value.
     * @return javax.swing.JTree
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JTree getExpressionTree() {
        if (ivjExpressionTree == null) {
            try {
                ivjExpressionTree = new javax.swing.JTree();
                ivjExpressionTree.setName("ExpressionTree");
                //ivjExpressionTree.setBorder(new javax.swing.plaf.basic.BasicBorders.MarginBorder());
                ivjExpressionTree.setBounds(0, 0, 76, 36);
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjExpressionTree;
    }

    /**
     * Return the ExpressionTreeScroll property value.
     * @return javax.swing.JScrollPane
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JScrollPane getExpressionTreeScroll() {
        if (ivjExpressionTreeScroll == null) {
            try {
                ivjExpressionTreeScroll = new javax.swing.JScrollPane();
                ivjExpressionTreeScroll.setName("ExpressionTreeScroll");
                getExpressionTreeScroll().setViewportView(getExpressionTree());
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjExpressionTreeScroll;
    }

    /**
     * Return the NotBuuton property value.
     * @return javax.swing.JButton
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JButton getNotBuuton() {
        if (ivjNotBuuton == null) {
            try {
                ivjNotBuuton = new javax.swing.JButton();
                ivjNotBuuton.setName("NotBuuton");
                ivjNotBuuton.setText("Not");
                ivjNotBuuton.setBackground(java.awt.SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjNotBuuton;
    }

    /**
     * Return the OperatorCombo property value.
     * @return javax.swing.JComboBox
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JComboBox getOperatorCombo() {
        if (ivjOperatorCombo == null) {
            try {
                ivjOperatorCombo = new javax.swing.JComboBox();
                ivjOperatorCombo.setName("OperatorCombo");
                ivjOperatorCombo.setBackground(java.awt.SystemColor.window);
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjOperatorCombo;
    }

    /**
     * Return the OperatorLabel property value.
     * @return javax.swing.JLabel
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JLabel getOperatorLabel() {
        if (ivjOperatorLabel == null) {
            try {
                ivjOperatorLabel = new javax.swing.JLabel();
                ivjOperatorLabel.setName("OperatorLabel");
                ivjOperatorLabel.setText("Operator:");
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjOperatorLabel;
    }

    /**
     * Return the OrButton property value.
     * @return javax.swing.JButton
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JButton getOrButton() {
        if (ivjOrButton == null) {
            try {
                ivjOrButton = new javax.swing.JButton();
                ivjOrButton.setName("OrButton");
                ivjOrButton.setText("Or");
                ivjOrButton.setBackground(java.awt.SystemColor.control);
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjOrButton;
    }

    /**
     * Return the ToolBar property value.
     * @return javax.swing.JToolBar
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JToolBar getToolBar() {
        if (ivjToolBar == null) {
            try {
                ivjToolBar = new javax.swing.JToolBar();
                ivjToolBar.setName("ToolBar");
                ivjToolBar.setBackground(java.awt.SystemColor.control);
                getToolBar().add(getAndButton(), getAndButton().getName());
                getToolBar().add(getOrButton(), getOrButton().getName());
                getToolBar().add(getNotBuuton(), getNotBuuton().getName());
                ivjToolBar.addSeparator();
                getToolBar().add(getClearButton(), getClearButton().getName());
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjToolBar;
    }

    /**
     * Return the ValueLabel property value.
     * @return javax.swing.JLabel
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JLabel getValueLabel() {
        if (ivjValueLabel == null) {
            try {
                ivjValueLabel = new javax.swing.JLabel();
                ivjValueLabel.setName("ValueLabel");
                ivjValueLabel.setText("Value:");
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjValueLabel;
    }

    /**
     * Return the ValueText property value.
     * @return javax.swing.JTextField
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    javax.swing.JTextField getValueText() {
        if (ivjValueText == null) {
            try {
                ivjValueText = new javax.swing.JTextField();
                ivjValueText.setName("ValueText");
                // user code begin {1}
                // user code end
            } catch (java.lang.Throwable ivjExc) {
                // user code begin {2}
                // user code end
                handleException(ivjExc);
            }
        }
        return ivjValueText;
    }

    /**
     * Called whenever the part throws an exception.
     * @param exception java.lang.Throwable
     */
    private void handleException(Throwable exception) {
        MessageDialog.displayException(exception, this);
    }

    /**
     * Initializes connections
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    void initConnections() throws java.lang.Exception {
        // user code begin {1}
        // user code end
        getOrButton().addActionListener(ivjEventHandler);
        getAndButton().addActionListener(ivjEventHandler);
        getNotBuuton().addActionListener(ivjEventHandler);
        getClearButton().addActionListener(ivjEventHandler);
    }

    /**
     * Initialize the class.
     */
    private

    /* WARNING: THIS METHOD WILL BE REGENERATED. */
    void initialize() {
        try {
            // user code begin {1}
            // user code end
            setName("ExpressionPanel");
            setLayout(new java.awt.GridBagLayout());
            setBackground(java.awt.SystemColor.control);
            setSize(742, 472);

            java.awt.GridBagConstraints constraintsAttributeLabel =
                new java.awt.GridBagConstraints();
            constraintsAttributeLabel.gridx = 0;
            constraintsAttributeLabel.gridy = 0;
            constraintsAttributeLabel.anchor =
                    java.awt.GridBagConstraints.SOUTHWEST;
            constraintsAttributeLabel.insets = new java.awt.Insets(2, 2, 0, 2);
            add(getAttributeLabel(), constraintsAttributeLabel);

            java.awt.GridBagConstraints constraintsValueText =
                new java.awt.GridBagConstraints();
            constraintsValueText.gridx = 2;
            constraintsValueText.gridy = 1;
            constraintsValueText.fill = java.awt.GridBagConstraints.HORIZONTAL;
            constraintsValueText.weightx = 0.2;
            constraintsValueText.ipadx = 20;
            constraintsValueText.insets = new java.awt.Insets(0, 2, 2, 2);
            add(getValueText(), constraintsValueText);

            java.awt.GridBagConstraints constraintsAttributeCombo =
                new java.awt.GridBagConstraints();
            constraintsAttributeCombo.gridx = 0;
            constraintsAttributeCombo.gridy = 1;
            constraintsAttributeCombo.fill =
                    java.awt.GridBagConstraints.HORIZONTAL;
            constraintsAttributeCombo.weightx = 0.2;
            constraintsAttributeCombo.insets = new java.awt.Insets(0, 2, 2, 2);
            add(getAttributeCombo(), constraintsAttributeCombo);

            java.awt.GridBagConstraints constraintsOperatorCombo =
                new java.awt.GridBagConstraints();
            constraintsOperatorCombo.gridx = 1;
            constraintsOperatorCombo.gridy = 1;
            constraintsOperatorCombo.fill =
                    java.awt.GridBagConstraints.HORIZONTAL;
            constraintsOperatorCombo.weightx = 0.2;
            constraintsOperatorCombo.insets = new java.awt.Insets(0, 2, 2, 2);
            add(getOperatorCombo(), constraintsOperatorCombo);

            java.awt.GridBagConstraints constraintsOperatorLabel =
                new java.awt.GridBagConstraints();
            constraintsOperatorLabel.gridx = 1;
            constraintsOperatorLabel.gridy = 0;
            constraintsOperatorLabel.anchor =
                    java.awt.GridBagConstraints.SOUTHWEST;
            constraintsOperatorLabel.insets = new java.awt.Insets(2, 2, 0, 2);
            add(getOperatorLabel(), constraintsOperatorLabel);

            java.awt.GridBagConstraints constraintsValueLabel =
                new java.awt.GridBagConstraints();
            constraintsValueLabel.gridx = 2;
            constraintsValueLabel.gridy = 0;
            constraintsValueLabel.anchor =
                    java.awt.GridBagConstraints.SOUTHWEST;
            constraintsValueLabel.insets = new java.awt.Insets(2, 2, 0, 2);
            add(getValueLabel(), constraintsValueLabel);

            java.awt.GridBagConstraints constraintsExpressionTreeScroll =
                new java.awt.GridBagConstraints();
            constraintsExpressionTreeScroll.gridx = 0;
            constraintsExpressionTreeScroll.gridy = 3;
            constraintsExpressionTreeScroll.gridwidth = 10;
            constraintsExpressionTreeScroll.fill =
                    java.awt.GridBagConstraints.BOTH;
            constraintsExpressionTreeScroll.weightx = 1.0;
            constraintsExpressionTreeScroll.weighty = 0.6;
            constraintsExpressionTreeScroll.insets =
                    new java.awt.Insets(2, 2, 2, 2);
            add(getExpressionTreeScroll(), constraintsExpressionTreeScroll);

            java.awt.GridBagConstraints constraintsToolBar =
                new java.awt.GridBagConstraints();
            constraintsToolBar.gridx = 0;
            constraintsToolBar.gridy = 2;
            constraintsToolBar.gridwidth = 3;
            constraintsToolBar.fill = java.awt.GridBagConstraints.BOTH;
            add(getToolBar(), constraintsToolBar);
            initConnections();
        } catch (java.lang.Throwable ivjExc) {
            handleException(ivjExc);
        }

        // user code begin {2}
        reset();
        // user code end
    }

    public void notExpression() {
        if (getExpression() != null) {
            setExpression(getExpression().not());
        }
    }

    public void orExpression() {
        Expression newExpression = buildExpressionNode();
        if (newExpression == null) {
            return;
        }

        if (getExpression() == null) {
            setExpression(newExpression);
        } else {
            setExpression(getExpression().or(newExpression));
        }
    }

    public void reset() {
        resetAttributes();
        if (getOperatorCombo().getItemCount() == 0) {
            resetOperators();
        }
        setExpression(null);
    }

    public void resetAttributes() {
        if (getAttributeCombo().getItemCount() > 0) {
            getAttributeCombo().removeAllItems();
        }
        if (getDescriptor() != null) {
            for (Enumeration mappingsEnum =
                 getDescriptor().getMappings().elements();
                 mappingsEnum.hasMoreElements(); ) {
                DatabaseMapping mapping =
                    (DatabaseMapping)mappingsEnum.nextElement();
                if (mapping.isDirectToFieldMapping()) {
                    getAttributeCombo().addItem(mapping.getAttributeName());
                }
            }
        }
    }

    public void resetOperators() {
        getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.Equal));
        getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.NotEqual));
        getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.LessThan));
        getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.LessThanEqual));
        getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.GreaterThan));
        getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.GreaterThanEqual));
        getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.Like));
        getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.NotLike));
        //getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.In));
        //getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.NotIn));
        //getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.Between));
        //getOperatorCombo().addItem(ExpressionNode.getOperator(ExpressionOperator.NotBetween));
        getOperatorCombo().addItem(ExpressionNode.KeyWordAll);
        getOperatorCombo().addItem(ExpressionNode.KeyWordAny);
    }

    public void setDescriptor(ClassDescriptor descriptor) {
        this.descriptor = descriptor;
        reset();
    }

    public void setExpression(Expression expression) {
        this.expression = expression;
        ExpressionTreeModel model =
            new ExpressionTreeModel(new ExpressionNode(expression));
        getExpressionTree().setModel(model);
        for (int index = 0; index < getExpressionTree().getRowCount();
             index++) {
            getExpressionTree().expandRow(index);
        }
        getExpressionTree().repaint();
    }

    class IvjEventHandler implements java.awt.event.ActionListener {
        @Override
        public void actionPerformed(java.awt.event.ActionEvent e) {
            if (e.getSource() == ExpressionPanel.this.getOrButton()) {
                connEtoC1(e);
            }
            if (e.getSource() == ExpressionPanel.this.getAndButton()) {
                connEtoC2(e);
            }
            if (e.getSource() == ExpressionPanel.this.getNotBuuton()) {
                connEtoC3(e);
            }
            if (e.getSource() == ExpressionPanel.this.getClearButton()) {
                connEtoC4(e);
            }
        }
    }
}
