package mit.rmi.ui ;

public class ClientComponent
extends mit.swing.xJComponent
implements	mit.comm.event.DisplayResultRaiser
	,	mit.util.event.NewAppRaiser
	,	mit.comm.event.HostRaiser
	,	mit.rmi.event.MethodResponseRaiser
	,	mit.event.Listener
{
	private mit.event.RaiserAdapter raiserAdapter = new mit.event.RaiserAdapter( this ) ;
	public mit.event.RaiserAdapter getRaiserAdapter() { return this.raiserAdapter ; }
	public void setRaiserAdapter( mit.event.RaiserAdapter raiserAdapter ) { this.raiserAdapter = raiserAdapter ; }

	private mit.event.ListenerAdapter listenerAdapter = new mit.event.ListenerAdapter( this ) ;
	public mit.event.ListenerAdapter getListenerAdapter() { return this.listenerAdapter ; }
	public void setListenerAdapter( mit.event.ListenerAdapter listenerAdapter ) { this.listenerAdapter = listenerAdapter ; }

	private mit.rmi.Client client = null ;
	private boolean clientAuthenticated = false ;

	private byte[] serviceTicket = null ;
	public byte[] getServiceTicket() { return this.serviceTicket ; }
	public void setServiceTicket( byte[] serviceTicket ) { this.serviceTicket = serviceTicket ; }

	private String host = null ;
	public String getHost() { return this.host ; }
	public void setHost( String host ) { this.host = host ; }

	private Integer port = null ;
	public Integer getPort() { return this.port ; }
	public void setPort( Integer port ) { this.port = port ; }

	private String service = "rcmd" ;
	public String getService() { return this.service ; }
	public void setService( String service ) { this.service = service ; }

	private String status = null ;
	public String getStatus() { return this.status ; }
	public void setStatus( String status ) { this.status = status ; }

	private String statusMessage = null ;
	public String getStatusMessage() { return this.statusMessage ; }
	public void setStatusMessage( String statusMessage ) { this.statusMessage = statusMessage ; }

	private javax.swing.JComponent resultsComponent = null ;
	public javax.swing.JComponent getResultsComponent() { return this.resultsComponent ; }
	public void setResultsComponent( javax.swing.JComponent resultsComponent ) { this.resultsComponent = resultsComponent ; }

	private java.util.Vector criteriaComponents = null ;
	public java.util.Vector getCriteriaComponents() { return this.criteriaComponents ; }
	public void setCriteriaComponents( java.util.Vector criteriaComponents ) { this.criteriaComponents = criteriaComponents ; }

	private mit.swing.xJButton[] actionButtons = null ;
	public mit.swing.xJButton[] getActionButtons() { return this.actionButtons ; }
	public void setActionButtons( mit.swing.xJButton[] actionButtons ) { this.actionButtons = actionButtons ; }

	private Object methodResponse = null ;
	public Object getMethodResponse() { return this.methodResponse ; }
	public void setMethodResponse( Object methodResponse ) { this.methodResponse = methodResponse ; }

	private String methodName = null ;
	public String getMethodName() { return this.methodName ; }
	public void setMethodName( String methodName ) { this.methodName = methodName ; }

	public void eventRaised( mit.event.Event e )
	{
		try
		{
			if( e instanceof mit.util.event.ClearEvent )
			{
				HandleClearEvent( ( mit.util.event.ClearEvent ) e ) ;
			}
			else if( e instanceof mit.rmi.event.HostEvent )
			{
				HandleHostEvent( ( mit.rmi.event.HostEvent ) e ) ;
			}
			else if( e instanceof mit.rmi.event.PortEvent )
			{
				HandlePortEvent( ( mit.rmi.event.PortEvent ) e ) ;
			}
			else if( e instanceof mit.rmi.event.TestEvent )
			{
				HandleTestEvent( ( mit.rmi.event.TestEvent ) e ) ;
			}
			else if( e instanceof mit.util.event.ValidServiceEvent )
			{
				HandleValidServiceEvent( ( mit.util.event.ValidServiceEvent ) e ) ;
			}
			else if( e instanceof mit.rmi.event.InvokeMethodEvent )
			{
				HandleInvokeMethodEvent( ( mit.rmi.event.InvokeMethodEvent ) e ) ;
			}
		}
		catch( Throwable ex )
		{
			ex.printStackTrace() ;
		}
	}

	private void resetAll()
	{
		setHost( null ) ;
		setPort( null ) ;
		setStatus( null ) ;
		setStatusMessage( null ) ;
	}

	private void HandleInvokeMethodEvent( mit.rmi.event.InvokeMethodEvent e )
	throws Throwable
	{
System.out.println( "ClientComponent.HandleInvokeMethodEvent" ) ;
		if( null != getServiceTicket() )
		{
			validateClient() ;
			mit.rmi.event.InvokeMethodRaiser r = ( mit.rmi.event.InvokeMethodRaiser ) e.getSource() ;
			if( ! clientAuthenticated )
			{
				clientAuthenticated = client.authenticate( getServiceTicket() ).booleanValue() ;
			}
			setMethodName( r.getMethodName() ) ;
System.out.println( "ClientComponent.HandleInvokeMethodEvent object: " + r.getObject() ) ;
System.out.println( "ClientComponent.HandleInvokeMethodEvent methodName: " + r.getMethodName() ) ;
System.out.println( "ClientComponent.HandleInvokeMethodEvent argTypes: " + r.getArgTypes() ) ;
System.out.println( "ClientComponent.HandleInvokeMethodEvent args: " + r.getArgs() ) ;
			setMethodResponse( client.invoke( r.getObject() , r.getMethodName() , r.getArgTypes() , r.getArgs() ) ) ;
System.out.println( "ClientComponent.HandleInvokeMethodEvent methodResponse raised" ) ;
			( new mit.rmi.event.MethodResponseEvent( this ) ).raise() ;
System.out.println( "ClientComponent.HandleInvokeMethodEvent done" ) ;
		}
	}

	private void HandleTestEvent( mit.rmi.event.TestEvent e )
	throws Throwable
	{
		if( null != getServiceTicket() )
		{
			validateClient() ;
			if( ! clientAuthenticated )
			{
				clientAuthenticated = client.authenticate( getServiceTicket() ).booleanValue() ;
			}
			setStatusMessage( ( String ) client.invoke( new mit.rmi.TestObject() , "getMessage" , new Class[ 0 ] , new Object[ 0 ] ) ) ;
			( new mit.comm.event.DisplayResultEvent( this ) ).raise() ;
			( new mit.util.event.NewAppEvent( this ) ).raise() ;
		}
	}

	private void HandleValidServiceEvent( mit.util.event.ValidServiceEvent e )
	throws Throwable
	{
		mit.util.event.ValidServiceRaiser r = ( mit.util.event.ValidServiceRaiser ) e.getSource() ;
		setServiceTicket( r.getServiceTicket() ) ;

		String ticketFilename = new String( getHost() + ".ticket" ) ;
		setBytes( ticketFilename , getServiceTicket() ) ;
		System.out.println( "Ticket written to: " + ticketFilename ) ;
	}

	private static void setBytes( String filename , byte[] bytes )
	throws Throwable
	{
		java.io.FileOutputStream out = new java.io.FileOutputStream( filename ) ;
		for( int i = 0 ; bytes.length != i ; i ++ )
		{
			out.write( bytes[ i ] ) ;
		}
		out.close() ;
	}

	private void HandleClearEvent( mit.util.event.ClearEvent e )
	{
		resetAll() ;
	}

	private void HandleHostEvent( mit.rmi.event.HostEvent e )
	{
		mit.rmi.event.HostRaiser r = ( mit.rmi.event.HostRaiser ) e.getSource() ;
		setHost( r.getHost() ) ;
		raiseCommHostEvent() ;
	}

	private void HandlePortEvent( mit.rmi.event.PortEvent e )
	{
		mit.rmi.event.PortRaiser r = ( mit.rmi.event.PortRaiser ) e.getSource() ;
		setPort( r.getPort() ) ;
		raiseCommHostEvent() ;
	}

	private void raiseCommHostEvent()
	{
		if
		( ( null != getHost() )
		&&( null != getPort() )
		&&( null != getService() )
		)
		{
			( new mit.comm.event.HostEvent( this ) ).raise() ;
		}
	}

	private static String clientstr = "mit.rmi.Client" ;
	private void validateClient()
	throws Exception
	{
		if( null == client )
		{
			client = mit.rmi.Client.create( getHost() , getPort() ) ;
			mit.util.RuntimeContext.setProperty
				( new String( clientstr )
				, client
				) ;
		}
	}

	public void addNotify()
	{
		super.addNotify() ;
		try
		{
			resetAll() ;

			getListenerAdapter().addHandled( mit.util.event.ValidServiceEvent.class ) ;
			getListenerAdapter().addHandled( mit.util.event.ClearEvent.class ) ;
			getListenerAdapter().addHandled( mit.rmi.event.HostEvent.class ) ;
			getListenerAdapter().addHandled( mit.rmi.event.PortEvent.class ) ;
			getListenerAdapter().addHandled( mit.rmi.event.TestEvent.class ) ;
			getListenerAdapter().addHandled( mit.rmi.event.InvokeMethodEvent.class ) ;
		}
		catch( Exception ex )
		{
			ex.printStackTrace() ;
		}
	}
}