How do I define a variable that is being defined at a later part of my smart contract?

Okay, first things first...I'm kind of an idiot. I'm a self-taught solidity dev and probably a bad one at that...so please don't judge me :see_no_evil:

I am working on this contract and my objective at this point is to make the contract scan the wallet address of the caller to see how much they own of another contract address, the contract does this already. However I am trying to make the amount the wallet owner has be the max amount they can mint for free off this contract.

As an example, if wallet owner 1 has 5 NFTs from A contract, they should be able to mint 5 NFTs from B contract but no more than 5 for free. If wallet owner 2 has 3 NFTs from A contract, they should only be able to mint 3 NFTs from contract B at a maximum.

Below is the code, you can see here I tried to make maxgiveawayamount = otherTokenAmount however it is an undeclared variable, so this will not work. However there is a function later called walletofOwnerofOtherContract that does produce the variable I'm looking for, "otherTokenAmount" and I want that variable to be the variable that governs maxgiveaway. Maybe its a pipe dream, I feel like I'm the verge of something but due to my lack of experience its hard for me to connect the dots.

Thanks to anyone who can assist.

pragma solidity >=0.7.0 <0.9.0;

contract NFT is ERC721, Ownable {
    using Strings for uint256;
    using Counters for Counters.Counter;

    Counters.Counter private supply;

    

    //other token nft contract
    address public contract1;
    address public contract2;
    uint256 public criteria1 = 1;

    string public baseURI;
    string public baseExtension = ".json";
    string public notRevealedUri;

    uint256 public cost = 1 ether;
    uint256 public maxSupply = 500;
    uint256 public maxMintAmountPerTx = 10;
    uint256 public MaxgiveawayAmountperTx = otherTokenAmount;
    uint256 public giveawaylimit = 500;
    uint256 public givedAway = 0;
    bool public paused = false;
    bool public revealed = true;

    struct GivedAwayFree {
        bool claimedFree;
    }
    mapping(address => GivedAwayFree) public givedAwayFree;

  constructor(
    string memory _name,
    string memory _symbol,
    string memory _initBaseURI,
    string memory _initNotRevealedUri
  ) ERC721(_name, _symbol) {
    setBaseURI(_initBaseURI);
    setNotRevealedURI(_initNotRevealedUri);
  }

  // internal
  function _baseURI() internal view virtual override returns (string memory) {
    return baseURI;
  }

    modifier mintCompliance(uint256 _mintAmount) {
        require(
            _mintAmount > 0 && _mintAmount <= maxMintAmountPerTx,
            "Invalid mint amount!"
        );
        require(
            supply.current() + _mintAmount <= maxSupply,
            "Max supply exceeded!"
        );
        _;
    }

    modifier giveawayCompliance(uint256 _giveawayAmount) {
        require(
          _giveawayAmount > 0 && _giveawayAmount <= MaxgiveawayAmountperTx,
            "Invalid giveaway amount!"
        );
        require(
            supply.current() + _giveawayAmount <= maxSupply,
            "Max supply exceeded!"
        );
        _;
    }


    function totalSupply() public view returns (uint256) {
        return supply.current();
    }

function giveaway(uint256 _giveawayAmount)
        public
        payable
        giveawayCompliance(_giveawayAmount)
    {
        require(!paused, "The contract is paused!");
        // check if other user owns token from different contract
        uint256 _contract1 = walletOfOwnerOfOtherContract(
            msg.sender,
            contract1   
        );
        uint256 _contract2 = walletOfOwnerOfOtherContract(
            msg.sender,
            contract2   
        );
        //if user owns any token from different contract
        if (givedAway >= 500) {
            require(msg.value >= cost * _giveawayAmount, "Insufficient funds!");
            _mintLoop(msg.sender, _giveawayAmount);
        } else {
            if (
                _contract1 >= criteria1 && 
                _contract2 >= criteria1

            ) {
                //check if user has already claimed free token
                if (givedAwayFree[msg.sender].claimedFree == true) {
                    // if user has already claimed free token, then he can't mint for free, and has to pay
                    require(
                        msg.value >= cost * _giveawayAmount,
                        "Insufficient funds!"
                    );
                    _giveawayLoop(msg.sender, _giveawayAmount);
                } else {
                    // if user has not claimed free token, then he can mint for free
                    _giveawayLoop(msg.sender, _giveawayAmount);
                    givedAwayFree[msg.sender].claimedFree = true;
                    givedAway++;
                }
            } else {
                // if user does not own any token from different contract, then he cannot mint for free
                require(msg.value >= cost * _giveawayAmount, "Insufficient funds!");
                _giveawayLoop(msg.sender, _giveawayAmount);
            }
        }
    }

    function mint(uint256 _mintAmount)
        public
        payable
        mintCompliance(_mintAmount)
    {
        require(!paused, "The contract is paused!");
        require(msg.value >= cost * _mintAmount, "Insufficient funds!");
        _mintLoop(msg.sender, _mintAmount);
        }

    function mintForAddress(uint256 _mintAmount, address _receiver)
        public
        mintCompliance(_mintAmount)
        onlyOwner
    {
        _mintLoop(_receiver, _mintAmount);
    }

    function walletOfOwnerOfOtherContract(
        address _owner,
        address contractAddress
    ) public view returns (uint256 otherTokenAmount) {
        uint256 ownerTokenCount = ERC721(contractAddress).balanceOf(_owner);
        return ownerTokenCount;
    }

    function walletOfOwner(address _owner)
        public
        view
        returns (uint256[] memory)
    {
        uint256 ownerTokenCount = balanceOf(_owner);
        uint256[] memory ownedTokenIds = new uint256[](ownerTokenCount);
        uint256 currentTokenId = 1;
        uint256 ownedTokenIndex = 0;

        while (
            ownedTokenIndex < ownerTokenCount && currentTokenId <= maxSupply
        ) {
            address currentTokenOwner = ownerOf(currentTokenId);

            if (currentTokenOwner == _owner) {
                ownedTokenIds[ownedTokenIndex] = currentTokenId;

                ownedTokenIndex++;
            }

            currentTokenId++;
        }

        return ownedTokenIds;
    }

  function tokenURI(uint256 tokenId)
    public
    view
    virtual
    override
    returns (string memory)
  {
    require(
      _exists(tokenId),
      "ERC721Metadata: URI query for nonexistent token"
    );
    
    if(revealed == false) {
        return notRevealedUri;
    }

    string memory currentBaseURI = _baseURI();
    return bytes(currentBaseURI).length > 0
        ? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension))
        : "";
  }

    function setcontract1(address _contract1) public onlyOwner returns(address){
        return  contract1 = _contract1;
    }

    function setcontract2(address _contract2) public onlyOwner returns(address){
        return  contract2 = _contract2;
    }

    function setcriteria1(uint256 _criteria1) public onlyOwner {
        criteria1 = _criteria1;
    }
    
    function setRevealed(bool _state) public onlyOwner {
        revealed = _state;
    }

    function setCost(uint256 _cost) public onlyOwner {
        cost = _cost;
    }

    function setMaxMintAmountPerTx(uint256 _maxMintAmountPerTx)
        public
        onlyOwner
    {
        maxMintAmountPerTx = _maxMintAmountPerTx;
    }

     function setMaxgiveawayAmountPerTx(uint256 _maxgiveawayAmountPerTx)
        public
        onlyOwner
    {
        MaxgiveawayAmountperTx = _maxgiveawayAmountPerTx;
    }
  function setBaseURI(string memory _newBaseURI) public onlyOwner {
    baseURI = _newBaseURI;
  }

  function setBaseExtension(string memory _newBaseExtension) public onlyOwner {
    baseExtension = _newBaseExtension;
  }
  
  function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner {
    notRevealedUri = _notRevealedURI;
  }

    function setPaused(bool _state) public onlyOwner {
        paused = _state;
    }

    function withdraw() public onlyOwner {
        (bool os, ) = payable(owner()).call{value: address(this).balance}("");
        require(os);
    }

    function _mintLoop(address _receiver, uint256 _mintAmount) internal {
        for (uint256 i = 0; i < _mintAmount; i++) {
            supply.increment();
            _safeMint(_receiver, supply.current());
        }
    }

    function _giveawayLoop(address _receiver, uint256 _giveawayAmount) internal {
        for (uint256 i = 0; i < _giveawayAmount; i++) {
            supply.increment();
            _safeMint(_receiver, supply.current());
            givedAway++;
        }
    }
}

you can use an interface:

interface contractA {
 function balanceOf(address _add) external view returns(uint256[]);
}

something like that.

contract B {
 contractA tokenA;

 function setA(address _add) public onlyOwner {
  tokenA = contractA(_add);
}

function mintB() public {
 uint256[] memory a = tokenA.ownerOf(msg.sender);
 mint(msg.sender, a.length);
 }
}

with that you have an interface that you can use to look up what NFTs msg.sender has. the mintB function takes the amount of NFTs he owns (ownerOf only gives tokenIds out in this example) and puts mints the amount. you also put the tokenIds in an blacklist array otherwise the msg.sender could just send the NFT to an other wallet and do it over again.

Getting an error that when I put in interface:

"ParserError: Function, variable, struct or modifier declaration expected.
--> Mini Contract/mini.sol:1335:5:
|
1335 | interface contractA {
| ^^^^^^^^^"

You can simply create a function that gets balanceof token a, then let it the amount returned = a variable, which you can use as max minting amount

Be proud of yourself most of us are self learned

Did you put the interface directly under the imports/solidity decleration
Do not put the interface in your contract. put it over the contract or under everything.