/**************************************************************
 * 
 * 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.awt.Rectangle;
import com.sun.star.awt.XMessageBox;
import com.sun.star.awt.XMessageBoxFactory;
import com.sun.star.awt.XWindowPeer;
import com.sun.star.beans.NamedValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.container.XNameAccess;
import com.sun.star.frame.XModel;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.lib.uno.helper.Factory;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.ui.dialogs.XExecutableDialog;
import com.sun.star.ui.dialogs.XFolderPicker;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.CloseVetoException;
import com.sun.star.util.XChangesBatch;
import com.sun.star.util.XCloseable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import org.openoffice.XInstanceInspector;


/** The purpose of this class is to provide a factory for creating the service
 * (<CODE>__getServiceFactory</CODE>) and writes the information into the given
 * registry key (<CODE>__writeRegistryServiceInfo</CODE>).
 */
public class Inspector{
     public static final String sIDLDOCUMENTSUBFOLDER = "docs/common/ref/";

    
    /** This class implements the method of the interface XInstanceInspector.
     * Also the class implements the interfaces XServiceInfo, and XTypeProvider.
     */
    static public class _Inspector extends WeakBase implements XInstanceInspector, XServiceInfo{
    
        static private final String __serviceName = "org.openoffice.InstanceInspector";    
        private HashMap aApplicationHashMap = new HashMap();
        private String sTitle = "Object Inspector";
        private Vector aHiddenDocuments = new Vector();
//        private String[] sApplicationDocUrls = new String[]{"private:factory/swriter", "private:factory/scalc", "private:factory/simpress", "private:factory/sdraw", "private:factory/sbase"};
//        private String[] sApplicationDocNames = new String[]{"Text Document", "Spreadsheet", "Presentation", "Drawing", "Database"};
        private XComponentContext m_xComponentContext; 
        private HashMap aInspectorPanes = new HashMap();
        private XDialogProvider m_oSwingDialogProvider;
        private TDocSupplier oTDocSupplier;
        private Introspector m_oIntrospector = null;
        // TODO: improve these strings:
        private static final String sWRONGINSTALLATIONPATH = "Your selected path does not refer to an SDK-Installation!";
        /** Creates a new instance of Dialog */
        public _Inspector(XComponentContext _xComponentContext) {
            m_xComponentContext = _xComponentContext;
            m_oIntrospector = Introspector.getIntrospector(m_xComponentContext);
            aApplicationHashMap.put("private:factory/swriter", "Text Document");        
            aApplicationHashMap.put("private:factory/scalc", "Spreadsheet");
            aApplicationHashMap.put("private:factory/simpress", "Presentation");
            aApplicationHashMap.put("private:factory/sdraw", "Drawing");
            aApplicationHashMap.put("private:factory/smath", "Formula");
            m_oSwingDialogProvider = new SwingDialogProvider(this, sTitle);
//            aApplicationHashMap.put("private:factory/sbase", "Database");  
        }
        
        
        public XComponentContext getXComponentContext(){
            return m_xComponentContext;
        }
                        
        
        public HashMap getInspectorPages(){
            return aInspectorPanes;
        }
        
        
        protected String getSDKPath(){
        String sRetPath = "";
        try{
            XNameAccess xNameAccess  = getConfigurationAccess("org.openoffice.inspector.ObjectInspector", true);
            XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xNameAccess);
            sRetPath = (String) xPropertySet.getPropertyValue("SDKPath");   
        }catch( Exception exception ) {
            exception.printStackTrace(System.out);
        }
        return sRetPath;
        }
        
        
        public String getIDLPath(){
            String sRetPath = getSDKPath();
            if (m_oIntrospector.isValidSDKInstallationPath(sRetPath)){
                sRetPath = m_oIntrospector.addToPath(sRetPath, sIDLDOCUMENTSUBFOLDER);
            }
            else{
                sRetPath = "";
            }
            return sRetPath;
        }
        
        
        public void openIdlFileforSelectedNode(){
            InspectorPane oInspectorPane = m_oSwingDialogProvider.getSelectedInspectorPage();
            if (oInspectorPane != null){
                XUnoNode oUnoNode = oInspectorPane.getSelectedNode();
                if (oUnoNode != null){
                    String sPath = getIDLPath();
                    oUnoNode.openIdlDescription(sPath);
                }
            }
        }        
                
                
        public void assignSDKPath() {
        try {
            String sInstallationFolder = "";
            Object oFolderPicker = m_xComponentContext.getServiceManager().createInstanceWithContext("com.sun.star.ui.dialogs.FolderPicker", m_xComponentContext);
            XFolderPicker xFolderPicker = (XFolderPicker) UnoRuntime.queryInterface(XFolderPicker.class, oFolderPicker);
            XExecutableDialog xExecutable = (XExecutableDialog) UnoRuntime.queryInterface(XExecutableDialog.class, oFolderPicker);
            XComponent xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, oFolderPicker);
            String sPath = getSDKPath();
            if (!sPath.equals("")){
                xFolderPicker.setDisplayDirectory(sPath);
            }
            xFolderPicker.setTitle("Add the Path to your SDK installation");
            short nResult = xExecutable.execute();
            if (nResult == com.sun.star.ui.dialogs.ExecutableDialogResults.OK){
                sInstallationFolder = xFolderPicker.getDirectory();
                if (m_oIntrospector.isValidSDKInstallationPath(sInstallationFolder)){
                    XNameAccess xNameAccess = getConfigurationAccess(true);
                    XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xNameAccess);
                    xPropertySet.setPropertyValue("SDKPath", sInstallationFolder);
                    XChangesBatch xBatch = (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class, xNameAccess);
                    xBatch.commitChanges();                
                }
                else{
                    XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xFolderPicker);
                    Object oWindow = xPropertySet.getPropertyValue("Window");
                    XWindowPeer xWindowPeer = (XWindowPeer) UnoRuntime.queryInterface(XWindowPeer.class, oWindow);
                    showErrorMessageBox(xWindowPeer, sTitle, sWRONGINSTALLATIONPATH);
                    assignSDKPath();
                }
            }
            xComponent.dispose();
        }catch( Exception exception ) {
            exception.printStackTrace(System.out);
        }}
            
        
        public void showErrorMessageBox(XWindowPeer _xWindowPeer, String _sTitle, String _sMessage){
        try {
            Object oToolkit = m_xComponentContext.getServiceManager().createInstanceWithContext("com.sun.star.awt.Toolkit", m_xComponentContext);
            XMessageBoxFactory xMessageBoxFactory = (XMessageBoxFactory) UnoRuntime.queryInterface(XMessageBoxFactory.class, oToolkit);
            XMessageBox xMessageBox = xMessageBoxFactory.createMessageBox(_xWindowPeer, com.sun.star.awt.MessageBoxType.ERRORBOX, com.sun.star.awt.MessageBoxButtons.BUTTONS_OK, _sTitle, _sMessage);
            XComponent xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, xMessageBox);
            if (xMessageBox != null){
                short nResult = xMessageBox.execute();
                xComponent.dispose();
            }
        } catch (com.sun.star.uno.Exception ex) {
            ex.printStackTrace(System.out);
        }}
        
                
        public void inspect(java.lang.Object _oUserDefinedObject, String _sTitle) throws com.sun.star.uno.RuntimeException {
        try {
            int nPageIndex = m_oSwingDialogProvider.getInspectorPageCount();
            SwingTreeControlProvider oSwingTreeControlProvider = new SwingTreeControlProvider(m_oSwingDialogProvider);
            InspectorPane oInspectorPane = new InspectorPane(getXComponentContext(), m_oSwingDialogProvider, oSwingTreeControlProvider, getSourceCodeLanguage());
            oInspectorPane.inspect(_oUserDefinedObject, _sTitle);
            getInspectorPages().put(_sTitle, oInspectorPane);
            m_oSwingDialogProvider.show(nPageIndex);
        }catch( Exception exception ) {
            exception.printStackTrace(System.out);
        }}
                
        
        public void inspectOpenEmptyDocument(String _sApplicationDocUrl){
            XComponent xComponent = getTDocSupplier().openEmptyDocument(_sApplicationDocUrl);
            String sRootTitle = (String) aApplicationHashMap.get(_sApplicationDocUrl);
            inspect(xComponent, sRootTitle);
            aHiddenDocuments.add(xComponent);
        }
        
        
        public void inspectOpenDocument(String _sTDocUrl){
            String sTreeNodeName = getTDocSupplier().getTitleByTDocUrl(_sTDocUrl);
            XModel xTDocModel = getTDocSupplier().getXModelByTDocUrl(_sTDocUrl);
            inspect(xTDocModel, sTreeNodeName);
        }        
        
        
        public void inspectSelectedNode(){
            InspectorPane oInspectorPane = m_oSwingDialogProvider.getSelectedInspectorPage();
            if (oInspectorPane != null){
                XUnoNode oUnoNode = oInspectorPane.getSelectedNode();
                Object oUnoObject = oUnoNode.getUnoObject();
                if (oUnoObject != null){
                    String sNodeDescription = UnoNode.getNodeDescription(oUnoObject);
                    inspect(oUnoObject, sNodeDescription);
                }
            }
        }

        
        public void addSourceCodeOfSelectedNode(){
            InspectorPane oInspectorPane = m_oSwingDialogProvider.getSelectedInspectorPage();
            if (oInspectorPane != null){
                oInspectorPane.addSourceCodeOfSelectedNode();
            }
        }
        

        public void invokeSelectedMethod(){
            InspectorPane oInspectorPane = m_oSwingDialogProvider.getSelectedInspectorPage();
            if (oInspectorPane != null){
                oInspectorPane.invokeSelectedMethodNode();
            }
        }
                
        
        public void setSourceCodeLanguage(final int _nLanguage){
        try{
            String sLanguage = "Java";
            XNameAccess xNameAccess  = getConfigurationAccess("org.openoffice.inspector.ObjectInspector", true);
            XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xNameAccess);
            switch (_nLanguage){
                case XLanguageSourceCodeGenerator.nJAVA:
                    sLanguage = "Java";
                    break;
                case XLanguageSourceCodeGenerator.nCPLUSPLUS:
                    sLanguage = "CPlusPlus";
                    break;
                case XLanguageSourceCodeGenerator.nBASIC:
                    sLanguage = "Basic";
                    break;
                default:
                    System.out.println("Warning: Sourcecode language is not defined!");
            }
            xPropertySet.setPropertyValue("Language", sLanguage);
            XChangesBatch xBatch = (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class, xNameAccess);
            xBatch.commitChanges();
            for (int i = 0; i < m_oSwingDialogProvider.getInspectorPageCount(); i++){
                m_oSwingDialogProvider.getInspectorPage(i).convertCompleteSourceCode(_nLanguage);
            }
        }catch( Exception exception ) {
            exception.printStackTrace(System.out);
        }}
            
        
        private TDocSupplier getTDocSupplier(){
            if (oTDocSupplier == null){
                oTDocSupplier = new TDocSupplier(m_xComponentContext);        
            }
            return oTDocSupplier;
        }

        public String[] getTDocUrls(){
            return getTDocSupplier().getTDocUrls();
        }
        
        
        public String[] getTDocTitles(String[] _sTDocUrls){
            return getTDocSupplier().getTDocTitles(_sTDocUrls);
        }
      
        
        public String[][] getApplicationUrls(){
            Set aSet = aApplicationHashMap.keySet();
            String[][] sReturnList = new String[aSet.size()][];
            int n= 0;
            for ( Iterator i = aSet.iterator(); i.hasNext(); ){
                String[] sSingleApplication = new String[2];
                sSingleApplication[0] = (String) i.next();
                // assign the title in the second index
                sSingleApplication[1] = (String) aApplicationHashMap.get(sSingleApplication[0]);
                sReturnList[n++] = sSingleApplication;
            }
            return sReturnList;
        }

        
        public void disposeHiddenDocuments(){
            int nHiddenCount = aHiddenDocuments.size();
            if (nHiddenCount > 0){
                for (int i = nHiddenCount - 1; i >= 0; i--){
                    XComponent xComponent = (XComponent) aHiddenDocuments.get(i);
                    if (xComponent != null){
                        try {
                            XCloseable xCloseable = (XCloseable) UnoRuntime.queryInterface(XCloseable.class, xComponent);
                            xCloseable.close(true);
                            aHiddenDocuments.remove(i);
                        } catch (CloseVetoException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
        }
        
        
        public static String[] getServiceNames() {
            String[] sSupportedServiceNames = { __serviceName };
            return sSupportedServiceNames;
        }
        
        // Implement the interface XServiceInfo
        /** Get all supported service names.
         * @return Supported service names.
         */
        public String[] getSupportedServiceNames() {
            return getServiceNames();
        }
        
        // Implement the interface XServiceInfo
        /** Test, if the given service will be supported.
         * @param sService Service name.
         * @return Return true, if the service will be supported.
         */
        public boolean supportsService( String sServiceName ) {
            return sServiceName.equals( __serviceName );
        }
        
        // Implement the interface XServiceInfo
        /** Get the implementation name of the component.
         * @return Implementation name of the component.
         */
        public String getImplementationName() {
            return _Inspector.class.getName();
        }
        

        private int getSourceCodeLanguage(){
        int nLanguage = XLanguageSourceCodeGenerator.nJAVA;
        try{
            XNameAccess xNameAccess  = getConfigurationAccess("org.openoffice.inspector.ObjectInspector", false);
            String sLanguage = (String) xNameAccess.getByName("Language");
            if (sLanguage.toUpperCase().equals("JAVA")){
                nLanguage = XLanguageSourceCodeGenerator.nJAVA;
            }
            else if (sLanguage.toUpperCase().equals("BASIC")){
                nLanguage = XLanguageSourceCodeGenerator.nBASIC;                
            }
            else if (sLanguage.toUpperCase().equals("CPLUSPLUS")){
                nLanguage = XLanguageSourceCodeGenerator.nCPLUSPLUS;                
            }
            else{
                System.out.println("Warning: Sourcecode language " + sLanguage + " is not defined!");
            }
            m_oSwingDialogProvider.selectSourceCodeLanguage(nLanguage);
        }catch( Exception exception ) {
            exception.printStackTrace(System.out);
        }
            return nLanguage;
        }            
     
        
        public XNameAccess getConfigurationAccess(boolean _bUpdate){
            return getConfigurationAccess("org.openoffice.inspector.ObjectInspector", _bUpdate);
        }


        public XNameAccess getConfigurationAccess(String _sNodePath, boolean update) {
        XNameAccess xNameAccess = null;
        try {
            String sAccess = "";
            if (update) {
                sAccess = "com.sun.star.configuration.ConfigurationUpdateAccess";
            }
            else{
                sAccess = "com.sun.star.configuration.ConfigurationAccess";
            }
            XMultiComponentFactory xMCF = m_xComponentContext.getServiceManager();
            Object oDefaultProvider = xMCF.createInstanceWithContext("com.sun.star.configuration.DefaultProvider", this.getXComponentContext());
            XMultiServiceFactory xMSFCfg = (XMultiServiceFactory) UnoRuntime.queryInterface(XMultiServiceFactory.class, oDefaultProvider);        
            Object oAccess = xMSFCfg.createInstanceWithArguments(sAccess, new Object[]{new NamedValue("nodepath", _sNodePath)});
            xNameAccess = (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class, oAccess);
        } catch (com.sun.star.uno.Exception e) {  
        }
        return xNameAccess;
        }
        
        
    }
    
// end of inner class
    
    
    /**
     * Gives a factory for creating the service.
     * This method is called by the <code>JavaLoader</code>
     * <p>
     * @return  returns a <code>XSingleComponentFactory</code> for creating
     *          the component
     * @param   sImplName the name of the implementation for which a
     *          service is desired
     * @see     com.sun.star.comp.loader.JavaLoader
     */
    public static XSingleComponentFactory __getComponentFactory( String sImplName )
    {
        XSingleComponentFactory xFactory = null;
        if ( sImplName.equals( _Inspector.class.getName() ) )
            xFactory = Factory.createComponentFactory(_Inspector.class, _Inspector.getServiceNames());
        if ( xFactory == null )
            xFactory = InspectorAddon.__getComponentFactory(sImplName);
        return xFactory;
    }

    /**
     * Writes the service information into the given registry key.
     * This method is called by the <code>JavaLoader</code>
     * <p>
     * @return  returns true if the operation succeeded
     * @param   regKey the registryKey
     * @see     com.sun.star.comp.loader.JavaLoader
     */
    public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
        return (Factory.writeRegistryServiceInfo(_Inspector.class.getName(), _Inspector.getServiceNames(), regKey) 
                && InspectorAddon.__writeRegistryServiceInfo(regKey));
    }
}
    
