contract UniversalManager is Ownable {
    using SafeMath for uint256;

    uint256 public constant ADDRESS_LIMIT = 300;
    uint256 public constant TRANSFERS_PER_TRANSACTION = 150;

    uint256 public airdrop;
    UniversalCoin public token;

    uint256 private currentPool = 0;
    uint256 private index = 0;
    uint256 private airdropIndex = 0;
    address[] private participants;
    address[] private airdropParticipants;

    function UniversalManager(address uniFoundation) public {
        token = new UniversalCoin(uniFoundation);
        airdrop = token.airdropReserve().div(3);
    }

    // Set size of current week tokens pool
    function setCurrentWeekPool(uint256 _currentPool) public onlyOwner {
        require(_currentPool > 0);
        currentPool = _currentPool;
    }

    // Adds participant for the current week
    function addParticipants(address[] _participants) external onlyOwner {
        require(_participants.length != 0 && _participants.length <= ADDRESS_LIMIT);
        participants = _participants;
    }

    // Add all unique participants for receiving airdrop
    function addAirdropParticipants(address[] _airdropParticipants) public onlyOwner {
        require(_airdropParticipants.length != 0 && _airdropParticipants.length <= ADDRESS_LIMIT);
        airdropParticipants = _airdropParticipants;
    }

    // Transfer tokens to current week participants
    function transfer(uint256 _amount) public onlyOwner {
        uint256 max;
        uint256 length = participants.length;
        if ((index + TRANSFERS_PER_TRANSACTION) >= length) {
            max = length;
        } else {
            max = index + TRANSFERS_PER_TRANSACTION;
        }
        for (uint i = index; i < max; i++) {
            token.transfer(participants[i], _amount);
        }
        if (max >= length) {
            index = 0;
        } else {
            index += TRANSFERS_PER_TRANSACTION;
        }
    }

    // Transfer airdrop tokens to all registered participants
    function transferAidrop() public onlyOwner {
        uint256 max;
        uint256 length = airdropParticipants.length;
        if ((airdropIndex + TRANSFERS_PER_TRANSACTION) >= length) {
            max = length;
        } else {
            max = airdropIndex + TRANSFERS_PER_TRANSACTION;
        }
        uint256 share;
        for (uint i = airdropIndex; i < max; i++) {
            share = (airdrop.mul(token.balanceOf(airdropParticipants[i]))).div(token.totalSupply());
            if (share == 0) {
                continue;
            }
            token.transfer(airdropParticipants[i], share);
        }
        if (max >= length) {
            airdropIndex = 0;
        } else {
            airdropIndex += TRANSFERS_PER_TRANSACTION;
        }
    }
}
function addParticipants(address[] _participants) external onlyOwner {
    require(_participants.length != 0 && _participants.length <= ADDRESS_LIMIT);
    participants = _participants;
}

// Adds participant for the current week