/*
 * DocumentStructurePanel.java
 *
 * Created on 25 novembre 2005, 11.34
 */

package it.businesslogic.ireport.gui.documentstructure;
import it.businesslogic.ireport.ElementGroup;
import it.businesslogic.ireport.gui.MainFrame;
import it.businesslogic.ireport.gui.event.CrosstabLayoutChangedListener;
import it.businesslogic.ireport.gui.event.ReportListener;
import it.businesslogic.ireport.gui.event.SubDatasetObjectChangedListener;
import javax.swing.tree.DefaultTreeSelectionModel;
import it.businesslogic.ireport.gui.*;
import it.businesslogic.ireport.*;
import it.businesslogic.ireport.crosstab.CrosstabCell;
import it.businesslogic.ireport.crosstab.gui.CrosstabEditorPanel;
import it.businesslogic.ireport.gui.docking.GenericDragTargetListener;
import it.businesslogic.ireport.gui.event.*;
import java.util.Enumeration;
import java.util.Vector;
import javax.swing.tree.TreePath;
import it.businesslogic.ireport.undo.UnGroupEmentsOperation;
import java.awt.dnd.DropTarget;
import java.util.ArrayList;
import java.util.List;
/**
 *
 * @author  Administrator
 */
public class CrosstabStructurePanel extends javax.swing.JPanel implements ReportListener, SubDatasetObjectChangedListener, CrosstabLayoutChangedListener {
    
    private boolean dontHandleEvent = false;
    
    private JReportFrame oldJReportFrame = null;
    private CrosstabReportElement crosstabReportElement = null;
    private CrosstabEditorPanel oldCrosstabEditorPanel = null;
            
    /** Creates new form DocumentStructurePanel */
    public CrosstabStructurePanel() {
        initComponents();
        
        DefaultTreeSelectionModel dtsm = (DefaultTreeSelectionModel)jTreeDocument.getSelectionModel();
        dtsm.setSelectionMode( DefaultTreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION );
        
        DocumentStructureTreeNode rootDoc = new DocumentStructureTreeNode("Crosstab");
        javax.swing.tree.DefaultTreeModel modelDoc = new javax.swing.tree.DefaultTreeModel(rootDoc);
        
        jTreeDocument.setDropTarget(new DropTarget(this, new GenericDragTargetListener()));
        
        jTreeDocument.setModel( modelDoc );
        jTreeDocument.setCellRenderer( new DocumentStructureTreeCellRenderer());
    }
    
