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



import com.sun.star.beans.Property;
import com.sun.star.beans.PropertyValue;
import com.sun.star.lang.NullPointerException;
import com.sun.star.reflection.XConstantTypeDescription;
import com.sun.star.reflection.XIdlMethod;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.Type;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;



public class SwingTreeControlProvider implements XTreeControlProvider{
    private JTextArea jtxtGeneratedSourceCode = new JTextArea();
    private JTextField jtxtFilter = new JTextField();
    private javax.swing.JLabel jlblFilter = new javax.swing.JLabel("Set a filter");
    private JPanel jPnlBottom = new JPanel(new BorderLayout());
    private JPanel jPanelProgress = new JPanel(new BorderLayout());
    private JPanel jPnlPath = new JPanel(new BorderLayout());
    private JLabel jLblPath = new JLabel("Generated source code");
    private JProgressBar jProgressBar1 = new JProgressBar();
    private JTree jTree = new javax.swing.JTree();
    private XDialogProvider m_xDialogProvider;    
    private HideableTreeModel treeModel;
    private UnoTreeRenderer oUnoTreeRenderer;
    private InspectorPane m_oInspectorPane;
    private Object oUserDefinedObject = null;
    private boolean bIsUserDefined = false;
    private SwingUnoNode oRootNode;
    
    private final int nDIALOGWIDTH = 800;
    
    
    
    public SwingTreeControlProvider(XDialogProvider _xDialogProvider){
        m_xDialogProvider = _xDialogProvider;      
    }

    
    public void addInspectorPane(InspectorPane _oInspectorPane){
        m_oInspectorPane = _oInspectorPane;
    }
    
    public InspectorPane getInspectorPane() throws NullPointerException{
        if (m_oInspectorPane == null){
            throw new NullPointerException("InspectorPage has not been added to TreeControl");
        }
        else{
            return m_oInspectorPane;
        }
    }
    
    private void ComponentSelector(Object _oRootObject, String _sRootTreeNodeName) {
        String sTreeNodeName =  _sRootTreeNodeName;
        oRootNode = new SwingUnoNode(_oRootObject);
        oRootNode.setLabel(_sRootTreeNodeName);
        treeModel = new HideableTreeModel(oRootNode);
        jTree.setModel(treeModel);
        jTree.setRootVisible(true);           
        jTree.setVisible(true);
        oRootNode.setFoldable(true);
        enableFilterElements(null);
    }

    
    
    private void insertTopPanel(JPanel _jPnlCenter){
        javax.swing.JPanel jPnlTop = new javax.swing.JPanel(new BorderLayout(10, 10));
        jPnlTop.setPreferredSize(new java.awt.Dimension(nDIALOGWIDTH, 20));
        jlblFilter.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jlblFilter.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        jPnlTop.add(jlblFilter, java.awt.BorderLayout.WEST);
        jtxtFilter.setHorizontalAlignment(javax.swing.JTextField.LEFT);
        jtxtFilter.setPreferredSize(new java.awt.Dimension(200, 10));
        jtxtFilter.addKeyListener(new InspectorKeyFilterAdapter());
        jPnlTop.add(jtxtFilter, java.awt.BorderLayout.CENTER);
        _jPnlCenter.add(jPnlTop, java.awt.BorderLayout.NORTH);            
    }
    
    
    private void insertBottomPanel(JSplitPane _jSplitPane){ //JPanel _jPnlCenter){
        jtxtGeneratedSourceCode.setTabSize(4);
        jtxtGeneratedSourceCode.getAccessibleContext().setAccessibleName("generated SourceCode");
        JScrollPane jScrollPane = new JScrollPane(jtxtGeneratedSourceCode);
        jScrollPane.setPreferredSize(new Dimension(nDIALOGWIDTH,205));
        jtxtGeneratedSourceCode.setEditable(false);
        _jSplitPane.setBottomComponent(jScrollPane);
    }
    
