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

    uint256 public constant TOTAL_SKULL = 888;
    uint256 public mint_fee = 88000000000000000; //0.088 Ether
    string baseTokenURI;
    bool public allowMint = false;

    event DeadsHeadMinted(uint256 totalMinted);

    constructor(string memory baseURI) ERC721("DeadsHead", "Skull") {
        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 setMintFee(uint256 _newMintFee) external onlyOwner {
        mint_fee = _newMintFee;
    }

    function toggleAllowMint() external onlyOwner {
        allowMint = !allowMint;
    }

    function withdrawETH() external onlyOwner {
        (bool success, ) = payable(msg.sender).call{value: address(this).balance}("");
        require(success, "Transfer failed.");
    }

    //mint DeadsHead
    function mintDeadsHead(address _to, uint256 _mintNumber) external payable {
        require(
            totalSupply() + _mintNumber <= TOTAL_SKULL,
            "Exceeds maximum supply of DeadsHead"
        );
        require(
            _mintNumber > 0,
            "Minimum 1 DeadsHead has to be minted per transaction"
        );
        if (msg.sender != owner()) {
            require(allowMint, "Minting is not open yet");
            require(
                _mintNumber <= 6,
                "Maximum 6 DeadsHead can be minted per transaction"
            );
            require(
                msg.value >= mint_fee * _mintNumber,
                "Ether sent with this transaction is not correct"
            );
        }

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

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

    function _baseURI() internal view virtual override returns (string memory) {
        return baseTokenURI;
    }
}
/// @author Hammad 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