contract theHonest8Ball is ERC721, Ownable {
    using SafeMath for uint256;
    uint public constant MAX_BALLS = 8888;
    bool public hasSaleStarted = false;
    string public metadataProvenanceHash = "";

    constructor() ERC721("theHonest8Ball","HONEST8")  {
        setBaseURI("https://perfectlyhonest8ball.xyz/api/token/");
        _safeMint(msg.sender,0);
        }
    

    
    function tokensOfOwner(address _owner) external view returns(uint256[] memory ) {
        uint256 tokenCount = balanceOf(_owner);
        if (tokenCount == 0) {
            // Return an empty array
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](tokenCount);
            uint256 index;
            for (index = 0; index < tokenCount; index++) {
                result[index] = tokenOfOwnerByIndex(_owner, index);
            }
            return result;
        }
    }
    

    function calculatePrice() public view returns (uint256) {
        require(hasSaleStarted == true, "Magic hasn't started");
        require(totalSupply() < MAX_BALLS, "Magic has already ended");
        return 10000000000000000; // 0.01ETH 
    }

    
   function mintBALL(uint256 numBalls) public payable {
        require(totalSupply() < MAX_BALLS, "Magic has already ended");
        require(numBalls > 0 && numBalls <= 100, "You can ask minimum 1, maximum 100 BALLS");
        require(totalSupply().add(numBalls) <= MAX_BALLS, "Exceeds MAX_BALLS");
        require(msg.value >= calculatePrice().mul(numBalls), "Ether value sent is below the price");

        for (uint i = 0; i < numBalls; i++) {
            uint mintIndex = totalSupply();
            _safeMint(msg.sender, mintIndex);
        }

    }


    // FUNCTIONS
    function setProvenanceHash(string memory _hash) public onlyOwner {
        metadataProvenanceHash = _hash;
    }
    
    function setBaseURI(string memory baseURI) public onlyOwner {
        _setBaseURI(baseURI);
    }
    
    function startDrop() public onlyOwner {
        hasSaleStarted = true;
    }
    
    function pauseDrop() public onlyOwner {
        hasSaleStarted = false;
    }
    
    function withdrawAll() public payable onlyOwner {
        require(payable(msg.sender).send(address(this).balance));
    }
    
}
function setProvenanceHash(string memory _hash) public onlyOwner {
    metadataProvenanceHash = _hash;
}

// FUNCTIONS