/**************************************************************
 * 
 * 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.uno.XComponentContext;
import com.sun.star.lib.uno.helper.Factory;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.lang.XInitialization;
import com.sun.star.lang.XTypeProvider;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.uno.Type;
import	com.sun.star.frame.XStatusListener;
import	com.sun.star.frame.XDispatchProvider;
import	com.sun.star.frame.XDispatch;
import	com.sun.star.frame.XModel;
import	com.sun.star.frame.XFrame;
import	com.sun.star.frame.DispatchDescriptor;
import com.sun.star.awt.XToolkit;
import com.sun.star.awt.XWindowPeer;
import com.sun.star.awt.XMessageBox;
import com.sun.star.awt.WindowAttribute;
import com.sun.star.awt.WindowClass;
import com.sun.star.awt.WindowDescriptor;
import com.sun.star.awt.Rectangle;

public class ProtocolHandlerAddon {
    /** This class implements the component. At least the interfaces XServiceInfo,
     * XTypeProvider, and XInitialization should be provided by the service.
     */
    public static class ProtocolHandlerAddonImpl extends WeakBase implements
                                                 XDispatchProvider,
                                                 XDispatch,                  
                                                 XInitialization,
                                                 XServiceInfo {

        /** The service name, that must be used to get an instance of this service.
         */
        static private final String[] m_serviceNames = { "com.sun.star.frame.ProtocolHandler" };
    
        /** The component context, that gives access to the service manager and all registered services.
         */
        private XComponentContext m_xCmpCtx;

        /** The toolkit, that we can create UNO dialogs.
         */
        private XToolkit m_xToolkit;

        /** The frame where the addon depends on.
         */
        private XFrame m_xFrame;
        private XStatusListener m_xStatusListener;

        
        /** The constructor of the inner class has a XMultiServiceFactory parameter.
         * @param xmultiservicefactoryInitialization A special service factory
         * could be introduced while initializing.
         */
        public ProtocolHandlerAddonImpl( XComponentContext xComponentContext ) {
            m_xCmpCtx = xComponentContext;
        }
    
        /** This method is a member of the interface for initializing an object
         * directly after its creation.
         * @param object This array of arbitrary objects will be passed to the
         * component after its creation.
         * @throws Exception Every exception will not be handled, but will be
         * passed to the caller.
         */
        public void initialize( Object[] object )
            throws com.sun.star.uno.Exception {

            if ( object.length > 0 )
            {
                m_xFrame = ( XFrame ) UnoRuntime.queryInterface(
                    XFrame.class, object[ 0 ] );
            }

            // Create the toolkit to have access to it later
            m_xToolkit = (XToolkit) UnoRuntime.queryInterface(
                XToolkit.class,
                m_xCmpCtx.getServiceManager().createInstanceWithContext("com.sun.star.awt.Toolkit",
                                                                        m_xCmpCtx));
        }
    
        /** This method returns an array of all supported service names.
         * @return Array of supported service names.
         */
        public String[] getSupportedServiceNames() {
            return getServiceNames();
        }

        public static String[] getServiceNames() {
            return m_serviceNames;
        }
        
        /** This method returns true, if the given service will be
         * supported by the component.
         * @param stringService Service name.
         * @return True, if the given service name will be supported.
         */
        public boolean supportsService( String sService ) {
            int len = m_serviceNames.length;
        
            for( int i=0; i < len; i++) {
                if ( sService.equals( m_serviceNames[i] ) )
                    return true;
            }
        
            return false;
        }
    
        /** Return the class name of the component.
         * @return Class name of the component.
         */
        public String getImplementationName() {
            return ProtocolHandlerAddonImpl.class.getName();
        }
        
        // XDispatchProvider
        public XDispatch queryDispatch( /*IN*/com.sun.star.util.URL aURL,
                                        /*IN*/String sTargetFrameName,
                                        /*IN*/int iSearchFlags ) {
            XDispatch xRet = null;
            if ( aURL.Protocol.compareTo("org.openoffice.Office.addon.example:") == 0 ) {
                if ( aURL.Path.compareTo( "Function1" ) == 0 )
                    xRet = this;
                if ( aURL.Path.compareTo( "Function2" ) == 0 )
                    xRet = this;
                if ( aURL.Path.compareTo( "Help" ) == 0 )
                    xRet = this;
            }
            return xRet;
        }
        
        public XDispatch[] queryDispatches( /*IN*/DispatchDescriptor[] seqDescripts ) {
            int nCount = seqDescripts.length;
            XDispatch[] lDispatcher = new XDispatch[nCount];
            
            for( int i=0; i<nCount; ++i )
                lDispatcher[i] = queryDispatch( seqDescripts[i].FeatureURL,
                                                seqDescripts[i].FrameName,
                                                seqDescripts[i].SearchFlags );
            
            return lDispatcher;           
        }

        // XDispatch
        public void dispatch( /*IN*/com.sun.star.util.URL aURL,
                              /*IN*/com.sun.star.beans.PropertyValue[] aArguments ) {
            
            if ( aURL.Protocol.compareTo("org.openoffice.Office.addon.example:") == 0 )
            {
                if ( aURL.Path.compareTo( "Function1" ) == 0 )
                {
                    showMessageBox("SDK DevGuide Add-On example", "Function 1 activated");
                }
                if ( aURL.Path.compareTo( "Function2" ) == 0 )
                {
                    showMessageBox("SDK DevGuide Add-On example", "Function 2 activated");
                }
                if ( aURL.Path.compareTo( "Help" ) == 0 )
                {
                    showMessageBox("About SDK DevGuide Add-On example", "This is the SDK Add-On example");
                }
            }
        }
        
        public void addStatusListener( /*IN*/XStatusListener xControl,
                                       /*IN*/com.sun.star.util.URL aURL ) {
        }
        
        public void removeStatusListener( /*IN*/XStatusListener xControl,
                                          /*IN*/com.sun.star.util.URL aURL ) {
        }

        public void showMessageBox(String sTitle, String sMessage) {
            try {
                if ( null != m_xFrame && null != m_xToolkit ) {

                    // describe window properties.
                    WindowDescriptor aDescriptor = new WindowDescriptor();
                    aDescriptor.Type              = WindowClass.MODALTOP;
                    aDescriptor.WindowServiceName = new String( "infobox" );
                    aDescriptor.ParentIndex       = -1;
                    aDescriptor.Parent            = (XWindowPeer)UnoRuntime.queryInterface(
                        XWindowPeer.class, m_xFrame.getContainerWindow());
                    aDescriptor.Bounds            = new Rectangle(0,0,300,200);
                    aDescriptor.WindowAttributes  = WindowAttribute.BORDER |
                        WindowAttribute.MOVEABLE |
                        WindowAttribute.CLOSEABLE;
                    
                    XWindowPeer xPeer = m_xToolkit.createWindow( aDescriptor );
                    if ( null != xPeer ) {
                        XMessageBox xMsgBox = (XMessageBox)UnoRuntime.queryInterface(
                            XMessageBox.class, xPeer);
                        if ( null != xMsgBox )
                        {
                            xMsgBox.setCaptionText( sTitle );
                            xMsgBox.setMessageText( sMessage );
                            xMsgBox.execute();
                        }
                    }
                }
            } catch ( com.sun.star.uno.Exception e) {
                // do your error handling 
            }
        }
    }
            
  
    /** Gives a factory for creating the service.
     * This method is called by the <code>JavaLoader</code>
     * <p>
     * @return Returns a <code>XSingleServiceFactory</code> for creating the
     * component.
     * @see com.sun.star.comp.loader.JavaLoader#
     * @param stringImplementationName The implementation name of the component.
     * @param xmultiservicefactory The service manager, who gives access to every
     * known service.
     * @param xregistrykey Makes structural information (except regarding tree
     * structures) of a single
     * registry key accessible.
     */
    public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) {
        XSingleComponentFactory xFactory = null;
    
        if ( sImplementationName.equals( ProtocolHandlerAddonImpl.class.getName() ) )
            xFactory = Factory.createComponentFactory(ProtocolHandlerAddonImpl.class,
                                                      ProtocolHandlerAddonImpl.getServiceNames());
        
        return xFactory;
    }
  
    /** Writes the service information into the given registry key.
     * This method is called by the <code>JavaLoader</code>.
     * @return returns true if the operation succeeded
     * @see com.sun.star.comp.loader.JavaLoader#
     * @see com.sun.star.lib.uno.helper.Factory#
     * @param xregistrykey Makes structural information (except regarding tree
     * structures) of a single
     * registry key accessible.
     */
    public static boolean __writeRegistryServiceInfo(
        XRegistryKey xRegistryKey ) {
        return Factory.writeRegistryServiceInfo(
            ProtocolHandlerAddonImpl.class.getName(),
            ProtocolHandlerAddonImpl.getServiceNames(),
            xRegistryKey );
  }
}
