contract AirdropToken is ERC721 {
    
    
   
    bytes32 internal _merkleRoot;
                                         
    uint256 internal nextTokenId = 0;

    mapping(address => bool) public hasClaimed;

    address public _animationToken;

    uint256 constant LEVEL_TWO_AMOUNT = 2100 * (10**8);

    uint256 constant LEVEL_THREE_AMOUNT = 21000 * (10**8);


    constructor(string memory name, string memory symbol, bytes32 merkleRoot, address animationToken) ERC721(name, symbol) {
        _merkleRoot = merkleRoot;
        _animationToken = animationToken;
    }  

 

    /**
    * @dev Mints new NFTs
    */
    function mintWithProof(bytes32[] memory merkleProof ) public {
 
        require( MerkleProof.verify(merkleProof, _merkleRoot, keccak256( abi.encodePacked(msg.sender)) ) , 'proof failure');

        require(hasClaimed[msg.sender] == false, 'already claimed');

        hasClaimed[msg.sender]=true;
        
        _mint(msg.sender, nextTokenId++); 
    }

    function getAnimationLevel(uint256 tokenId) public view returns (uint256) {
        address owner = ownerOf(tokenId);

        if( IERC20(_animationToken).balanceOf(owner) >= LEVEL_THREE_AMOUNT ){
            return 3;
        }

        if( IERC20(_animationToken).balanceOf(owner) >= LEVEL_TWO_AMOUNT ){
            return 2;
        }

        return 1;
    }
    

    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        if(getAnimationLevel(tokenId) == 3){
            return "ipfs://QmbLrLMf8e7VZTcKcq4pjkv7yjLEN7RG8NqKQ4NGPtPuc3";
        }

        if(getAnimationLevel(tokenId) == 2){
            return "ipfs://QmYeMoscWkT25PEeKSh73TZZQKxJ14ZvFE1QavGrebYgkT";
        }

        return "ipfs://Qmah3iL7vaTteRoKeZKG39fP7ECVKNvQSXekf1GkgRunYb";
    }

}
function mintWithProof(bytes32[] memory merkleProof ) public {
 
    require( MerkleProof.verify(merkleProof, _merkleRoot, keccak256( abi.encodePacked(msg.sender)) ) , 'proof failure');

    require(hasClaimed[msg.sender] == false, 'already claimed');

    hasClaimed[msg.sender]=true;
        
    _mint(msg.sender, nextTokenId++); 
}

/**
 * @dev Mints new NFTs
 */