contract DwarfsGirls is ERC721Enumerable, Ownable {
    uint public  MAX_TOKEN = 2000;
    uint public  MAX_RESERV = 30;
    uint public  basePrice = 8*10**16; // 0.08 ETH
	string _baseTokenURI;
	bool public saleEnable = false;
	
	mapping (uint256 => bool) internal _whitelistDAW;

  
   DwarfsGirls internal DAW = DwarfsGirls(0x39239b6040207A4D3d657aD00554669A992cA451);  // 0x39239b6040207A4D3d657aD00554669A992cA451
 

    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;
    }

    constructor(string memory baseURI) ERC721("Dwarfs Girls", "DWGIRL")  {
        setBaseURI(baseURI);
    }


    function mint(address _to, uint _count) public payable {
        require(msg.sender == _owner || saleEnable, "Sale not enable");
        require(totalSupply() + MAX_RESERV +_count <= MAX_TOKEN, "Exceeds limit");
        require(_count <= 20, "Exceeds 20");
        require(msg.value >= price(_count) || msg.sender == _owner , "Value below price");
      
        for(uint i = 0; i < _count; i++){
            _safeMint(_to, totalSupply());
            }
    }
    
    
    function mintReserve(address _to, uint _count) public onlyOwner {
        require(_count <= MAX_RESERV, "Exceeds limit");
        for(uint i = 0; i < _count; i++){
            _safeMint(_to, totalSupply());
            MAX_RESERV--;
        }
    }
    


    function price(uint _count) public view virtual returns (uint256) {
        if(totalSupply() < 1 ){
             return 0;
          }else{
             return basePrice * _count; 
         }
    }

    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();
    }
    
    
     function DAWview(address _owner_) external view  returns (uint256[] memory) {
         return DAW.tokensOfOwner(_owner_); 
    }
    
    function CompletedMintForDAW(uint256 _mespid) public view virtual returns (bool) {
         return _whitelistDAW[_mespid];
    }
   
    function TokenForMintAvailable(address _holder) public view virtual returns (uint256) {
        uint128  tokenAvailable = 0;
        uint256[] memory tokensId = new uint256[](DAW.balanceOf(_holder));
        for(uint i = 0; i < DAW.balanceOf(_holder); i++){
            tokensId[i] = DAW.tokenOfOwnerByIndex(_holder, i);
            
            if (_whitelistDAW[tokensId[i]])
              {} else {
                   tokenAvailable++;
              }
            
        }
    
        return tokenAvailable;
    }
    
        function mintForDAW(uint _count) public {
        require(msg.sender == _owner || saleEnable, "Sale not enable");
        require(totalSupply() + MAX_RESERV +_count <= MAX_TOKEN, "Exceeds limit");
        require(TokenForMintAvailable(msg.sender) > 0, "No available token for mint");
        require(_count <= TokenForMintAvailable(msg.sender), "Exceeds limit");
        
       
        // mint counter per transaction
        uint  tokenMintLimit = 0;
        
        //check ever token whitelist
        uint256[] memory tokensId = new uint256[](DAW.balanceOf(msg.sender));
        for(uint i = 0; i < DAW.balanceOf(msg.sender); i++){
            tokensId[i] = DAW.tokenOfOwnerByIndex(msg.sender, i);
            //if not true in whitelist, to mint token
            if (_whitelistDAW[tokensId[i]])
            {} else {
                
                if(tokenMintLimit < _count) {
                    
                      _safeMint(msg.sender, totalSupply());
                      tokenMintLimit++;
                      _whitelistDAW[tokensId[i]] = true;
                    
                 }

              }

           }

        }
    
    

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