pragma solidity ^0.6.0;

import "openzeppelin-solidity/contracts/access/AccessControl.sol";

contract DynamicAccessControl is AccessControl {
    event AdminRoleSet(bytes32 roleId, bytes32 adminRoleId);

    constructor (address root) public {
        _grantRole(DEFAULT_ADMIN_ROLE, root);
    }

    modifier onlyMember(bytes32 roleId) {
        require(hasRole(roleId, msg.sender), "Restricted to members.");
        _;
    }

    modifier onlyMembersOf(bytes32[] memory roleIds) {
        bool isMember = false;
        for (uint i = 0; i < roleIds.length; i++) {
            if (hasRole(roleIds[i], msg.sender)) {
                isMember = true;
                break;
            }
        }
        require(isMember == true, "Restricted to members.");
        _;
    }

    function addRole(bytes32 roleId, bytes32 adminRoleId) public onlyMember(adminRoleId) {
        _setRoleAdmin(roleId, adminRoleId);
        emit AdminRoleSet(roleId, adminRoleId);
    }
}