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

#include <OB/Basic.h>
#include <OB/Except.h>
#include <OB/Template.h>
#include <OB/Declarations.h>
#include <OB/IOP.h>
#include <OB/Object.h>
#include <OB/PolicyManager.h>

#include <ORBPolicyManager_impl.h>
#include <PolicyValidator.h>

// ----------------------------------------------------------------------
// ORBPolicyManager_impl constructor and destructor
// ----------------------------------------------------------------------

ORBPolicyManager_impl::ORBPolicyManager_impl(CORBA_PolicyList& policies)
    : policies_(policies)
{
}

ORBPolicyManager_impl::~ORBPolicyManager_impl()
{
}

// ----------------------------------------------------------------------
// ORBPolicyManager_impl public member implementation
// ----------------------------------------------------------------------

CORBA_Policy_ptr
ORBPolicyManager_impl::get_policy_override(CORBA_PolicyType policy_type)
{
    CORBA_ULong policiesLen = policies_.length();
    for(CORBA_ULong i = 0; i < policiesLen; ++i)
	if(policies_[i] -> policy_type() == policy_type)
	    return CORBA_Policy::_duplicate(policies_[i]);

    return CORBA_Policy::_nil();
}

CORBA_PolicyList*
ORBPolicyManager_impl::get_specific_policy_overrides(
                        const CORBA_PolicyTypeSeq& types)
{
    CORBA_ULong len = policies_.length();
    CORBA_ULong typesLen = types.length();

    CORBA_PolicyList_var policies = new CORBA_PolicyList(typesLen);

    for(CORBA_ULong i = 0 ; i < typesLen; ++i)
    {
        CORBA_PolicyType currType = types[i];
        for(CORBA_ULong j = 0 ; j < len ; ++j)
            if(policies_[j] -> policy_type() == currType)
                policies -> append(policies_[j]);
    }

    return policies._retn();
}

CORBA_PolicyList*
ORBPolicyManager_impl::get_all_policy_overrides()
{
    return new CORBA_PolicyList(policies_);
}


void
ORBPolicyManager_impl::add_policy_overrides(const CORBA_PolicyList& np)
{
    CORBA_PolicyList newPolicies = policies_;
    
    CORBA_ULong npLen  = np.length();
    for(CORBA_ULong i = 0 ; i < npLen ; ++i)
    {
        CORBA_ULong len = newPolicies.length();
        CORBA_ULong j;
        
        for(j = 0 ; j < len ; ++j)
            if(newPolicies[j] -> policy_type() == np[i] -> policy_type())
                break;
        
        if(j < len)
            newPolicies[j] = np[i];
        else
            newPolicies.append(np[i]);
    }
    PolicyValidator::validatePolicies(newPolicies);
    
    policies_ = newPolicies;
}

void
ORBPolicyManager_impl::remove_policy_overrides(const CORBA_PolicyTypeSeq& ts)
{
    CORBA_ULong typesLen = ts.length();

    for(CORBA_ULong i = 0 ; i < typesLen; ++i)
    {
        CORBA_PolicyType currType = ts[i];
        CORBA_ULong len = policies_.length();
        for(CORBA_ULong j = 0 ; j < len ; ++j)
        {
            if(policies_[j] -> policy_type() == currType)
            {
                policies_.remove(j);
                return;
            }
        }
    }
}

void
ORBPolicyManager_impl::replace_all_policy_overrides(
                        const CORBA_PolicyList& policies)
{
    PolicyValidator::validatePolicies(policies);
    policies_ = policies;
}