    /** 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() {
        jPopupMenuDocumentStructure = new javax.swing.JPopupMenu();
        jMenuItemDS_properties = new javax.swing.JMenuItem();
        jMenuItemDSB_crosstabProperties1 = new javax.swing.JMenuItem();
        jSeparator22 = new javax.swing.JSeparator();
        jMenuItemMoveUp = new javax.swing.JMenuItem();
        jMenuItemMoveDown = new javax.swing.JMenuItem();
        jSeparator23 = new javax.swing.JSeparator();
        jMenuItemDS_cut = new javax.swing.JMenuItem();
        jMenuItemDS_copy = new javax.swing.JMenuItem();
        jMenuItemDS_paste = new javax.swing.JMenuItem();
        jMenuItemDS_delete = new javax.swing.JMenuItem();
        jPopupMenuDocumentStructureCell = new javax.swing.JPopupMenu();
        jMenuItemDSB_crosstabProperties = new javax.swing.JMenuItem();
        jMenuItemDSB_properties = new javax.swing.JMenuItem();
        jPopupMenuDocumentStructureGroup = new javax.swing.JPopupMenu();
        jMenuItemUngroup = new javax.swing.JMenuItem();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTreeDocument = new javax.swing.JTree();

        jMenuItemDS_properties.setText("Properties");
        jMenuItemDS_properties.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemDS_propertiesActionPerformed(evt);
            }
        });

        jPopupMenuDocumentStructure.add(jMenuItemDS_properties);

        jMenuItemDSB_crosstabProperties1.setText("Crosstab properties");
        jMenuItemDSB_crosstabProperties1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemDSB_crosstabPropertiesjMenuItemDSB_propertiesActionPerformed1(evt);
            }
        });

        jPopupMenuDocumentStructure.add(jMenuItemDSB_crosstabProperties1);

        jPopupMenuDocumentStructure.add(jSeparator22);

        jMenuItemMoveUp.setText("Move up");
        jMenuItemMoveUp.setEnabled(false);
        jMenuItemMoveUp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemMoveUpActionPerformed(evt);
            }
        });

        jPopupMenuDocumentStructure.add(jMenuItemMoveUp);

        jMenuItemMoveDown.setText("Move down");
        jMenuItemMoveDown.setEnabled(false);
        jMenuItemMoveDown.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemMoveDownActionPerformed(evt);
            }
        });

        jPopupMenuDocumentStructure.add(jMenuItemMoveDown);

        jPopupMenuDocumentStructure.add(jSeparator23);

        jMenuItemDS_cut.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/cut.png")));
        jMenuItemDS_cut.setText("Cut");
        jMenuItemDS_cut.setEnabled(false);
        jMenuItemDS_cut.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemDS_cutActionPerformed(evt);
            }
        });

        jPopupMenuDocumentStructure.add(jMenuItemDS_cut);

        jMenuItemDS_copy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/copy.png")));
        jMenuItemDS_copy.setText("Copy");
        jMenuItemDS_copy.setEnabled(false);
        jMenuItemDS_copy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemDS_copyActionPerformed(evt);
            }
        });

        jPopupMenuDocumentStructure.add(jMenuItemDS_copy);

        jMenuItemDS_paste.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/paste.png")));
        jMenuItemDS_paste.setText("Paste");
        jMenuItemDS_paste.setEnabled(false);
        jMenuItemDS_paste.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemDS_pasteActionPerformed(evt);
            }
        });

        jPopupMenuDocumentStructure.add(jMenuItemDS_paste);

        jMenuItemDS_delete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/delete.png")));
        jMenuItemDS_delete.setText("Delete");
        jMenuItemDS_delete.setEnabled(false);
        jMenuItemDS_delete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemDS_deleteActionPerformed(evt);
            }
        });

        jPopupMenuDocumentStructure.add(jMenuItemDS_delete);

        jMenuItemDSB_crosstabProperties.setText("Crosstab properties");
        jMenuItemDSB_crosstabProperties.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemDSB_propertiesActionPerformed1(evt);
            }
        });

        jPopupMenuDocumentStructureCell.add(jMenuItemDSB_crosstabProperties);

        jMenuItemDSB_properties.setText("Cell properties");
        jMenuItemDSB_properties.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemDSB_propertiesActionPerformed(evt);
            }
        });

        jPopupMenuDocumentStructureCell.add(jMenuItemDSB_properties);

        jMenuItemUngroup.setText("Ungroup");
        jMenuItemUngroup.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemUngroupActionPerformed(evt);
            }
        });

        jPopupMenuDocumentStructureGroup.add(jMenuItemUngroup);

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

        jTreeDocument.addTreeExpansionListener(new javax.swing.event.TreeExpansionListener() {
            public void treeCollapsed(javax.swing.event.TreeExpansionEvent evt) {
                jTreeDocumentTreeCollapsed(evt);
            }
            public void treeExpanded(javax.swing.event.TreeExpansionEvent evt) {
                jTreeDocumentTreeExpanded(evt);
            }
        });
        jTreeDocument.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                jTreeDocumentValueChanged(evt);
            }
        });
        jTreeDocument.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jTreeDocumentMousePressed(evt);
            }
        });

        jScrollPane2.setViewportView(jTreeDocument);

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

    }// </editor-fold>//GEN-END:initComponents

    private void jMenuItemDSB_crosstabPropertiesjMenuItemDSB_propertiesActionPerformed1(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemDSB_crosstabPropertiesjMenuItemDSB_propertiesActionPerformed1
        it.businesslogic.ireport.crosstab.gui.CrosstabPropertiesDialog cpd = new it.businesslogic.ireport.crosstab.gui.CrosstabPropertiesDialog(MainFrame.getMainInstance(),true);
        cpd.setCurrentCrosstabReportElement( getCrosstabReportElement() );
        cpd.setVisible(true);  
    }//GEN-LAST:event_jMenuItemDSB_crosstabPropertiesjMenuItemDSB_propertiesActionPerformed1

    private void jMenuItemDSB_propertiesActionPerformed1(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemDSB_propertiesActionPerformed1

        it.businesslogic.ireport.crosstab.gui.CrosstabPropertiesDialog cpd = new it.businesslogic.ireport.crosstab.gui.CrosstabPropertiesDialog(MainFrame.getMainInstance(),true);
        cpd.setCurrentCrosstabReportElement( getCrosstabReportElement() );
        cpd.setVisible(true);  

    }//GEN-LAST:event_jMenuItemDSB_propertiesActionPerformed1

    private void jMenuItemUngroupActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemUngroupActionPerformed

        if (jTreeDocument.getSelectionCount() > 0) {
            DocumentStructureTreeNode elementNode = (DocumentStructureTreeNode)jTreeDocument.getSelectionPath().getLastPathComponent();
            if (elementNode.getUserObject() instanceof ElementGroup) {
                String elementGroupName = ((ElementGroup)elementNode.getUserObject()).getName();
                while ( ((DocumentStructureTreeNode)elementNode.getParent()).getUserObject() instanceof ElementGroup)
                {
                    elementNode = (DocumentStructureTreeNode)elementNode.getParent();
                    elementGroupName = ((ElementGroup)elementNode.getUserObject()).getName() + "." + elementGroupName;
                }
                
                String newElementGroupName = elementGroupName;
                if (newElementGroupName.lastIndexOf(".")>=0)
                {
                    newElementGroupName = newElementGroupName.substring(0,newElementGroupName.lastIndexOf("."));
                }
                else
                {
                    newElementGroupName = "";
                }
                
                /************************/
                UnGroupEmentsOperation undoOp = new UnGroupEmentsOperation(MainFrame.getMainInstance().getActiveReportFrame());
                Vector elements = getCrosstabReportElement().getElements();
                for (int i=0; i<elements.size(); ++i)
                {
                    ReportElement element = (ReportElement)elements.elementAt(i);
                    String oldElementGroupName = element.getElementGroup();
                    if (element.getElementGroup().startsWith(elementGroupName+".") || element.getElementGroup().equals(elementGroupName))
                    {
                         String tmpElementGroupName = element.getElementGroup().substring(elementGroupName.length());
                         if (tmpElementGroupName.length() == 0) tmpElementGroupName = newElementGroupName;
                         tmpElementGroupName = newElementGroupName + tmpElementGroupName;
                         if (tmpElementGroupName.startsWith(".")) tmpElementGroupName = tmpElementGroupName.substring(1);
                         
                        element.setElementGroup(tmpElementGroupName);
                        undoOp.addElement(element, i,i, oldElementGroupName, tmpElementGroupName);
                    }
                }
                        
