contract EmptyBunnies is
    ERC721Enumerable,
    ERC721Burnable,
    ReentrancyGuard,
    Ownable,
    PaymentSplitter
{
    // Sale begins:
    // GMT: Tuesday, October 19, 2021 1:30:00 AM
    //      Monday, October 18, 2021 6:30:00 PM GMT-07:00
    uint256 public saleTime = 1634607000;
    uint256 public price = 40000000000000000;
    uint256 public supplyCap = 6000;
    uint256 public perTxLimit = 20;
    uint256 public reservedMints = 35;
    uint256 private tokenCounter = 0;
    uint256[] private _teamShares = [36, 50, 13, 1];

    string public provenanceHash = "";
    string private baseTokenURI = "";
    
     address[] private _team = [
         0xa0260d525e841D5FbA772D69860dF59713992E95,
         0x23D4AA98cb89166D8d5043CA6E8d0aE0B7f70495,
         0x3097617CbA85A26AdC214A1F87B680bE4b275cD0,
         0x14679b51D4043B5C2BD16E83b26bFC4F662d8Bfa
     ];

    constructor(string memory _baseTokenURI)
        payable
        PaymentSplitter(_team, _teamShares)
        ERC721("Empty Bunnies NFT", "BUNS")
    {
        baseTokenURI = _baseTokenURI;
    }

    // Method which is used to mint during the standard minting window
    function mint(uint256 _amountMinted, address _recipient)
        public
        payable
        nonReentrant
    {
        if (owner() != _msgSender()) {
            require(
                saleTime != 0 && saleTime <= block.timestamp,
                "ERC721: Sale is paused..."
            );
        }
        require(totalSupply() < supplyCap, "ERC721: Sale is finished.");
        require(
            _amountMinted > 0 && _amountMinted <= perTxLimit,
            "ERC721: You may only mint up to 20 Empty Buns."
        );
        require(
            totalSupply() + _amountMinted < supplyCap,
            "ERC721: Transaction would exceed supply cap."
        );
        require(
            msg.value >= getTokenPrice(true) * _amountMinted,
            "ERC721: Incorrect value sent."
        );

        // Prevent nefarious contracts from bypassing limits
        require(
            tx.origin == _msgSender(),
            "ERC721: The caller is another contract."
        );

        for (uint256 i = 0; i < _amountMinted; i++) {
            _safeMint(_recipient, tokenCounter);
            tokenCounter++;
        }
    }

    // Setters-----------------------------

    // Owner only method which sets token price
    function setSaleTime(uint256 _saleTime) external onlyOwner {
        saleTime = _saleTime;
    }

    // Owner only method which sets provenance hash
    function setProvenanceHash(string memory _provenanceHash) public onlyOwner {
        provenanceHash = _provenanceHash;
    }

    // Owner only method which sets token price
    function setTokenPrice(uint256 _price) public onlyOwner {
        price = _price;
    }

    // Owner only method which sets baseUri
    function setBaseURI(string memory baseURI) public onlyOwner {
        baseTokenURI = baseURI;
    }

    // Owner only method which sets baseUri
    function setReservedMints(uint256 _reservedMints) public onlyOwner {
        reservedMints = _reservedMints;
    }

    // Public method which retrieves token price
    function getTokenPrice(bool showFree) public view returns (uint256) {
        if (!showFree) {
            return price;
        }
        if (totalSupply() < reservedMints) {
            return 0;
        }
        return price;
    }

    // Public method which retrieves holders inventory of tokens
    function getHoldersTokens(address _holder)
        public
        view
        returns (uint256[] memory)
    {
        uint256 tokenCount = balanceOf(_holder);

        uint256[] memory tokensId = new uint256[](tokenCount);

        for (uint256 i; i < tokenCount; i++) {
            tokensId[i] = tokenOfOwnerByIndex(_holder, i);
        }

        return tokensId;
    }

    // ----------- Overrides to satisfy openzeppelin ERC721 dependencies:
    function _baseURI() internal view virtual override returns (string memory) {
        return baseTokenURI;
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}
////import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
////import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
////import "@openzeppelin/contracts/access/Ownable.sol";
////import "@openzeppelin/contracts/finance/PaymentSplitter.sol";
////import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
function mint(uint256 _amountMinted, address _recipient)
    public
    payable
    nonReentrant
{
    if (owner() != _msgSender()) {
        require(
            saleTime != 0 && saleTime <= block.timestamp,
            "ERC721: Sale is paused..."
        );
    }
    require(totalSupply() < supplyCap, "ERC721: Sale is finished.");
    require(
        _amountMinted > 0 && _amountMinted <= perTxLimit,
        "ERC721: You may only mint up to 20 Empty Buns."
    );
    require(
        totalSupply() + _amountMinted < supplyCap,
        "ERC721: Transaction would exceed supply cap."
    );
    require(
        msg.value >= getTokenPrice(true) * _amountMinted,
        "ERC721: Incorrect value sent."
    );

    // Prevent nefarious contracts from bypassing limits
    require(
        tx.origin == _msgSender(),
        "ERC721: The caller is another contract."
    );

    for (uint256 i = 0; i < _amountMinted; i++) {
        _safeMint(_recipient, tokenCounter);
        tokenCounter++;
    }
}

// Method which is used to mint during the standard minting window