        private void insertBorderPanes(Container _cp){
            JPanel jPnlEast  = new JPanel(new BorderLayout());
            JPanel jPnlNorth = new JPanel(new BorderLayout());
            JPanel jPnlSouth = new JPanel(new BorderLayout());
            JPanel jPnlWest = new JPanel(new BorderLayout());
            _cp.add(jPnlNorth, java.awt.BorderLayout.NORTH);
            jPnlWest.setPreferredSize(new java.awt.Dimension(10, 10));
            _cp.add(jPnlWest, java.awt.BorderLayout.WEST);
            jPnlEast.setPreferredSize(new java.awt.Dimension(10, 10));
            _cp.add(jPnlEast, java.awt.BorderLayout.EAST);
            jPnlSouth.setPreferredSize(new java.awt.Dimension(10, 10));
            _cp.add(jPnlSouth, java.awt.BorderLayout.SOUTH);
        }            
    
        
        public String enableFilterElements(XUnoNode _oUnoNode){
            String sFilter ="";
            boolean bIsFacetteNode = isFacetteNode(_oUnoNode);
            this.jtxtFilter.setEnabled(bIsFacetteNode);
            this.jlblFilter.setEnabled(bIsFacetteNode);
            sFilter = m_oInspectorPane.getFilter(_oUnoNode);
            jtxtFilter.setText(sFilter);
            return sFilter;
        }
        
        
        private class InspectorKeyFilterAdapter extends KeyAdapter{
            public void keyReleased(KeyEvent e){
                String sFilter = jtxtFilter.getText();
                SwingTreePathProvider oSwingTreePathProvider = new SwingTreePathProvider(jTree.getSelectionPath());
                XUnoNode oUnoNode = oSwingTreePathProvider.getLastPathComponent();
                if (oUnoNode instanceof XUnoFacetteNode){
                    m_oInspectorPane.applyFilter((XUnoFacetteNode) oUnoNode, sFilter);
                }
            }
        }
        
    
    
