contract CheerkatMeerkatsChessClub is ERC721Enumerable, Ownable {
    uint public  MAX_TOKEN = 10000;
    uint public  basePrice = 40*10**15; // 
    uint public  basePriceBZC = 30*10**15; // 
    mapping (uint256 => bool) public _whitelistBZC;

	string _baseTokenURI;
	bool public saleEnable = false;

	CheerkatMeerkatsChessClub internal BZC = CheerkatMeerkatsChessClub(0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D);  // 0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D

    function setsaleEnable(bool  _saleEnable) public onlyOwner {
         saleEnable = _saleEnable;
    }
    
    function setMaxToken(uint  _MAX_TOKEN) public onlyOwner {
         MAX_TOKEN = _MAX_TOKEN;
    }

    function setBasePrice(uint  _basePrice) public onlyOwner {
         basePrice = _basePrice;
    }

    function setBasePriceBZC(uint  _basePriceBZC) public onlyOwner {
         basePriceBZC = _basePriceBZC;
    }

    constructor(string memory baseURI) ERC721("CheerkatMeerkatsChessClub", "CMCC")  {
        setBaseURI(baseURI);
    }

    function mint(address _to, uint _count) public payable {
        require(msg.sender == _owner || saleEnable, "Sale not enable");
        require(totalSupply() +_count <= MAX_TOKEN, "Exceeds limit");
        require(_count <= 50, "Exceeds 50");
        require(msg.value >= basePrice * _count || msg.sender == _owner , "Value below price");
      
        for(uint i = 0; i < _count; i++){
            _safeMint(_to, totalSupply());
            }
        
    }
    
  
    function _baseURI() internal view virtual override returns (string memory) {
        return _baseTokenURI;
    }
    
    function setBaseURI(string memory baseURI) public onlyOwner {
        _baseTokenURI = baseURI;
    }

    function tokensOfOwner(address _owner) external view returns(uint256[] memory) {
        uint tokenCount = balanceOf(_owner);

        uint256[] memory tokensId = new uint256[](tokenCount);
        for(uint i = 0; i < tokenCount; i++){
            tokensId[i] = tokenOfOwnerByIndex(_owner, i);
        }

        return tokensId;
    }

    function withdrawAll() public payable onlyOwner {
        _withdrawAll();
    }
     
    //mint for BZC
   function CompletedMintForBZC(uint256 _BZCid) public view virtual returns (bool) {
         return _whitelistBZC[_BZCid];
    }
   
    function TokenForMintAvailable(address _holder) public view virtual returns (uint256) {
        uint128  tokenAvailable = 0;
        uint256[] memory tokensId = new uint256[](BZC.balanceOf(_holder));
        for(uint i = 0; i < BZC.balanceOf(_holder); i++){
            tokensId[i] = BZC.tokenOfOwnerByIndex(_holder, i);
            
            if (_whitelistBZC[tokensId[i]])
              {} else {
                   tokenAvailable++;
              }
            
        }
    
        return tokenAvailable;
    }
    
        function mintForBAYC(uint _count) public payable{
        require(msg.sender == _owner || saleEnable, "Sale not enable");
        require(totalSupply() +_count <= MAX_TOKEN, "Exceeds limit");
        require(TokenForMintAvailable(msg.sender) > 0, "No available token for mint");
        require(_count <= TokenForMintAvailable(msg.sender), "Exceeds limit");
        require(msg.value >= basePriceBZC * _count , "Value below price");
       
        // mint counter per transaction
        uint  tokenMintLimit = 0;
        
        //check ever token whitelist
        uint256[] memory tokensId = new uint256[](BZC.balanceOf(msg.sender));
        for(uint i = 0; i < BZC.balanceOf(msg.sender); i++){
            tokensId[i] = BZC.tokenOfOwnerByIndex(msg.sender, i);
            //if not true in whitelist, to mint token
            if (_whitelistBZC[tokensId[i]])
            {} else {
                
                if(tokenMintLimit < _count) {
                    
                      _safeMint(msg.sender, totalSupply());
                      tokenMintLimit++;
                      _whitelistBZC[tokensId[i]] = true;
                    
                 }

              }

           }

        } 
    
 
}
function setsaleEnable(bool  _saleEnable) public onlyOwner {
     saleEnable = _saleEnable;
}

// 0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D