/*
 * 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) --{@literal >} 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) --{@literal >} 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) --{@literal >} 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) --{@literal >} 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<DatabaseMapping> mappingsEnum =
                 getDescriptor().getMappings().elements();
                 mappingsEnum.hasMoreElements(); ) {
                DatabaseMapping mapping =
                        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);
            }
        }
    }
}
