// **********************************************************************
//
// Copyright (c) 2002
// IONA Technologies, Inc.
// Waltham, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef OB_PLUGIN_MANAGER_H
#define OB_PLUGIN_MANAGER_H

#include <OB/TypeCodeConst_fwd.h>
#include <OB/PluginManager_fwd.h>

#include <OB/OCI_init.h>
#include <OB/list.h>

namespace OB
{

//
// Forward declaration
//
class SharedLibrary;

//
// The PluginManager class
//
class PluginManager : public OB::SimpleRefCount
{
    //
    // Hide copy-constructor and assignment operator
    //
    PluginManager(const PluginManager&);
    void operator=(const PluginManager&);

public: // Some compilers need this

    //
    // Plug-in data
    //
    struct PluginData
    {
        CORBA::String_var name;
        OCI::Plugin_var plugin;
        SharedLibrary* lib;
    };

private:

    //
    // The ORB
    //
    CORBA::ORB_var orb_;

    //
    // The set of registered plugins
    //
    OB_STL::list<PluginData> plugins_;

    bool destroy_; // True if destroy() was called

public:

    PluginManager(CORBA::ORB_ptr);
    virtual ~PluginManager();

    static inline PluginManager_ptr _duplicate(PluginManager_ptr p)
    { if(p) p -> _OB_incRef(); return p; }
    static inline PluginManager_ptr _nil()
    { return 0; }

    //
    // Destroy the PluginManager
    //
    void destroy();

    //
    // Initialize the plug-in with the given name. The plug-in may be
    // loaded dynamically. If the plug-in could not be initialized,
    // nil is returned.
    //
    OCI::Plugin_ptr initPlugin(const char*, int&, char**&);
};

} // End of namespace OB

namespace CORBA
{

inline void
release(OB::PluginManager_ptr p)
{
    if(p)
        p -> _OB_decRef();
}

inline Boolean
is_nil(OB::PluginManager_ptr p)
{
    return p == 0;
}

} // End of namespace CORBA

#endif
