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

#ifndef OB_OBJECT_H
#define OB_OBJECT_H

#include <OB/TypeCodeConst.h>
#include <OB/Object_fwd.h>
#include <OB/PolicyTypes.h>
#include <OB/Policy_fwd.h>
#include <OB/IFR2_fwd.h>
#include <OB/AbstractBase_fwd.h>
#include <OB/DII_fwd.h>
#include <OB/Context_fwd.h>
#include <OB/NamedValue_fwd.h>
#include <OB/OCIClient_fwd.h>
#include <OB/RefCounted_fwd.h> // For _OB_origIOR

namespace CORBA
{

//
// PolicyList
//
class OBUnique_PolicyList;
typedef OB::ObjSeq< Policy, OBUnique_PolicyList > PolicyList;
typedef OB::SeqVar< OB::ObjSeq< Policy, OBUnique_PolicyList > > PolicyList_var;
typedef OB::SeqOut< OB::ObjSeq< Policy, OBUnique_PolicyList > > PolicyList_out;

//
// PolicyType
//
typedef ULong PolicyType;
typedef ULong_out PolicyType_out;

//
// PolicyTypeSeq
//
class OBUnique_PolicyTypeSeq;
typedef OB::FixSeq< CORBA::ULong, OBUnique_PolicyTypeSeq > PolicyTypeSeq;

} // End of namespace CORBA

namespace CORBA
{

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

protected:

    //
    // The IDs for CORBA::Object (only for consistency, the list must
    // be empty)
    //
    static const char* ids_[];

    //
    // Constructor is protected
    //
    Object();

public:

    virtual ~Object();

    //
    // Standard IDL to C++ Mapping
    //
    static inline Object_ptr _duplicate(Object_ptr p)
    { if(p) p -> _add_ref(); return p; }
    static inline Object_ptr _nil()
    { return 0; }

    virtual InterfaceDef_ptr _get_interface() = 0;
    virtual Boolean _is_a(const char*) = 0;
    virtual Boolean _non_existent() = 0;

    virtual Boolean _is_equivalent(Object_ptr) = 0;
    virtual ULong _hash(ULong) = 0;

    static Object_ptr _narrow(AbstractBase_ptr);
    static Object_ptr _unchecked_narrow(AbstractBase_ptr);

    virtual void _create_request(Context_ptr, const char*, NVList_ptr,
				 NamedValue_ptr, Request_out, Flags) = 0;

    virtual void _create_request(Context_ptr, const char*, NVList_ptr,
				 NamedValue_ptr,
				 ExceptionList_ptr, ContextList_ptr,
				 Request_out, Flags) = 0;

    virtual Request_ptr _request(const char* operation) = 0;

    virtual Policy_ptr _get_policy(PolicyType) = 0;
    virtual Object_ptr _set_policy_overrides(const PolicyList&,
					     SetOverrideType) = 0;
	//throw(SystemException, InvalidPolicies);
    
    //
    // Policies
    // From draft messaging specification
    //
    virtual PolicyList* _get_policy_overrides(const PolicyTypeSeq&) = 0;
    virtual Policy_ptr _get_client_policy(PolicyType) = 0;
    virtual Boolean _validate_connection(PolicyList_out) = 0;

    //
    // Additional ORBacus-specific functions
    //
    virtual OCI::ConnectorInfo_ptr _get_oci_connector_info() = 0;
    virtual OCI::TransportInfo_ptr _get_oci_transport_info() = 0;

    //
    // ORBacus internal functions
    // Application programs must not use these functions directly
    //
    virtual const char** _OB_ids() const = 0;

    static const char** _OB_staticIds();

    virtual CORBA::AbstractBase_ptr _OB_toAbstractBase() = 0;

    //
    // This is needed for string_to_object/local forwarding
    //
    // TODO: Perhaps it's better to have a dynamic cast instead of
    // polluting the base Object interface with IOR specific stuff.
    // If this is removed remove the include <OB/RefCounted_fwd.h>
    // above.
    //
    virtual OB::RefCountIOR_ptr _OB_origIOR() const = 0;
    virtual OB::RefCountIOR_ptr _OB_IOR() const = 0;
    virtual void _OB_marshalOrigIOR(OB::OutputStreamImpl*) const = 0;
};

//
// release and is_nil
//
inline void
release(Object_ptr p)
{
    if(p)
	p -> _remove_ref();
}

inline Boolean
is_nil(Object_ptr p)
{
    return p == 0;
}

} // End of namespace CORBA

#endif