                MainFrame.getMainInstance().getActiveReportFrame().addUndoOperation(undoOp);
                
                MainFrame.getMainInstance().getActiveReportFrame().fireReportListenerReportElementsChanged(new ReportElementChangedEvent(MainFrame.getMainInstance().getActiveReportFrame(), new Vector() , ReportElementChangedEvent.REMOVED ));  
            }
        }        
        // Get group name...
        
        
    }//GEN-LAST:event_jMenuItemUngroupActionPerformed

    private void jTreeDocumentTreeCollapsed(javax.swing.event.TreeExpansionEvent evt) {//GEN-FIRST:event_jTreeDocumentTreeCollapsed
           //System.out.println("collapsing..." + evt.getPath());
    }//GEN-LAST:event_jTreeDocumentTreeCollapsed

    private void jTreeDocumentTreeExpanded(javax.swing.event.TreeExpansionEvent evt) {//GEN-FIRST:event_jTreeDocumentTreeExpanded
           // System.out.println("expanding..." + evt.getPath());
            
        
    }//GEN-LAST:event_jTreeDocumentTreeExpanded

    private void jMenuItemDSB_propertiesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemDSB_propertiesActionPerformed
if (jTreeDocument.getSelectionCount() > 0) {
            DocumentStructureTreeNode elementNode = (DocumentStructureTreeNode)jTreeDocument.getSelectionPath().getLastPathComponent();
            if (elementNode.getUserObject() instanceof CrosstabCell) {
                CrosstabCell thisCell = ((CrosstabCell)elementNode.getUserObject());
                MainFrame.getMainInstance().getActiveReportFrame().getSelectedCrosstabEditorPanel().editCell(thisCell);
            }
        }
    }//GEN-LAST:event_jMenuItemDSB_propertiesActionPerformed

    private void jMenuItemDS_deleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemDS_deleteActionPerformed
    MainFrame.getMainInstance().getActiveReportFrame().getSelectedCrosstabEditorPanel().deleteSelectedElements();
    }//GEN-LAST:event_jMenuItemDS_deleteActionPerformed

    private void jMenuItemDS_pasteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemDS_pasteActionPerformed
MainFrame.getMainInstance().getActiveReportFrame().paste();
    }//GEN-LAST:event_jMenuItemDS_pasteActionPerformed

    private void jMenuItemDS_copyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemDS_copyActionPerformed
MainFrame.getMainInstance().getActiveReportFrame().copy();
    }//GEN-LAST:event_jMenuItemDS_copyActionPerformed

    private void jMenuItemDS_cutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemDS_cutActionPerformed
