/**************************************************************
 * 
 * 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.Type;
import com.sun.star.uno.UnoRuntime; 
import com.sun.star.uno.XComponentContext;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.lang.XTypeProvider;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.lang.XSingleServiceFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lib.uno.helper.Factory;
import com.sun.star.comp.loader.FactoryHelper;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XDialogProvider2;
import com.sun.star.awt.XDialogEventHandler;
import com.sun.star.awt.XControl;
import com.sun.star.awt.XControlModel;
import com.sun.star.awt.XControlContainer;
import com.sun.star.beans.XPropertySet;
import com.sun.star.frame.XModel;
import com.sun.star.frame.XFrame;

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;
 
import com.sun.star.test.XTestDialogHandler;

// DialogComponent implements all necessary interfaces self, this is only
// for demonstration. More convenient is to use the impelmentation WeakBase or
// ComponentBase, see implementation of TestComponentA.
public class DialogComponent {

    // public static class _DialogComponent extends WeakBase 
	public static class _DialogComponent
		implements XTypeProvider, XServiceInfo, XTestDialogHandler, XDialogEventHandler {

		static final String __serviceName= "com.sun.star.test.TestDialogHandler";
 
   		static byte[] _implementationId;
		private XComponentContext m_xCmpCtx;
        
		private XFrame m_xFrame;
		private XToolkit m_xToolkit;

		public _DialogComponent(XComponentContext context) {
			m_xCmpCtx= context;

			try {
				// 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)); 
			}
			catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		// XTestDialogHandler
		public String createDialog( String DialogURL, XModel xModel, XFrame xFrame ) {
			m_xFrame = xFrame;
    
			try {
				XMultiComponentFactory xMCF = m_xCmpCtx.getServiceManager();
				Object obj;

				// If valid we must pass the XModel when creating a DialogProvider object
				if( xModel != null ) {
					Object[] args = new Object[1];
					args[0] = xModel;
                                   
					obj = xMCF.createInstanceWithArgumentsAndContext(
						"com.sun.star.awt.DialogProvider2", args, m_xCmpCtx );
				}
				else {
					obj = xMCF.createInstanceWithContext(
						"com.sun.star.awt.DialogProvider2", m_xCmpCtx );
				}

				XDialogProvider2 xDialogProvider = (XDialogProvider2)
					UnoRuntime.queryInterface( XDialogProvider2.class, obj );
						
				XDialog xDialog = xDialogProvider.createDialogWithHandler( DialogURL, this );
				if( xDialog != null )
					xDialog.execute();
			}
			catch (Exception e) {
				e.printStackTrace();
			}
			return "Created dialog \"" + DialogURL + "\"";
		}
    
		public void copyText( XDialog xDialog, Object aEventObject ) {
			XControlContainer xControlContainer = (XControlContainer)UnoRuntime.queryInterface(
				XControlContainer.class, xDialog );
			String aTextPropertyStr = "Text";
			String aText = "";
			XControl xTextField1Control = xControlContainer.getControl( "TextField1" );	
			XControlModel xControlModel1 = xTextField1Control.getModel();
			XPropertySet xPropertySet1 = (XPropertySet)UnoRuntime.queryInterface(
				XPropertySet.class, xControlModel1 );
			try
			{
				aText = (String)xPropertySet1.getPropertyValue( aTextPropertyStr );
			}
			catch (Exception e) {
				e.printStackTrace();
			}
  
			XControl xTextField2Control = xControlContainer.getControl( "TextField2" );	
			XControlModel xControlModel2 = xTextField2Control.getModel();
			XPropertySet xPropertySet2 = (XPropertySet)UnoRuntime.queryInterface(
				XPropertySet.class, xControlModel2 );
			try
			{
				xPropertySet2.setPropertyValue( aTextPropertyStr, aText );
			}
			catch (Exception e) {
				e.printStackTrace();
			}

			showMessageBox( "DialogComponent", "copyText() called" );
		}

		public void handleEvent() {
			showMessageBox( "DialogComponent", "handleEvent() called" );
		}
    
		public void handleEventWithArguments( XDialog xDialog, Object aEventObject ) {
			showMessageBox( "DialogComponent", "handleEventWithArguments() called\n\n" +
				"Event Object = " + aEventObject );
		}

		private final String aHandlerMethod1 = "doit1";
		private final String aHandlerMethod2 = "doit2";
		private final String aHandlerMethod3 = "doit3";

		//XDialogEventHandler
		public boolean callHandlerMethod( /*IN*/XDialog xDialog, /*IN*/Object EventObject, /*IN*/String MethodName ) {
			if ( MethodName.equals( aHandlerMethod1 ) )
			{
				showMessageBox( "DialogComponent", "callHandlerMethod() handled \"" + aHandlerMethod1 + "\"" );
				return true;
			}
			else if ( MethodName.equals( aHandlerMethod2 ) )
			{
				showMessageBox( "DialogComponent", "callHandlerMethod() handled \"" + aHandlerMethod2 + "\"" );
				return true;
			}
			else if ( MethodName.equals( aHandlerMethod3 ) )
			{
				showMessageBox( "DialogComponent", "callHandlerMethod() handled \"" + aHandlerMethod3 + "\"" );
				return true;
			}
			return false;
		}

		public String[] getSupportedMethodNames() {
			String[] retValue= new String[3];
			retValue[0]= aHandlerMethod1;
			retValue[1]= aHandlerMethod2;
			retValue[2]= aHandlerMethod3;
			return retValue;
		}


		//XTypeProvider
		public com.sun.star.uno.Type[] getTypes(  ) {
			Type[] retValue= new Type[4];
			retValue[0]= new Type( XServiceInfo.class);
			retValue[1]= new Type( XTypeProvider.class);
			retValue[2]= new Type( XTestDialogHandler.class);
			retValue[3]= new Type( XDialogEventHandler.class);
			return retValue;
		}
		//XTypeProvider
		synchronized public byte[] getImplementationId(  ) {
			if (_implementationId == null) {
				_implementationId= new byte[16];
				int hash = hashCode();
				_implementationId[0] = (byte)(hash & 0xff);
				_implementationId[1] = (byte)((hash >>> 8) & 0xff);
				_implementationId[2] = (byte)((hash >>> 16) & 0xff);
				_implementationId[3] = (byte)((hash >>>24) & 0xff);
			}
			return _implementationId;
		}



        /** This method is a simple helper function to used in the
         * static component initialisation functions as well as in
         * getSupportedServiceNames.
         */
        public static String[] getServiceNames() {
            String[] sSupportedServiceNames = { __serviceName };
            return sSupportedServiceNames;
        }
      
		//XServiceInfo
        public String[] getSupportedServiceNames() {
            return getServiceNames();
        }

		//XServiceInfo
        public boolean supportsService( String sServiceName ) {
            return sServiceName.equals( __serviceName );
        }
    
		//XServiceInfo
        public String getImplementationName() {
            // return  DialogComponent.class.getName();
            return  _DialogComponent.class.getName();
        }        

        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>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( _DialogComponent.class.getName() ) )
            xFactory = Factory.createComponentFactory(_DialogComponent.class,
                                             _DialogComponent.getServiceNames());
        
        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
     */
    // This method not longer necessary since OOo 3.4 where the component registration
    // was changed to passive component registration. For more details see
    // http://wiki.services.openoffice.org/wiki/Passive_Component_Registration

//    public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
//         return Factory.writeRegistryServiceInfo(_DialogComponent.class.getName(),
//                                                 _DialogComponent.getServiceNames(),
//                                                 regKey);
//    }
}
