contract AFRICARARE is ERC721, Ownable, Pausable {


    //Tracks num minted
    uint256 public numMinted = 0;
    //URI of the genesis NFT metadata
    string public genesisMetadata = "https://ipfs.io/ipfs/bafkreicyanj53lbyw5kt57uedtvd565t4csmaoyve6xz377ydj2ajjcfdy";



    // Mapping for token URIs
    mapping (uint256 => string) private _tokenURIs;

    //Constructor
    constructor() ERC721("Africarare Genesis Collection", "gRARE") {
    }



    /**
    * @dev sets token URI
    */
    function _setTokenURI(uint256 tokenId, string memory URI) internal virtual {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = URI;
    }


    /**
    * @dev gets token URI
    */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        return _tokenURIs[tokenId];
    }


    /**
    * @dev Mints 1 NFT to senders address
    */
    function mintSingleGenesisNFT(string memory URI) internal onlyOwner {
        uint256 tokenId = numMinted;
        require(!_exists(tokenId), "That token ID has already been minted. Please try again.");
        ++numMinted;
        _safeMint(msg.sender, tokenId);
        _setTokenURI(tokenId, URI);

    }


    /**
    * @dev Mints 1 NFT to specified address
    */
    function mintToAddressSingleGenesisNFT(string memory URI, address receiverAddress) internal onlyOwner {
        uint256 tokenId = numMinted;
        require(!_exists(tokenId), "That token ID has already been minted. Please try again.");
        ++numMinted;
        _safeMint(receiverAddress, tokenId);
        _setTokenURI(tokenId, URI);

    }

    /**
    * @dev Mints batch of n number of NFTs
    */
    function mintBatchOfGenesisNFT(uint256 numToMint) external onlyOwner {
        for (uint i=0; i < numToMint; i++) {
            mintSingleGenesisNFT(genesisMetadata);
        }
    }

    /**
    * @dev Mints batch of n number of NFTs to specified address
    */
    function mintToAddressBatchOfGenesisNFT(uint256 numToMint, address receiverAddress) external onlyOwner {
        for (uint i=0; i < numToMint; i++) {
            mintToAddressSingleGenesisNFT(genesisMetadata, receiverAddress);
        }
    }

    /**
    * @dev Withdraw funds from this contract (Callable by owner)
    */
    function withdraw() external onlyOwner {
        uint256 balance = address(this).balance;
        address payable ownerAddress = payable(msg.sender);
        require(ownerAddress != address(0), "ERC20: transfer to the zero address");
        ownerAddress.transfer(balance);
    }


    /**
    * @dev Pause
    */
    function pause() external virtual onlyOwner() {
        super._pause();
    }

  /**
    * @dev Unpause
    */
    function unpause() external virtual onlyOwner() {
        super._unpause();
    }
}
/**
 * @title AfricaRare Mint Contract
 * @author Beau Williams (@beauwilliams)
 * @dev Smart contract for Africarare to mint one off NFTs
 */
function pause() external virtual onlyOwner() {
    super._pause();
}

/**
 * @dev Pause
 */