// **********************************************************************
//
// Copyright (c) 1999
// Object Oriented Concepts, Inc.
// Billerica, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#include <OB/CORBA.h>
#include <OB/Util.h>
#include <OB/Properties.h>

#include <OB/CosEventChannelAdmin_skel.h>

#include <ProxyConsumer_impl.h>
#include <ProxyState.h>
#include <PropagatorBaseThread.h> // SGI 7.0/7.1 needs this, and PusherBase...
#include <PusherBaseThread.h>
#include <EC_ProxyPushConsumer_impl.h>
#include <EC_ProxyPullConsumer_impl.h>
#include <EC_SupplierAdmin_impl.h>

// ----------------------------------------------------------------------
// EC_SupplierAdmin_impl constructor and destructor
// ----------------------------------------------------------------------

EC_SupplierAdmin_impl::EC_SupplierAdmin_impl(
    CORBA_ORB_ptr orb,
    EC_EventChannel_impl* e)
    : orb_(CORBA_ORB::_duplicate(orb)),
      channel_(e),
      nextId_(0),
      destroyed_(false)
{
}

EC_SupplierAdmin_impl::~EC_SupplierAdmin_impl()
{
#ifdef OB_TRACE
    OBMessageViewer::instance() -> trace(2, "Destroy SupplierAdmin");
#endif
    assert(proxies_.length() == 0);
}

// ----------------------------------------------------------------------
// EC_SupplierAdmin_impl public member implementation
// ----------------------------------------------------------------------

CosEventChannelAdmin_ProxyPushConsumer_ptr
EC_SupplierAdmin_impl::obtain_push_consumer()
{
    JTCSynchronized sync(*this);

    if(destroyed_)
        throw CORBA_OBJECT_NOT_EXIST();
    
    EC_ProxyPushConsumer_impl* p =
        new EC_ProxyPushConsumer_impl(orb_, channel_, this, nextId_++);
    proxies_.append(p);
    return CosEventChannelAdmin_ProxyPushConsumer::_duplicate(p);
}

CosEventChannelAdmin_ProxyPullConsumer_ptr
EC_SupplierAdmin_impl::obtain_pull_consumer()
{
    JTCSynchronized sync(*this);

    if(destroyed_)
        throw CORBA_OBJECT_NOT_EXIST();
    
    EC_ProxyPullConsumer_impl* p =
        new EC_ProxyPullConsumer_impl(orb_, channel_, this, nextId_++);
    proxies_.append(p);
    return CosEventChannelAdmin_ProxyPullConsumer::_duplicate(p);
}

void
EC_SupplierAdmin_impl::removeProxy(ProxyConsumer_impl* p)
{
    JTCSynchronized sync(*this);

    //
    // Find the element, and remove it from the sequence.
    //
    for(CORBA_ULong i = 0; i < proxies_.length(); ++i)
        if(proxies_[i] == p)
        {
            p -> release();
            proxies_.remove(i);
            return;
        }
    assert(false);
}

void
EC_SupplierAdmin_impl::disconnect()
{
    JTCSynchronized sync(*this);
    
    assert(!destroyed_);
    destroyed_ = true;

    //
    // disconnect each proxy.
    //
    for(CORBA_ULong i = 0; i < proxies_.length(); ++i)
    {
        proxies_[i] -> disconnect();
        proxies_[i] -> release();
    }
    proxies_.length(0);

    //
    // Disconnect the servant from the ORB.
    //
    orb_ -> disconnect(this);
}
