contract Cairn721 is Context, ERC721, Ownable{

    address payable public withdrawalAddress;
    address public rocksAddress;

    event MetadataUpdated(string newTokenUriBase);
    event CairnMinted(address sender, uint256 tokenId);
    event TokensBurnt(uint256 [] rocks, address pfpAddress, uint256 pfpId, string collectorsNote);

    constructor(
        string memory givenTokenURIBase,
        address givenRocksAddress
    ) ERC721("UNSHADED CAIRN", "CAIRN" ) {
        _setBaseURI(givenTokenURIBase);
        rocksAddress = givenRocksAddress;
    }

    function updateBaseURI(string memory givenTokenURIBase) public onlyOwner{
        _setBaseURI(givenTokenURIBase);
    }

    function setRocksAddress(address givenRockAddress) public onlyOwner{
        rocksAddress = givenRockAddress;
    }

    //Withdrawal - there will be no price tho
    function setWithdrawalAddress(address payable givenWithdrawalAddress) public onlyOwner {
        withdrawalAddress = givenWithdrawalAddress;
    }

    function withdrawEth() public onlyOwner {
        Address.sendValue(withdrawalAddress, address(this).balance);
    }

    function tokenInfo(uint256 tokenId) public view returns (address) {
        return (ownerOf(tokenId));
    }

    function getOwners(uint256 start, uint256 end) public view returns (address[] memory){
        address[] memory re = new address[](end - start);
        for (uint256 i = start; i < end; i++) {
                re[i - start] = ownerOf(i);
        }
        return re;
    }

    function mintCairn( address pfpAddress, uint256 pfpToBurn, uint256[] memory rocksToBurn, string memory collectorsNote) public { 
        require(rocksToBurn.length >= 11, "not enough rocks to burn");
        require(pfpAddress != rocksAddress, "pfp address must be different from rocks address");

        for (uint256 i = 0; i < 11; i++) {
                IERC721(rocksAddress).safeTransferFrom(msg.sender, address(0xdEaD), rocksToBurn[i]);
        }

        IERC721(pfpAddress).safeTransferFrom(msg.sender, address(0xdEaD), pfpToBurn);

        emit TokensBurnt(rocksToBurn, pfpAddress, pfpToBurn, collectorsNote);
        mint();
    }

    function mint() private returns (uint256) {
        emit CairnMinted(msg.sender, totalSupply());
        uint256 tokenToMint = totalSupply();
        _safeMint(msg.sender, tokenToMint);
        return tokenToMint;
    }
    
}
/**
 * @dev {ERC721} token, including:
 *
 *  - ability for holders to burn (destroy) their tokens
 *  - a minter role that allows for token minting (creation)
 *  - token ID and URI autogeneration
 *
 * This contract uses {AccessControl} to lock permissioned functions using the
 * different roles - head to its documentation for details.
 *
 * The account that deploys the contract will be granted the minter and pauser
 * roles, as well as the default admin role, which will let it grant both minter
 * and pauser roles to other accounts.
 */
function setWithdrawalAddress(address payable givenWithdrawalAddress) public onlyOwner {
    withdrawalAddress = givenWithdrawalAddress;
}

//Withdrawal - there will be no price tho