/******************************************************************************
*                                                                             *
*  File: SimpleConfigurator.h                                                 *
*                                                                             *
*  Description: A concrete class that reifies dependencies between components.*
*                                                                             *
*  Project: 2K - Automatic Configuration                                      *
*  Author: Fabio Kon (f-kon@cs.uiuc.edu)                                      *
*                                                                             *
*******************************************************************************

   Revision Control Information

   $Revision: $

   $Log: $
******************************************************************************/

#if !defined (SIMPLE_CONFIGURATOR_H)
#define       SIMPLE_CONFIGURATOR_H

#include "ace/OS.h"
#include "ace/Service_Object.h"

typedef ACE_Service_Object Object;  // Maybe we should have something else here.

#include "HookSpecification.h"

/////////////////////////////////

#include "ComponentConfigurator.h"

class SimpleConfigurator : public ComponentConfigurator {
  private:
    /* The Java object implementating this component. */
    Object *implementation_;

    /* A list containing the hooks for this component. */
    HookList hookList_;

    /* A list containing the clients for this component.  */
    HookList clientList_;

    /* The name of this component. */
    char *name_;

    /* Information string about this component. */
    char *info_;

  public:
    /* Creates a new configurator for a given object.
     *
     * @param     name             the component name.
     * @param     implementation   the object implementation.
     */
    SimpleConfigurator (const char *name, Object *implementation);
    
    /* Deletes the references to all internal data structures. */
    void destroyComponentConfigurator ();

    /* Adds a hook to the configurator.
     * @param   hookName  the name of the hook to be added.
     */
    int addHook (const char *hookName);
        
    /* Deletes a hook from the configurator.
     * @param   hookName  the name of the hook to be deleted.
     */
    int deleteHook (const char *hookName);
        
    /* Attaches a ComponentConfigurator to the given hook.
     * @param  hookName  the name of the hook.
     * @param  cc        the ComponentConfigurator to be attached to the hook.
     */
    int hook (const char *hookName, ComponentConfigurator *cc);

    /* Detaches a ComponentConfigurator from the given hook.
     * @param hookName  the name of the hook.
     * @param cc        the ComponentConfigurator to be detached.
     */
    int unhook (const char *hookName);
    
    /*
     * Adds a new component to the list of clients.
     * @param  client  the ComponentConfigurator representing the new client.
     * @param  hookNameInClient the name of the hook to which
     *          this component is attached.
     */
    int registerClient (ComponentConfigurator *client, 
                        const char *hookNameInClient);
    
    /* Removes a pair (client, hook) from the list of clients.
     * @param  client  the ComponentConfigurator representing the new client.
     * @param  hookNameInClient the name of the hook to which 
     *         this component is attached.
     */
    int unregisterClient (ComponentConfigurator *client, 
                          const char *hookNameInClient);
    
    /* This implementation simply prints the event to the standard output.
     * @param  hookedComponent the ComponentConfigurator that generated the event.
     * @param  e               the event that was generated. 
     */
    void eventOnHookedComponent (const ComponentConfigurator *hookedComponent,
                                 const ComponentEvent *e);
    
    /* This implementation simply prints the event to the standard output.
     * @param  client  the ComponentConfigurator that generated the event.
     * @param  e       the event that was generated. 
     */
    void eventOnClient (const ComponentConfigurator *client, 
                        const ComponentEvent *e);
    
    /* Accessor for the component name.
     * @return a string containing the component name. 
     */
    const char *name () const;
    
    /* Accessor for the component information string.
     * @return a string containing component information.
     */
    const char *info () const;
    
    /*
     * Provides a list of the hooks in this component.
     * @returns a list of HookSpecifications.
     */
    const HookList *listHooks ();

    /* Provides a list of the clients of this component.
     * @returns a list of HookSpecifications.
     */
    const HookList *listClients ();
    
    /* Sets the name of this component. The string is copied*/
    void name (const char *s);
    
    /* Sets the information string for this component. The string is copied*/
    void info (const char *s);

    /* Accessor for getting the component implementation.
     * @return the object implementation.
     */
    Object *implementation ();

    /* Accessor for setting the component implementation. */
    void implementation (Object *implementation);

  private:
    //////////////////////////////////////////////////////////////////////
    // Returns the index of the first hook with the name provided.
    // Returns -1 if such element is not found.
    //////////////////////////////////////////////////////////////////////
    HookSpecification *findHook (const char *hookName);

    ////////////////////////////////////////////////////////////////////// 
    // Returns a reference to the first client hook with the
    // ComponentConfigurator and name provided.  
    // Returns 0 if such element is not found.
    //////////////////////////////////////////////////////////////////////
    HookSpecification *findClientHook (const ComponentConfigurator *client, 
                                       const char *hookName);
    
};

#endif
