// Configurable element - domain association
bool CConfigurableDomains::addConfigurableElementToDomain(const string& strDomain, CConfigurableElement* pConfigurableElement, const CParameterBlackboard* pMainBlackboard, string& strError)
{
    // Find domain
    CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);

    if (!pConfigurableDomain) {

        return false;
    }
    // Delegate
    return pConfigurableDomain->addConfigurableElement(pConfigurableElement, pMainBlackboard, strError);
}
bool CConfigurableDomains::removeConfigurableElementFromDomain(const string& strDomain, CConfigurableElement* pConfigurableElement, string& strError)
{
    // Find domain
    CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);

    if (!pConfigurableDomain) {

        return false;
    }
    // Delegate
    return pConfigurableDomain->removeConfigurableElement(pConfigurableElement, strError);
}
bool CConfigurableDomains::setApplicationRule(const string& strDomain, const string& strConfiguration, const string& strApplicationRule, const CSelectionCriteriaDefinition* pSelectionCriteriaDefinition, string& strError)
{
    CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);

    if (!pConfigurableDomain) {

        return false;
    }

    // Delegate to domain
    return pConfigurableDomain->setApplicationRule(strConfiguration, strApplicationRule, pSelectionCriteriaDefinition, strError);
}
bool CConfigurableDomains::clearApplicationRule(const string& strDomain, const string& strConfiguration, string& strError)
{
    CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);

    if (!pConfigurableDomain) {

        return false;
    }

    // Delegate to domain
    return pConfigurableDomain->clearApplicationRule(strConfiguration, strError);
}
// Config save
bool CConfigurableDomains::saveConfiguration(const string& strDomain, const string& strConfiguration, const CParameterBlackboard* pMainBlackboard, string& strError)
{
    // Find domain
    CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);

    if (!pConfigurableDomain) {

        return false;
    }
    // Delegate
    return pConfigurableDomain->saveConfiguration(strConfiguration, pMainBlackboard, strError);
}
bool CConfigurableDomains::renameConfiguration(const string& strDomain, const string& strConfigurationName, const string& strNewConfigurationName, string& strError)
{
    // Find domain
    CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);

    if (!pConfigurableDomain) {

        return false;
    }
    // Delegate
    return pConfigurableDomain->renameConfiguration(strConfigurationName, strNewConfigurationName, strError);
}
// Ensure validity on whole domains from main blackboard
void CConfigurableDomains::validate(const CParameterBlackboard *pMainBlackboard)
{
    // Delegate to domains
    size_t uiNbConfigurableDomains = getNbChildren();

    for (size_t child = 0; child < uiNbConfigurableDomains; child++) {

        CConfigurableDomain *pChildConfigurableDomain =
            static_cast<CConfigurableDomain *>(getChild(child));

        pChildConfigurableDomain->validate(pMainBlackboard);
    }
}
bool CConfigurableDomains::renameDomain(const string &strName, const string &strNewName,
                                        string &strError)
{
    CConfigurableDomain *pConfigurableDomain = findConfigurableDomain(strName, strError);

    if (!pConfigurableDomain) {

        return false;
    }

    // Rename
    return pConfigurableDomain->rename(strNewName, strError);
}
bool CConfigurableDomains::setElementSequence(const string& strDomain, const string& strConfiguration, const std::vector<string>& astrNewElementSequence, string& strError)
{
    // Find domain
    CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);

    if (!pConfigurableDomain) {

        return false;
    }

    // Delegate to domain
    return pConfigurableDomain->setElementSequence(strConfiguration, astrNewElementSequence, strError);
}
bool CConfigurableDomains::setSequenceAwareness(const string& strDomain, bool bSequenceAware, string& strError)
{
    CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);

    if (!pConfigurableDomain) {

        return false;
    }

    pConfigurableDomain->setSequenceAwareness(bSequenceAware);

    return true;
}
bool CConfigurableDomains::split(const string& strDomain, CConfigurableElement* pConfigurableElement, string& strError)
{
    // Find domain
    CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strDomain, strError);

    if (!pConfigurableDomain) {

        return false;
    }
    // Delegate
    pConfigurableDomain->split(pConfigurableElement, strError);

    return true;
}
bool CConfigurableDomains::renameDomain(const string& strName, const string& strNewName, string& strError)
{
    CConfigurableDomain* pConfigurableDomain = findConfigurableDomain(strName, strError);

    if (!pConfigurableDomain) {

        return false;
    }

    log_info("Renaming configurable domain \"%s\" to \"%s\"", strName.c_str(), strNewName.c_str());

    // Rename
    return pConfigurableDomain->rename(strNewName, strError);
}
// Configurable element - domain association
bool CConfigurableDomains::addConfigurableElementToDomain(
    const string &domainName, CConfigurableElement *element,
    const CParameterBlackboard *mainBlackboard, core::Results &infos)
{
    // Find domain
    std::string error;
    CConfigurableDomain *domain = findConfigurableDomain(domainName, error);

    if (domain == nullptr) {

        infos.push_back(error);
        return false;
    }
    // Delegate
    return domain->addConfigurableElement(element, mainBlackboard, infos);
}
bool CConfigurableDomains::split(const string &domainName, CConfigurableElement *element,
                                 core::Results &infos)
{
    // Find domain
    std::string error;
    CConfigurableDomain *domain = findConfigurableDomain(domainName, error);

    if (domain == nullptr) {

        infos.push_back(error);
        return false;
    }
    // Delegate
    domain->split(element, infos);

    return true;
}
void CConfigurableDomains::deleteDomain(CConfigurableDomain& configurableDomain)
{
    log_info("Deleting configurable domain \"%s\"", configurableDomain.getName().c_str() );

    removeChild(&configurableDomain);

    delete &configurableDomain;
}
bool CConfigurableDomains::addDomain(CConfigurableDomain &domain, bool bOverwrite, string &strError)
{
    string strErrorDrop;

    string strDomainName(domain.getName());
    CConfigurableDomain *pExistingDomain = findConfigurableDomain(strDomainName, strErrorDrop);

    if (pExistingDomain) {
        if (!bOverwrite) {
            strError = "Can't add domain \"" + strDomainName +
                       "\" because it already exists and overwrite was not requested.";
            return false;
        }

        deleteDomain(*pExistingDomain);
    }

    addChild(&domain);

    return true;
}