contract MomijiTokenManager is Ownable {
    using EnumerableSet for EnumerableSet.UintSet;

    IMomijiToken public momijiToken;
    mapping(address => EnumerableSet.UintSet) private _tokensForCreator;
    mapping(address => bool) public whitelist;
    uint256 whitelistCount;

    bool public onlyForWhitelist = true;

    constructor(IMomijiToken _momijiToken) {
        momijiToken = _momijiToken;
    }

    // After creating a new card, will mint it automatically.
    function create(uint256 tokenId, uint256 maxSupply, string memory uri, bytes calldata data) public {
        if (onlyForWhitelist) {
            require(whitelist[msg.sender], "Open to only whitelist.");
        }
        momijiToken.create(tokenId, maxSupply, uri, data);
        momijiToken.addMinter(tokenId, address(this));
        momijiToken.mint(tokenId, msg.sender, maxSupply, data);
        momijiToken.removeMintManuallyQuantity(tokenId, maxSupply);
        momijiToken.transferCreator(tokenId, msg.sender);
        _tokensForCreator[msg.sender].add(tokenId);
    }

    // Get how many cards of a creator.
    function getTokenAmountOfCreator(address account) view public returns(uint256) {
        return _tokensForCreator[account].length();
    }

    // Get tokenid of the creator with an index
    function getTokenIdOfCreator(address account, uint256 index) view public returns(uint256) {
        return _tokensForCreator[account].at(index);
    }

    // Add a new card to this creator
    function addCardManually(uint256 cardId) public {
        require(msg.sender == momijiToken.creators(cardId), "You are not the creator of this NFT.");
        _tokensForCreator[msg.sender].add(cardId);
    }

    // Remove a card from set of creator.
    function removeCardManually(uint256 cardId) public {
        require(_tokensForCreator[msg.sender].contains(cardId), "This NFT is not in your creation.");
        _tokensForCreator[msg.sender].remove(cardId);
    }

    // add a new artist
    function addToWhitelist(address account) public onlyOwner {
        whitelist[account] = true;
        whitelistCount += 1;
    }

    // Remove an artist
    function removeFromWhitelist(address account) public onlyOwner {
        whitelist[account] = false;
    }

    function openToEveryone() public onlyOwner {
        onlyForWhitelist = false;
    }

    function openOnlyToWhitelist() public onlyOwner {
        onlyForWhitelist = true;
    }
}
/**
 Author: DokiDoki Dev: Kaki
 */
function removeFromWhitelist(address account) public onlyOwner {
    whitelist[account] = false;
}

// Remove an artist