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

#ifndef OB_POLICY_FACTORY_MANAGER_H
#define OB_POLICY_FACTORY_MANAGER_H

#include <OB/TypeCodeConst.h>
#include <OB/PolicyFactoryManager_fwd.h>
#include <OB/PIPolicy_fwd.h>

#include <OB/OBObject.h>
#include <OB/StubImpl.h>
#include <OB/MarshalStubImpl.h>
#include <OB/Policy.h>
#include <OB/Hashtable.h>

namespace OBCORBA
{

class ORB_impl; // For the friend declaration

} // End of namespace CORBA

namespace OB
{

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

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

    //
    // The set of registered policy factories
    //
    typedef Hashtable<CORBA::ULong, PortableInterceptor::PolicyFactory_var,
	ULongHasher> PolicyFactoryTable;

    //
    // These are PolicyFactory that are registered from the PIManager
    //
    PolicyFactoryTable policyFactoryTableExternal_;

    //
    // These are PolicyFactory that are registered internally (for ORB
    // policies, etc)
    //
    PolicyFactoryTable policyFactoryTableInternal_;

    PolicyFactoryManager();
    ~PolicyFactoryManager();
    
    friend class ::OBCORBA::ORB_impl; // ORB_impl creates PolicyFactoryManager
        
public:

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

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

    void registerPolicyFactory(CORBA::PolicyType,
			       PortableInterceptor::PolicyFactory_ptr,
                               bool internal);

    CORBA::Policy_ptr createPolicy(CORBA::PolicyType, const CORBA::Any&);
};

} // End namespace OB

namespace CORBA
{

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

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

} // End of namespace CORBA

#endif
