contract Slyguise is ERC721Enumerable, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenId;

    uint256 public constant MAX_GUISE = 1000;
    string baseTokenURI;

    event SlyguiseMinted(uint256 totalMinted);

    constructor(string memory baseURI) ERC721("Slyguise", "GUISE") {
        setBaseURI(baseURI);
    }

    //Get token Ids of all tokens owned by _owner
    function walletOfOwner(address _owner)
        external
        view
        returns (uint256[] memory)
    {
        uint256 tokenCount = balanceOf(_owner);

        uint256[] memory tokensId = new uint256[](tokenCount);
        for (uint256 i = 0; i < tokenCount; i++) {
            tokensId[i] = tokenOfOwnerByIndex(_owner, i);
        }

        return tokensId;
    }

    function setBaseURI(string memory baseURI) public onlyOwner {
        baseTokenURI = baseURI;
    }

    function batchMint(address[] calldata _recipients) external onlyOwner {
        require(
            totalSupply() + _recipients.length <= MAX_GUISE,
            "Presale minting will exceed maximum supply of Slyguise"
        );
        require(_recipients.length != 0, "No address found");
        for (uint256 i = 0; i < _recipients.length; i++) {
            require(_recipients[i] != address(0), "Minting to Null address");
            _mint(_recipients[i]);
        }
    }

    //mint Slyguise
    function mintSlyguise(address _to, uint256 _count) external onlyOwner {
        require(_count > 0, "Minimum 1 Slyguise has to be minted");
        require(
            totalSupply() + _count <= MAX_GUISE,
            "Exceeds maximum supply of Slyguise"
        );

        for (uint256 i = 0; i < _count; i++) {
            _mint(_to);
        }
    }

    function _mint(address _to) private {
        _tokenId.increment();
        uint256 tokenId = _tokenId.current();
        _safeMint(_to, tokenId);
        emit SlyguiseMinted(tokenId);
    }

    function _baseURI() internal view virtual override returns (string memory) {
        return baseTokenURI;
    }
}
/// @author Hammad Ahmed Ghazi
function walletOfOwner(address _owner)
    external
    view
    returns (uint256[] memory)
{
    uint256 tokenCount = balanceOf(_owner);

    uint256[] memory tokensId = new uint256[](tokenCount);
    for (uint256 i = 0; i < tokenCount; i++) {
        tokensId[i] = tokenOfOwnerByIndex(_owner, i);
    }

    return tokensId;
}

//Get token Ids of all tokens owned by _owner