MainFrame.getMainInstance().getActiveReportFrame().cut();
    }//GEN-LAST:event_jMenuItemDS_cutActionPerformed

    private void jMenuItemMoveDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemMoveDownActionPerformed
if (MainFrame.getMainInstance().getActiveReportFrame() != null) {
            JReportFrame jrf = MainFrame.getMainInstance().getActiveReportFrame();
            jrf.moveDown();
                       
            if (jrf.getSelectedCrosstabEditorPanel().getSelectedElements().size()>0)
                updateDocumentStructureTree(jrf, getCrosstabReportElement());
            
        }
    }//GEN-LAST:event_jMenuItemMoveDownActionPerformed

    private void jMenuItemMoveUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemMoveUpActionPerformed
 if (MainFrame.getMainInstance().getActiveReportFrame() != null) {
         JReportFrame jrf = MainFrame.getMainInstance().getActiveReportFrame();
         jrf.moveUp();
         this.jTreeDocument.updateUI();

         if (jrf.getSelectedCrosstabEditorPanel().getSelectedElements().size()>0)
             updateDocumentStructureTree(jrf, getCrosstabReportElement());
        }
        
    }//GEN-LAST:event_jMenuItemMoveUpActionPerformed

    private void jMenuItemDS_propertiesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemDS_propertiesActionPerformed
      MainFrame.getMainInstance().getElementPropertiesDialog().setVisible(true);
      //MainFrame.getMainInstance().getElementPropertiesDialog().updateSelection();
    }//GEN-LAST:event_jMenuItemDS_propertiesActionPerformed

    private void jTreeDocumentValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_jTreeDocumentValueChanged
          if (isDontHandleEvent()) return;
 
                // Get active jrf...
                if (MainFrame.getMainInstance().getActiveReportFrame() != null) {
                    //dontHandleEvent = true;
                    try {
                        JReportFrame jrf = MainFrame.getMainInstance().getActiveReportFrame();
                        Vector elementsToSelect = new Vector();

                        TreePath[] path = jTreeDocument.getSelectionPaths();


                        for (int i=0; i<path.length; ++i) {
                            DocumentStructureTreeNode elementNode = (DocumentStructureTreeNode)path[i].getLastPathComponent();
                            if (elementNode.getUserObject() instanceof ReportElement) {
                                elementsToSelect.addElement( (ReportElement)elementNode.getUserObject());
                            }
                            else if (path.length == 1) {
                                jrf.getSelectedCrosstabEditorPanel().setSelectedElement(null);
                                return;
                            }
                            else if (elementNode.getUserObject() instanceof ElementGroup)
                            {
                                
                                jrf.getSelectedCrosstabEditorPanel().setSelectedElement(null);
                                return;
                            }
                        }

                        jrf.getSelectedCrosstabEditorPanel().setSelectedElement(null);
                        Enumeration e = elementsToSelect.elements();
                        while (e.hasMoreElements()) {
                            jrf.getSelectedCrosstabEditorPanel().addSelectedElement((ReportElement)e.nextElement(), false);
                        }
                        jrf.getSelectedCrosstabEditorPanel().fireSelectionChangedEvent();
                    } catch (Exception ex)
                    {}
                    //
                }
    }//GEN-LAST:event_jTreeDocumentValueChanged

    private void jTreeDocumentMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTreeDocumentMousePressed
 if (evt.getButton() == evt.BUTTON3) {
            if (MainFrame.getMainInstance().getActiveReportFrame() != null) {
                JReportFrame jrf = MainFrame.getMainInstance().getActiveReportFrame();
                jTreeDocument.setSelectionPath( jTreeDocument.getPathForLocation(evt.getX(), evt.getY() ) );
                if (jTreeDocument.getSelectionCount() > 0) {
                    DocumentStructureTreeNode elementNode = (DocumentStructureTreeNode)jTreeDocument.getSelectionPath().getLastPathComponent();
                    if (elementNode.getUserObject() instanceof ReportElement) {
                        // (ReportElement)elementNode.getUserObject());
                        this.jPopupMenuDocumentStructure.show(jTreeDocument, evt.getPoint().x, evt.getPoint().y);
                        
                    } else if (elementNode.getUserObject() instanceof CrosstabCell) {
                        // (ReportElement)elementNode.getUserObject());
                        this.jPopupMenuDocumentStructureCell.show(jTreeDocument, evt.getPoint().x, evt.getPoint().y);

                    } else if (elementNode.getUserObject() instanceof ElementGroup) {
                        // (ReportElement)elementNode.getUserObject());
                        this.jPopupMenuDocumentStructureGroup.show(jTreeDocument, evt.getPoint().x, evt.getPoint().y);
                        
                    }
                }
            }
            
        }
        else if (evt.getButton() == evt.BUTTON1 && evt.getClickCount() == 2) {
          
            if (MainFrame.getMainInstance().getActiveReportFrame() != null) {
                      
                JReportFrame jrf = MainFrame.getMainInstance().getActiveReportFrame();
                if (jrf.getSelectedCrosstabEditorPanel().getSelectedElements().size() > 0) {
                    MainFrame.getMainInstance().getElementPropertiesDialog().setVisible(true);
                    MainFrame.getMainInstance().getElementPropertiesDialog().updateSelection();
                }
            }
        }
    }//GEN-LAST:event_jTreeDocumentMousePressed
    
    public void printSelectedPaths(String prefix)
    {
        try {
                       Enumeration enum_extended_paths = jTreeDocument.getExpandedDescendants(new TreePath(new Object[]{ jTreeDocument.getModel().getRoot() }));
                       if (enum_extended_paths != null)
                       {
                                  while (enum_extended_paths.hasMoreElements())
                                  {
                                   TreePath path = (TreePath)enum_extended_paths.nextElement();
                                   //System.out.println(prefix+ " "+path);
                               }
                       } 
                } catch (Exception ex)
                {
                    ex.printStackTrace();
                }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem jMenuItemDSB_crosstabProperties;
    private javax.swing.JMenuItem jMenuItemDSB_crosstabProperties1;
    private javax.swing.JMenuItem jMenuItemDSB_properties;
    private javax.swing.JMenuItem jMenuItemDS_copy;
    private javax.swing.JMenuItem jMenuItemDS_cut;
    private javax.swing.JMenuItem jMenuItemDS_delete;
    private javax.swing.JMenuItem jMenuItemDS_paste;
    private javax.swing.JMenuItem jMenuItemDS_properties;
    private javax.swing.JMenuItem jMenuItemMoveDown;
    private javax.swing.JMenuItem jMenuItemMoveUp;
    private javax.swing.JMenuItem jMenuItemUngroup;
    private javax.swing.JPopupMenu jPopupMenuDocumentStructure;
    private javax.swing.JPopupMenu jPopupMenuDocumentStructureCell;
    private javax.swing.JPopupMenu jPopupMenuDocumentStructureGroup;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSeparator jSeparator22;
    private javax.swing.JSeparator jSeparator23;
    private javax.swing.JTree jTreeDocument;
    // End of variables declaration//GEN-END:variables
    
    
    
    public void saveSelection()
    {
        List openedPaths = null;
        try {
            
                openedPaths = new ArrayList();
                Enumeration enum_extended_paths = jTreeDocument.getExpandedDescendants(new TreePath(new Object[]{ jTreeDocument.getModel().getRoot() }));
                if (enum_extended_paths!=null)
                {
                    while (enum_extended_paths.hasMoreElements())
                    {
                        TreePath path = (TreePath)enum_extended_paths.nextElement();
                        openedPaths.add( ((DocumentStructureTreeNode)path.getLastPathComponent()).getNodeId() );
                    }
                }
           } catch (Exception ex)
           {
                ex.printStackTrace();
           }

        if (oldCrosstabEditorPanel != null) oldCrosstabEditorPanel.setOpenedNodesDocumentStructure( openedPaths );
    }
    
    
    public void updateDocumentStructureTree(JReportFrame jrf, CrosstabReportElement crosstabReportElement)
    {
        
        
        List openedPaths = null;
        
        try {
            
                openedPaths = new ArrayList();
                Enumeration enum_extended_paths = jTreeDocument.getExpandedDescendants(new TreePath(new Object[]{ jTreeDocument.getModel().getRoot() }));
                if (enum_extended_paths!=null)
                {
                    while (enum_extended_paths.hasMoreElements())
                    {
                        TreePath path = (TreePath)enum_extended_paths.nextElement();
                        openedPaths.add( ((DocumentStructureTreeNode)path.getLastPathComponent()).getNodeId() );
                    }
                }
           } catch (Exception ex)
           {
                ex.printStackTrace();
           }
        
        if (jrf != null && jrf.getSelectedCrosstabEditorPanel() != oldCrosstabEditorPanel)
        {
            if (oldCrosstabEditorPanel != null) oldCrosstabEditorPanel.setOpenedNodesDocumentStructure( openedPaths );
            if (jrf != null && jrf.getSelectedCrosstabEditorPanel() != null)
            {
                openedPaths = jrf.getSelectedCrosstabEditorPanel().getOpenedNodesDocumentStructure();
                oldCrosstabEditorPanel = jrf.getSelectedCrosstabEditorPanel();
            }
            else
            {
                oldCrosstabEditorPanel = null;
            }
             
        }
        
        if (getCrosstabReportElement() != null && getCrosstabReportElement() != crosstabReportElement)
        {
            getCrosstabReportElement().removeCrosstabLayoutChangedListener(this);
        }
        
        this.setCrosstabReportElement( crosstabReportElement );
        
        if (getCrosstabReportElement() != null)
        {
            this.getCrosstabReportElement().addCrosstabLayoutChangedListener( this );
        }
                
        setDontHandleEvent(true);
        // Update the document tree structure...
        ((DocumentStructureTreeNode)this.jTreeDocument.getModel().getRoot()).removeAllChildren();
        ((javax.swing.tree.DefaultTreeModel)(this.jTreeDocument.getModel())).reload();
        
        if (jrf != null && getCrosstabReportElement() != null)
        {
            
            
            Enumeration cells = getCrosstabReportElement().getCells().elements();
            while (cells.hasMoreElements())
            {
                CrosstabCell cell = (CrosstabCell)cells.nextElement();
                DocumentStructureTreeNode bandNode = new DocumentStructureTreeNode(cell);
                ((DocumentStructureTreeNode)this.jTreeDocument.getModel().getRoot()).add( bandNode);    
                
                Enumeration elements = getCrosstabReportElement().getElements().elements();
                while (elements.hasMoreElements())
                {
                    ReportElement element = (ReportElement)elements.nextElement();
                    if (element.getCell() == cell)
                    {
                        String elementGroup = element.getElementGroup();
                        try {
                            if (element.getParentElement() != null)
                            {
                                DocumentStructureTreeNode parentNode = findElementTreeNode(element.getParentElement(),true);
                                if (parentNode != null)
                                {
                                    addElementToGroup(parentNode, elementGroup, element, openedPaths);
                                    if (openedPaths != null && openedPaths.contains(parentNode.getNodeId()))
                                    {   
                                        this.expandPath(parentNode);
                                    }
                                }
                            }
                            else
                            {
                                addElementToGroup(bandNode, elementGroup, element, openedPaths);
                            }
                            
                        } catch (Exception ex)
                        {
                            ex.printStackTrace();
                        }
                    }
                }
                if (openedPaths != null && openedPaths.contains(bandNode.getNodeId()))
                {   
                    this.expandPath(bandNode);
                }
            }
            setDontHandleEvent(false);
            if (jrf.getSelectedCrosstabEditorPanel() != null)
            {
                this.reportElementsSelectionChanged(new ReportElementsSelectionEvent(jrf, getCrosstabReportElement(), jrf.getSelectedCrosstabEditorPanel().getSelectedElements()));
            }
        }

        oldJReportFrame = jrf;
        setCrosstabReportElement( crosstabReportElement);
        
        jTreeDocument.updateUI();
    }
    
    public void addElementToGroup(DocumentStructureTreeNode parentNode, String subGroup, ReportElement element, List openedPaths)
    {
        // 1. We have to find the group node...
        if (subGroup.equals(""))
        {
            DocumentStructureTreeNode newNode = new DocumentStructureTreeNode(element);
            parentNode.add( newNode);
            
            if (openedPaths != null && openedPaths.contains(newNode.getNodeId()))
            {
                expandPath( (DocumentStructureTreeNode)newNode);
            }
            
            return;
        }
        String levelGroupName = "";
        if (subGroup.indexOf(".")>=0)
        {
            levelGroupName = subGroup.substring(0, subGroup.indexOf("."));
            subGroup = subGroup.substring(subGroup.indexOf(".")+1);
        }
        else
        {
            levelGroupName = subGroup;
            subGroup = "";
        }
        
        // 2. Look for the node named levelGroupName
        for (int i =0; i<parentNode.getChildCount(); ++i)
        {
            DocumentStructureTreeNode dmtn = (DocumentStructureTreeNode)parentNode.getChildAt(i);
            if (dmtn.getUserObject() != null && dmtn.getUserObject() instanceof ElementGroup)
            {
                ElementGroup ge = (ElementGroup)dmtn.getUserObject();
                if (ge.getName().equals( levelGroupName ))
                {
                    addElementToGroup(dmtn, subGroup, element, openedPaths);
                    return;
                }
            }
        }
        
        // Node doesn't exists....
        DocumentStructureTreeNode dmtn = new DocumentStructureTreeNode(new ElementGroup(levelGroupName));
        parentNode.add( dmtn );     
        addElementToGroup(dmtn, subGroup, element, openedPaths);
        
        if (openedPaths != null && openedPaths.contains(dmtn.getNodeId()))
        {
            expandPath( (DocumentStructureTreeNode)dmtn);
        }
        
        
    }
    
    public void expandPath(DocumentStructureTreeNode node)
    {
       //if (node.getChildCount() == 0) return;
        try {
            if (node.getParent() != null)
            {
                expandPath((DocumentStructureTreeNode)node.getParent());
            }
            jTreeDocument.expandPath(new TreePath(((DocumentStructureTreeNode)node).getPath() ));
        } catch (Exception ex)
        {
            ex.printStackTrace();
        }
     }
    
    
    public void crosstabLayoutChanged(CrosstabLayoutChangedEvent evt) {
        
        if (evt.getCrosstabReportElement() == getCrosstabReportElement())
        {
            
            this.updateDocumentStructureTree(  MainFrame.getMainInstance().getActiveReportFrame() , getCrosstabReportElement());
        }
    }
    
    public void reportElementsChanged(ReportElementChangedEvent evt) {
        
        if (evt.getType() == ReportElementChangedEvent.CHANGED) {
            for (int ir=0; ir<evt.getElements().size(); ++ir)
            {
                ReportElement re = (ReportElement)evt.getElements().elementAt(ir);
                
                DocumentStructureTreeNode node = findElementTreeNode(re, true);
                if (node == null) {
                    // This node has changed your band....
                    // Find the node based on objects availables....
                    node = findElementTreeNode(re, false);
                    if (node == null) return; // This should not happen....
                    // Remove from your parent....
                    node.removeFromParent();
                    // Add to the new parent...
                    DocumentStructureTreeNode root = (DocumentStructureTreeNode)jTreeDocument.getModel().getRoot();
                    for (int i=0; i<root.getChildCount(); ++i) {
                        DocumentStructureTreeNode bandNode = (DocumentStructureTreeNode)root.getChildAt(i);
                        if (bandNode.getUserObject() == re.band) {
                            bandNode.add( node );
                            setDontHandleEvent(true);
                            if (evt.getJReportFrame().getSelectedCrosstabEditorPanel().getSelectedElements().contains( re )) {
                                jTreeDocument.getSelectionModel().addSelectionPath(new TreePath(new Object[]
                                {root, bandNode,node}));
                            }
                            setDontHandleEvent(false);
                            break;
                        }
                    }
                }
            }
            jTreeDocument.updateUI();
        }
        else if (evt.getType() == ReportElementChangedEvent.REMOVED) {

            updateDocumentStructureTree( MainFrame.getMainInstance().getActiveReportFrame(), getCrosstabReportElement());
            jTreeDocument.updateUI();
        }
        else if (evt.getType() == ReportElementChangedEvent.ADDED) {
            
            updateDocumentStructureTree( MainFrame.getMainInstance().getActiveReportFrame(),getCrosstabReportElement() );
            jTreeDocument.updateUI();
        }
         
        
    }//end reportElementsChanged
    
    

    public void reportElementsSelectionChanged(ReportElementsSelectionEvent evt) {
        
        if (evt.getCrosstabReportElement() == null) return;
        setDontHandleEvent(true);
        
        TreePath[] path = jTreeDocument.getSelectionPaths();
        if (path != null && evt.getSelectedElements() != null && evt.getSelectedElements().size() == 0 &&
         ( ((DocumentStructureTreeNode) path[0].getLastPathComponent()).getUserObject() instanceof CrosstabCell
            || ((DocumentStructureTreeNode) path[0].getLastPathComponent()).getUserObject() instanceof ElementGroup)) {
            setDontHandleEvent(false);
            return;
        }
        
        jTreeDocument.getSelectionModel().clearSelection();
        
        
        java.util.Vector v = evt.getSelectedElements();
        Enumeration e = v.elements();
        while (e.hasMoreElements()) {
            ReportElement re = (ReportElement)e.nextElement();
            // looking for it in the tree...
            //1. Search the band...
            DocumentStructureTreeNode enode = findElementTreeNode( re, true);
            //TreePath treePath = findReportElement((DocumentStructureTreeNode)jTreeDocument.getModel().getRoot(), re);
            if (enode != null)
            {
                jTreeDocument.getSelectionModel().addSelectionPath(new TreePath(enode.getPath()));
            }
            
        }
        
        setDontHandleEvent(false);
        
    }
    
    /**
     *     If searchInYourBandOnly == true
     *     This method Look for the userObject re in elements contained in the same band
     *     of the element. This method MUST CHECK that the report IS in the band
     *     assigned. If not it must return null. The reason is that if the element
     *     is not found in your band, it has changed the band attribute and must be updated.
     */
    public DocumentStructureTreeNode findElementTreeNode( ReportElement re, boolean searchInYourCellOnly) {
        // looking for it in the tree...
        //1. Search the band...
        DocumentStructureTreeNode root = (DocumentStructureTreeNode)jTreeDocument.getModel().getRoot();
        for (int i=0; i<root.getChildCount(); ++i) {
            DocumentStructureTreeNode cellNode = (DocumentStructureTreeNode)root.getChildAt(i);
            if (!searchInYourCellOnly || cellNode.getUserObject() == re.getCell()) {
                
                DocumentStructureTreeNode newchild = findElementInTreeNode(cellNode,re);
                if (newchild != null) return newchild;
            }
        }
        return null;
    }

    public DocumentStructureTreeNode findElementInTreeNode(DocumentStructureTreeNode parentNode, ReportElement re)
    {
        for (int k=0; k<parentNode.getChildCount(); ++k) {
            DocumentStructureTreeNode child = (DocumentStructureTreeNode)parentNode.getChildAt(k);
            if (child.getUserObject() == re) {
                return child;
            }
            if (!re.getElementGroup().equals("") || re.getParentElement() != null)
            {
                if (child.getUserObject() instanceof ElementGroup ||
                    child.getUserObject() instanceof FrameReportElement)
                {
                    DocumentStructureTreeNode newchild = findElementInTreeNode(child,re);
                    if (newchild != null) return newchild;
                }
            }
        }
        return null;
    }
    
    public boolean isDontHandleEvent() {
        return dontHandleEvent;
    }

    public void setDontHandleEvent(boolean dontHandleEvent) {
        this.dontHandleEvent = dontHandleEvent;
    }
    
    public void applyI18n(){
        jMenuItemDS_cut.setText(it.businesslogic.ireport.util.I18n.getString("cut","Cut"));
        jMenuItemDS_copy.setText(it.businesslogic.ireport.util.I18n.getString("copy","Copy"));
        jMenuItemDS_paste.setText(it.businesslogic.ireport.util.I18n.getString("paste","Paste"));
        jMenuItemDS_delete.setText(it.businesslogic.ireport.util.I18n.getString("delete","Delete"));
        jMenuItemMoveUp.setText(it.businesslogic.ireport.util.I18n.getString("moveUp","Move up"));
        jMenuItemMoveDown.setText(it.businesslogic.ireport.util.I18n.getString("moveDown","Move down"));
        jMenuItemDSB_properties.setText(it.businesslogic.ireport.util.I18n.getString("cellProperties","Cell properties"));
        jMenuItemDS_properties.setText(it.businesslogic.ireport.util.I18n.getString("properties","Properties"));
        jMenuItemDS_cut.setText(it.businesslogic.ireport.util.I18n.getString("cut","Cut"));
        jMenuItemDS_copy.setText(it.businesslogic.ireport.util.I18n.getString("copy","Copy"));
        jMenuItemDS_paste.setText(it.businesslogic.ireport.util.I18n.getString("paste","Paste"));
        jMenuItemDS_delete.setText(it.businesslogic.ireport.util.I18n.getString("delete","Delete"));
        jMenuItemMoveUp.setText(it.businesslogic.ireport.util.I18n.getString("moveUp","Move up"));
        jMenuItemMoveDown.setText(it.businesslogic.ireport.util.I18n.getString("moveDown","Move down"));
        jMenuItemDSB_properties.setText(it.businesslogic.ireport.util.I18n.getString("cellProperties","Cell properties"));
        jMenuItemDS_properties.setText(it.businesslogic.ireport.util.I18n.getString("properties","Properties"));
        
    }  

    public void subDatasetObjectChanged(SubDatasetObjectChangedEvent evt) {
        
    }
    
    public void setCutCopyEnabled(boolean enabled) {
        this.jMenuItemDS_cut.setEnabled(enabled);
        this.jMenuItemDS_copy.setEnabled(enabled);
        this.jMenuItemDS_delete.setEnabled(enabled);
    }
    
    public void setPasteEnebled(boolean enabled) {
        this.jMenuItemDS_paste.setEnabled(enabled);
    }

    public CrosstabReportElement getCrosstabReportElement() {
        return crosstabReportElement;
    }

    public void setCrosstabReportElement(CrosstabReportElement crosstabReportElement) {
        this.crosstabReportElement = crosstabReportElement;
    }

    public void reportBandChanged(ReportBandChangedEvent evt) {
    }

    public void crosstabMeasureChanged(CrosstabLayoutChangedEvent evt) {
    }


}
