contract PawZeesClub is ERC721, Ownable {
    uint256 public count = 0;
    
    event Increment(address who);

    using SafeMath for uint256;
    uint256 public pawZeesPrice = 30000000000000000; //0.03 ETH
    uint public constant maxPawZeesPurchase = 20;
    uint256 public MAX_PAWZEES;
    bool public saleIsActive = false;
     mapping (
    address => uint) public Leaderboard;

    constructor(string memory name, string memory symbol, uint256 maxNftSupply) ERC721(name, symbol) {
        MAX_PAWZEES = maxNftSupply;
    }

    function withdraw() public onlyOwner {
        uint balance = address(this).balance;
        msg.sender.transfer(balance);
    }

    // Reserves 40 pawZees
    function reservePawZeesForDonations() public onlyOwner {        
        uint supply = totalSupply();
        uint i;
        for (i = 0; i < 40; i++) {
            _safeMint(msg.sender, supply + i);
            count += 1;
        }
        emit Increment(msg.sender);
    }

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

    function flipSaleState() public onlyOwner {
        saleIsActive = !saleIsActive;
    }

    function discoverPawZees(uint numberOfTokens,address referral) public payable {
        require(saleIsActive, "Sale must be active to mint pawZees");
        require(numberOfTokens <= maxPawZeesPurchase, "Can only mint 20 tokens at a time");
        require(totalSupply().add(numberOfTokens) <= MAX_PAWZEES, "Purchase would exceed max supply of pawZees");
        require(pawZeesPrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        
        for(uint i = 0; i < numberOfTokens; i++) {
            uint mintIndex = totalSupply();
            if (totalSupply() < MAX_PAWZEES) {
                _safeMint(msg.sender, mintIndex);
                count += 1;
            }
        }
        Leaderboard[referral]=Leaderboard[referral]+numberOfTokens;
        emit Increment(msg.sender);
    }

    function getCount() public view returns(uint256) {
        return count;
    }

    // Emergency: can be changed to account for large fluctuations in ETH price
    function emergencyChangePrice(uint256 newPrice) public onlyOwner {
        pawZeesPrice = newPrice;
    }
}
/**
 * @title pawZeesClub contract
 * @dev Extends ERC721 Non-Fungible Token Standard basic implementation
 */
function reservePawZeesForDonations() public onlyOwner {        
    uint supply = totalSupply();
    uint i;
    for (i = 0; i < 40; i++) {
        _safeMint(msg.sender, supply + i);
        count += 1;
    }
    emit Increment(msg.sender);
}

// Reserves 40 pawZees