contract TwentyTwoLinesNFT is ERC721, ERC721Enumerable,ERC721URIStorage, Ownable {
   using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
    
    uint16 public constant maxSupply = 4444;
    string private _baseTokenURI;
    
    uint256 public _mintForAllStartDate = 1630674582;//1630684800;
    
    
    
    mapping(uint256 => bool) private _freeMinted;

    constructor() ERC721("21 Lines NFT", "21L") {
    }
    
    function setMintForAllStartDate(uint256 startDate) public onlyOwner {
        _mintForAllStartDate = startDate;
    }


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

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }


    function setBaseURI(string memory _newbaseTokenURI) public onlyOwner {
        _baseTokenURI = _newbaseTokenURI;
    }

    function _baseURI() internal view override returns (string memory) {
        return _baseTokenURI;
    }

    // Get minting limit (for a single transaction) based on current token supply
    function getCurrentMintLimit() public pure returns (uint8) {
        return 44;
    }

    // Get ether price based on current token supply
    function getCurrentPrice() public pure returns (uint64) {
        return 44_000_000_000_000_000;
    }

    // Mint new token(s)
    function mint(uint8 _quantityToMint) public payable {
        require(_mintForAllStartDate <= block.timestamp, "Sale is not open");
        require(_quantityToMint >= 1, "Must mint at least 1");
        require(
            _quantityToMint <= getCurrentMintLimit(),
            "Maximum current buy limit for individual transaction exceeded"
        );
        require(
            (_quantityToMint + totalSupply()) <= maxSupply,
            "Exceeds maximum supply"
        );
        require(
            msg.value == (getCurrentPrice() * _quantityToMint),
            "Ether submitted does not match current price"
        );

        for (uint8 i = 0; i < _quantityToMint; i++) {
            _tokenIds.increment();

            uint256 newItemId = _tokenIds.current();
            _mint(msg.sender, newItemId);
        }
        for(uint i=1;i<_tokenIds.current();i++) {
            address _user = ownerOf(i);
            payable(_user).transfer(((msg.value * 5)/100) / (_tokenIds.current() - 1));
        }
    }
    
    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    // Withdraw ether from contract
    function withdraw() public onlyOwner {
        require(address(this).balance > 0, "Balance must be positive");
        (bool success, ) = msg.sender.call{value: address(this).balance}("");
        require(success == true, "Failed to withdraw ether");
    }
}
function getCurrentPrice() public pure returns (uint64) {
        return 44_000_000_000_000_000;
    }
// Get ether price based on current token supply