/*
 * ExpressionEditor.java
 *
 * Created on 17 novembre 2003, 22.03
 */

package it.businesslogic.ireport.gui;
import it.businesslogic.ireport.CrosstabReportElement;
import it.businesslogic.ireport.ExpressionContext;
import it.businesslogic.ireport.SubDataset;
import it.businesslogic.ireport.crosstab.CrosstabGroup;
import it.businesslogic.ireport.crosstab.CrosstabParameter;
import javax.swing.tree.*;
import javax.swing.*;
import java.util.*;
/**
 *
 * @author  Administrator
 */
public class ExpressionEditor extends javax.swing.JDialog
{
   
    //public final static int CONTEXT_REPORT_DATASET = 0;
    //public final static int CONTEXT_BUCKET_MEASURE = 1;
    //public final static int CONTEXT_DATASET_RUN = 2;
    //public final static int CONTEXT_STYLE = 3;
    
    private SubDataset subDataset = null;
    private Vector crosstabElements = new Vector();
    
    public static Vector defaultExpressions = null;
    
    
    static {
        defaultExpressions = new Vector();
        defaultExpressions.add("( <condition> ? exp1 : exp2 )");
        defaultExpressions.add("msg(<pattern>, <arg0>)");
        defaultExpressions.add("msg(<pattern>, <arg0>, <arg1>)");
        defaultExpressions.add("msg(<pattern>, <arg0>, <arg1>, <arg2>)");
        defaultExpressions.add("str(<key>)");
        defaultExpressions.add("((net.sf.jasperreports.engine.data.JRXmlDataSource)$P{REPORT_DATA_SOURCE}).subDataSource(<select expression>)");
        defaultExpressions.add("((net.sf.jasperreports.engine.data.JRXmlDataSource)$P{REPORT_DATA_SOURCE}).dataSource(<select expression>)");
    }
        
   /** Creates new form ExpressionEditor */
   public ExpressionEditor()
   {
      initComponents();
      this.setSize(750, 450);
      
      this.setModal(true);
      //this.setModal(true);
      org.syntax.jedit.SyntaxDocument sd = new org.syntax.jedit.SyntaxDocument();
      sd.setTokenMarker(new org.syntax.jedit.tokenmarker.JavaTokenMarker() );
      
      this.jEditTextArea1.setDocument( sd );
      this.jEditTextArea1.getPainter().setEOLMarkersPainted(false);
      this.jEditTextArea1.getPainter().setInvalidLinesPainted(false);
      this.jEditTextArea1.getPainter().setLineHighlightEnabled(false);
        
      
      DefaultMutableTreeNode dmtn = new DefaultMutableTreeNode("root");
      
      this.jTree1.setCellRenderer(new DocumentExpressionEditorTreeCellRenderer());
      this.jTree1.setModel(new javax.swing.tree.DefaultTreeModel(dmtn));
      
      it.businesslogic.ireport.util.Misc.centerFrame(this);
      
      jList1.setModel(new DefaultListModel());

      jEditTextArea1.requestFocusInWindow();
      this.pack();
   }
   
   
   
   /** This method is called from within the constructor to
    * initialize the form.
    * WARNING: Do NOT modify this code. The content of this method is
    * always regenerated by the Form Editor.
    */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanel1 = new javax.swing.JPanel();
        jSplitPane1 = new javax.swing.JSplitPane();
        jPanel6 = new javax.swing.JPanel();
        jEditTextArea1 = new org.syntax.jedit.JEditTextArea();
        jSplitPane2 = new javax.swing.JSplitPane();
        jPanel4 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jList1 = new javax.swing.JList();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTree1 = new javax.swing.JTree();
        jPanel2 = new javax.swing.JPanel();
        jPanel5 = new javax.swing.JPanel();
        jButton2 = new javax.swing.JButton();
        jButton1 = new javax.swing.JButton();

        setTitle("Expression editor...");
        setModal(true);
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        jPanel1.setLayout(new java.awt.BorderLayout());

        jPanel1.setPreferredSize(new java.awt.Dimension(752, 416));
        jSplitPane1.setDividerSize(4);
        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPane1.setResizeWeight(0.5);
        jPanel6.setLayout(new java.awt.GridBagLayout());