        /** Inspect the given object for methods, properties, interfaces, and
         * services.
         * @param a The object to inspect
         * @throws RuntimeException If
         */
        public Object inspect(java.lang.Object _oUserDefinedObject, String _sTitle) throws com.sun.star.uno.RuntimeException {
        JPanel jPnlContainer = new javax.swing.JPanel(new BorderLayout(10, 10));            
        try {
            javax.swing.JPanel jPnlCenter = new javax.swing.JPanel();
            bIsUserDefined = (_oUserDefinedObject != null);
            if (bIsUserDefined){
                oUserDefinedObject = _oUserDefinedObject;
                m_oInspectorPane.setTitle(_sTitle);
            }
            javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
            TreeSelectionModel tsm = new DefaultTreeSelectionModel();
            tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);            
            jTree.setSelectionModel(tsm);
            jTree.setVisible(false);
            jPnlCenter.setLayout(new java.awt.BorderLayout(10, 10));
            jPnlCenter.getAccessibleContext().setAccessibleName("inspection tab view");
            insertTopPanel(jPnlCenter);
            jScrollPane1.setViewportView(jTree);
            jScrollPane1.setPreferredSize(new java.awt.Dimension(600, 600));
            jScrollPane1.getAccessibleContext().setAccessibleName("API view scroll pane");
            
            JScrollBar jHScrollBar = jScrollPane1.createHorizontalScrollBar();
            jHScrollBar.getAccessibleContext().setAccessibleName("API view horizontal scroll bar");
            jScrollPane1.setHorizontalScrollBar(jHScrollBar);
            
            JScrollBar jVScrollBar = jScrollPane1.createVerticalScrollBar();
            jVScrollBar.getAccessibleContext().setAccessibleName("API view vertical scroll bar");
            jScrollPane1.setVerticalScrollBar(jVScrollBar);
            
            JSplitPane jSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
            jSplitPane.setTopComponent(jScrollPane1);
            jPnlCenter.add(jSplitPane, java.awt.BorderLayout.CENTER);
            jSplitPane.setDividerLocation(500);
            insertBottomPanel(jSplitPane);
            UnoTreeRenderer oUnoTreeRenderer = new UnoTreeRenderer();
            jTree.setCellRenderer(oUnoTreeRenderer);
            jTree.addTreeSelectionListener(
                new TreeSelectionListener() {
                    public void valueChanged(TreeSelectionEvent event) {
                        TreePath tp = event.getNewLeadSelectionPath();
                        if (tp != null){
                            XUnoNode oUnoNode = getSelectedNode();
                            String sFilter = enableFilterElements(oUnoNode);
                        }
                    }
                }
                );
            //  Add KeyListener for help
            jTree.addKeyListener( new java.awt.event.KeyAdapter() {
                public void keyReleased(java.awt.event.KeyEvent event) {
                    if ( event.getKeyCode() == KeyEvent.VK_F1 ) {
                        //  function key F1 pressed
                        TreePath aTreePath = jTree.getSelectionPath();
                        SwingUnoNode oUnoNode = (SwingUnoNode) aTreePath.getLastPathComponent();
                        oUnoNode.openIdlDescription(m_xDialogProvider.getIDLPath());
                    }
                }
            });
            jTree.addMouseListener(new MouseAdapter() {
                public void mousePressed (MouseEvent e) {
                    if (e.isPopupTrigger()){
                        m_oInspectorPane.showPopUpMenu(e.getComponent(), e.getX(), e.getY());
                    }
                    //unfortunately under Windows the method "isPopupTrigger" always returns false
                    else if ((e.getModifiersEx() & MouseEvent.BUTTON3_DOWN_MASK) == MouseEvent.BUTTON3_DOWN_MASK){
                        m_oInspectorPane.showPopUpMenu(e.getComponent(), e.getX(), e.getY());                        
                    }
                }
            });
            jPnlContainer.add(jPnlCenter, java.awt.BorderLayout.CENTER);            
            insertBorderPanes(jPnlContainer);
            if (this.bIsUserDefined){
                ComponentSelector(oUserDefinedObject, m_oInspectorPane.getTitle());
            }
            m_xDialogProvider.addInspectorPage(m_oInspectorPane.getTitle(), jPnlContainer);
            addTreeExpandListener();
            }
            catch( Exception exception ) {
                exception.printStackTrace(System.out);
            }            
            return jPnlContainer;
        }
    
        public HideableTreeModel getModel(){
            return  treeModel;
        }
        
        
        public void addTreeExpandListener(){
            jTree.addTreeWillExpandListener(
                new TreeWillExpandListener() {
                    public void treeWillExpand(javax.swing.event.TreeExpansionEvent event) throws javax.swing.tree.ExpandVetoException {
                        SwingTreePathProvider oSwingTreePathProvider = new SwingTreePathProvider(event.getPath());
                        XUnoNode oUnoNode = oSwingTreePathProvider.getLastPathComponent();
                        if (!m_oInspectorPane.expandNode(oUnoNode, oSwingTreePathProvider)){
                            throw new ExpandVetoException(event);
                        }
                    }

                    public void treeWillCollapse( javax.swing.event.TreeExpansionEvent evt) throws javax.swing.tree.ExpandVetoException {
                    }
            });
        }        
    
    
    public void setSourceCode(String _sSourceCode){
        jtxtGeneratedSourceCode.setText(_sSourceCode);
    }
    
    
    public XTreePathProvider getSelectedPath(){
        return new SwingTreePathProvider(jTree.getSelectionPath());
    }
    
    
    public void expandPath(XTreePathProvider _xTreePathProvider) throws ClassCastException{
        SwingTreePathProvider oSwingTreePathProvider = (SwingTreePathProvider) _xTreePathProvider;
        jTree.expandPath(oSwingTreePathProvider.getSwingTreePath());
    }
    
    
    public XUnoNode getSelectedNode(){            
        XUnoNode oUnoNode = null;
        TreePath aTreePath = jTree.getSelectionPath();
        Object oNode = aTreePath.getLastPathComponent();
        if (oNode instanceof XUnoNode){
            oUnoNode = (XUnoNode) oNode;
        }
        return oUnoNode;
    }

    
    public void nodeInserted(XUnoNode _oParentNode, XUnoNode _oChildNode, int index) {
        getModel().nodeInserted(_oParentNode, _oChildNode, _oParentNode.getChildCount()-1);
    }    
    
    
    public void nodeChanged(XUnoNode _oNode) {
        getModel().nodeChanged(_oNode);
    }
    
    
    public boolean setNodeVisible(Object node, boolean v) {    
       return getModel().setNodeVisible(node, v);
    }    
    

    public boolean isPropertyNode(XUnoNode _oUnoNode){
        return (_oUnoNode instanceof SwingUnoPropertyNode);
    }

    
    public boolean isMethodNode(XUnoNode _oUnoNode){
        return (_oUnoNode instanceof SwingUnoMethodNode);
    }


    public boolean isFacetteNode(XUnoNode _oUnoNode){
        return (_oUnoNode instanceof SwingUnoFacetteNode);
    }    

    
    public XUnoNode addUnoNode(Object _oUnoObject){
        return new SwingUnoNode(_oUnoObject);
    }
    
    
    public XUnoNode addUnoNode(Object _oUnoObject, Type _aType){
        return new SwingUnoNode(_oUnoObject, _aType);
    }
    
    
    public XUnoFacetteNode addUnoFacetteNode(XUnoNode _oParentNode, String _sNodeDescription, Object _oUnoObject){
        SwingUnoFacetteNode oSwingUnoFacetteNode = new SwingUnoFacetteNode(_oUnoObject);
        oSwingUnoFacetteNode.setLabel(_sNodeDescription);
        if (_oParentNode != null){
            ((SwingUnoNode) _oParentNode).addChildNode(oSwingUnoFacetteNode);
        }
        return oSwingUnoFacetteNode;
    }

    
    public XUnoMethodNode addMethodNode(Object _objectElement, XIdlMethod _xIdlMethod){
        SwingUnoMethodNode oSwingUnoMethodNode = new SwingUnoMethodNode(_xIdlMethod, _objectElement, m_xDialogProvider);
        return oSwingUnoMethodNode;
    }
    
    
    public XUnoPropertyNode addUnoPropertyNodeWithName(Property _aProperty){
        SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty);
        oUnoPropertyNode.setLabel("Name: " + _aProperty.Name);
        return oUnoPropertyNode;
    }

    
    public XUnoPropertyNode addUnoPropertyNodeWithHandle(Property _aProperty){
        SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty);
        oUnoPropertyNode.setLabel("Handle: " + _aProperty.Handle);
        return oUnoPropertyNode;
    }
    

    public XUnoPropertyNode addUnoPropertyNodeWithType(Property _aProperty){
        SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty);
        oUnoPropertyNode.setLabel("Type: " + _aProperty.Type.getTypeName());
        return oUnoPropertyNode;
    }
    
    
    public XUnoPropertyNode addUnoPropertyNodeWithAttributesDescription(Property _aProperty){
        SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty);
        XConstantTypeDescription[] xPropertyAttributesTypeDescriptions = Introspector.getIntrospector().getFieldsOfConstantGroup("com.sun.star.beans.PropertyAttribute");
        String sDisplay = Introspector.getIntrospector().getConstantDisplayString((int) _aProperty.Attributes, xPropertyAttributesTypeDescriptions, "Attributes: ");
        oUnoPropertyNode.setLabel(sDisplay);
        return oUnoPropertyNode;
    }
   
        
    public XUnoPropertyNode addUnoPropertyNode(Object _oUnoObject, Property _aProperty){
        SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty, _oUnoObject, null);
        oUnoPropertyNode.setPropertyNodeType(XUnoPropertyNode.nPROPERTYSETINFOTYPE);
        oUnoPropertyNode.setLabel(UnoPropertyNode.getStandardPropertyDescription(_aProperty, null));
        return oUnoPropertyNode;
    }
                
    
    public XUnoPropertyNode addUnoPropertyNode(Object _oUnoObject, Property _aProperty, Object _oUnoReturnObject){
        SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aProperty, _oUnoObject, _oUnoReturnObject);
        oUnoPropertyNode.setLabel(UnoPropertyNode.getStandardPropertyDescription(_aProperty, _oUnoReturnObject));
        return oUnoPropertyNode;
    }
    

    public XUnoPropertyNode addUnoPropertyNode(Object _oUnoObject, PropertyValue _aPropertyValue, Object _oReturnObject){
        SwingUnoPropertyNode oUnoPropertyNode = new SwingUnoPropertyNode(_aPropertyValue, _oUnoObject, _oReturnObject);
        oUnoPropertyNode.setLabel(UnoPropertyNode.getStandardPropertyValueDescription(_aPropertyValue));
        return oUnoPropertyNode;
    }
}