        jEditTextArea1.setFont(new java.awt.Font("Courier New", 0, 11));
        jEditTextArea1.setMinimumSize(new java.awt.Dimension(20, 20));
        jEditTextArea1.setPreferredSize(new java.awt.Dimension(750, 150));
        jEditTextArea1.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                jEditTextArea1ComponentResized(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        jPanel6.add(jEditTextArea1, gridBagConstraints);

        jSplitPane1.setLeftComponent(jPanel6);

        jSplitPane2.setDividerSize(4);
        jSplitPane2.setResizeWeight(0.1);
        jSplitPane2.setAutoscrolls(true);
        jSplitPane2.setPreferredSize(new java.awt.Dimension(361, 160));
        jPanel4.setLayout(new java.awt.BorderLayout());

        jPanel4.setPreferredSize(new java.awt.Dimension(100, 100));
        jList1.setFont(new java.awt.Font("SansSerif", 0, 12));
        jList1.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jList1ValueChanged(evt);
            }
        });
        jList1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jList1MouseClicked(evt);
            }
        });

        jScrollPane1.setViewportView(jList1);

        jPanel4.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jSplitPane2.setRightComponent(jPanel4);
        jPanel4.getAccessibleContext().setAccessibleParent(jPanel1);

        jPanel3.setLayout(new java.awt.BorderLayout());

        jScrollPane2.setPreferredSize(new java.awt.Dimension(100, 100));
        jTree1.setRootVisible(false);
        jTree1.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                jTree1ValueChanged(evt);
            }
        });

        jScrollPane2.setViewportView(jTree1);

        jPanel3.add(jScrollPane2, java.awt.BorderLayout.CENTER);

        jSplitPane2.setLeftComponent(jPanel3);
        jPanel3.getAccessibleContext().setAccessibleParent(jPanel1);

        jSplitPane1.setBottomComponent(jSplitPane2);

        jPanel1.add(jSplitPane1, java.awt.BorderLayout.CENTER);

        getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);

        jPanel2.setLayout(new java.awt.GridBagLayout());

        jPanel2.setMinimumSize(new java.awt.Dimension(10, 30));
        jPanel2.setPreferredSize(new java.awt.Dimension(10, 30));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.weightx = 1.0;
        jPanel2.add(jPanel5, gridBagConstraints);

        jButton2.setMnemonic('a');
        jButton2.setText("Apply");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
        jPanel2.add(jButton2, gridBagConstraints);

        jButton1.setMnemonic('c');
        jButton1.setText("Cancel");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
        jPanel2.add(jButton1, gridBagConstraints);

        getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jList1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jList1MouseClicked
        
        if (evt.getButton() == evt.BUTTON1 && evt.getClickCount() == 2)
        {
            try {
            jEditTextArea1.getDocument().replace(jEditTextArea1.getSelectionStart(), 
                                             jEditTextArea1.getSelectionEnd()-jEditTextArea1.getSelectionStart(), 
                                             jList1.getSelectedValue()+"", null);
            } catch (Exception ex){}
        }
    }//GEN-LAST:event_jList1MouseClicked

    private void jList1ValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jList1ValueChanged
        
        
        
        
    }//GEN-LAST:event_jList1ValueChanged
        
    private void jTree1ValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_jTree1ValueChanged
       
       ( (DefaultListModel)jList1.getModel()).removeAllElements();
       
       //if (getSubDataset() == null) return;
       DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode)jTree1.getSelectionPath().getLastPathComponent();
       if (dmtn.getUserObject() instanceof CrosstabReportElementWrapper)
       {
           CrosstabReportElement cr = ((CrosstabReportElementWrapper)dmtn.getUserObject()).getCrosstabReportElement();
           Enumeration e = cr.getMeasures().elements();
           while (e.hasMoreElements())
           {
             String measure = ""+e.nextElement();
             ( (DefaultListModel)jList1.getModel()).addElement( "$V{"+measure+"}" );
             for (int j=0; j<cr.getRowGroups().size(); ++j)
             {
                CrosstabGroup group = (CrosstabGroup)cr.getRowGroups().elementAt(j);
                ((DefaultListModel)jList1.getModel()).addElement( "$V{"+measure+"_"+group.getName()+"_"+"ALL}");
             }
             for (int j=0; j<cr.getColumnGroups().size(); ++j)
             {
                CrosstabGroup group = (CrosstabGroup)cr.getColumnGroups().elementAt(j);
                ((DefaultListModel)jList1.getModel()).addElement( "$V{"+measure+"_"+group.getName()+"_"+"ALL}");
             }
           }
           
           for (int i=0; i<cr.getRowGroups().size(); ++i)
           {
                CrosstabGroup group = (CrosstabGroup)cr.getRowGroups().elementAt(i);
                ( (DefaultListModel)jList1.getModel()).addElement( "$V{"+group +"}" );
           }
            
           for (int i=0; i<cr.getColumnGroups().size(); ++i)
           {
                CrosstabGroup group = (CrosstabGroup)cr.getColumnGroups().elementAt(i);
                ( (DefaultListModel)jList1.getModel()).addElement( "$V{"+group +"}" );
           }
           

           for (int i=0; i<cr.getCrosstabParameters().size(); ++i)
           {
               CrosstabParameter parameter = (CrosstabParameter)cr.getCrosstabParameters().elementAt(i);
               ( (DefaultListModel)jList1.getModel()).addElement( "$P{"+parameter +"}" );
           }

       }
       else if ((""+dmtn.getUserObject()).equalsIgnoreCase("Fields") && getSubDataset() != null)
       {
          Enumeration e = getSubDataset().getFields().elements();
          while (e.hasMoreElements())
          {
             ( (DefaultListModel)jList1.getModel()).addElement( "$F{"+e.nextElement() +"}" );
          }
       }
       else if ((""+dmtn.getUserObject()).equalsIgnoreCase("Parameters") && getSubDataset() != null)
       {
          Enumeration e = getSubDataset().getParameters().elements();
          while (e.hasMoreElements())
          {
             ( (DefaultListModel)jList1.getModel()).addElement( "$P{"+ e.nextElement()+"}" );
          }
       }
       else if ((""+dmtn.getUserObject()).equalsIgnoreCase("Variables") && getSubDataset() != null)
       {
          Enumeration e = getSubDataset().getVariables().elements();
          while (e.hasMoreElements())
          {
             ( (DefaultListModel)jList1.getModel()).addElement( "$V{"+e.nextElement() +"}" );
          }
       }
       else if ((""+dmtn.getUserObject()).equalsIgnoreCase("Formulas"))
       {
           for (int i=0; i<defaultExpressions.size(); ++i)
           {
               ( (DefaultListModel)jList1.getModel()).addElement(defaultExpressions.elementAt(i));
           }
       }
    }//GEN-LAST:event_jTree1ValueChanged
    
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
       //this.setExpression( this.jEditTextArea1.getText() );
       this.setDialogResult( javax.swing.JOptionPane.NO_OPTION );
       this.dispose();
    }//GEN-LAST:event_jButton1ActionPerformed
    
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
       this.setExpression( this.jEditTextArea1.getText() );
       this.setDialogResult( javax.swing.JOptionPane.OK_OPTION );
       this.dispose();
    }//GEN-LAST:event_jButton2ActionPerformed
    
    private void jEditTextArea1ComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_jEditTextArea1ComponentResized
       // Add your handling code here:
    }//GEN-LAST:event_jEditTextArea1ComponentResized
    
    private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
       //this.jEditTextArea1.recalculateVisibleLines();
       this.jEditTextArea1.updateScrollBars();
    }//GEN-LAST:event_formComponentResized
    
    /** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
       
    }//GEN-LAST:event_exitForm
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[])
    {
       new ExpressionEditor().setVisible(true);
    }
    

    /** Getter for property Expression.
     * @return Value of property Expression.
     *
     */
    public java.lang.String getExpression()
    {
       return Expression;
    }
    
    /** Setter for property Expression.
     * @param Expression New value of property Expression.
     *
     */
    public void setExpression(java.lang.String Expression)
    {
       this.jEditTextArea1.setText( Expression );
       this.Expression = Expression;
    }
    
    /** Getter for property dialogResult.
     * @return Value of property dialogResult.
     *
     */
    public int getDialogResult()
    {
       return dialogResult;
    }
    
    /** Setter for property dialogResult.
     * @param dialogResult New value of property dialogResult.
     *
     */
    public void setDialogResult(int dialogResult)
    {
       this.dialogResult = dialogResult;
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private org.syntax.jedit.JEditTextArea jEditTextArea1;
    private javax.swing.JList jList1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JSplitPane jSplitPane2;
    private javax.swing.JTree jTree1;
    // End of variables declaration//GEN-END:variables
    
   
    private String Expression;
    
    private int dialogResult;

    public SubDataset getSubDataset() {
        return subDataset;
    }

    public void setSubDataset(SubDataset subDataset) {
        this.subDataset = subDataset;
        
        // Selezioniamo il campo fields....
        if (subDataset != null)
        {
            jEditTextArea1.getTokenMarker().setKeywordLookup(subDataset.getKeywordLookup());
        }
        updateTreeEntries();
        
    }
    
    public void updateTreeEntries() {
        
        
        DefaultMutableTreeNode root = (DefaultMutableTreeNode)jTree1.getModel().getRoot();
        
        root.removeAllChildren();
        
        if (getSubDataset() != null)
        {
            root.add( new DefaultMutableTreeNode("Fields"));
            root.add( new DefaultMutableTreeNode("Variables"));
            root.add( new DefaultMutableTreeNode("Parameters"));
        }
        
        for (int i=0; i<getCrosstabElements().size(); ++i)
        {
            root.add( new DefaultMutableTreeNode( new CrosstabReportElementWrapper( (CrosstabReportElement)getCrosstabElements().get(i))));
        }
        
        root.add( new DefaultMutableTreeNode("Formulas"));
        jTree1.expandPath(new TreePath(root));
        jTree1.updateUI();    
        jTree1.setSelectionRow(0);
    }

    public Vector getCrosstabElements() {
        return crosstabElements;
    }

    public void setCrosstabElements(Vector crosstabElements) {
        this.crosstabElements = crosstabElements;
    }
    
    
    public void addCrosstabReportElement(CrosstabReportElement re)
    {
        if (!this.getCrosstabElements().contains(re))
        {
            getCrosstabElements().add(re);
            updateTreeEntries();
        }
    }
    
    /**
     * Set an expression contex. If the passes expression context is null,
     * nothing is done...
     * The context replace all previos settings
     */
    public void setExpressionContext(ExpressionContext ec)
    {
        if ( ec == null) return;
        setCrosstabElements(ec.getCrosstabReportElements());
        
        setSubDataset(ec.getSubDataset());
    }
   
    
}

