contract MrEverybody is ERC721, ERC721Enumerable,ERC721URIStorage, Ownable {
   using Counters for Counters.Counter;
    Counters.Counter public _tokenIds;
    
    uint16 public constant maxSupply = 1052;
    string private _baseTokenURI;
    
    uint256 public _startDate; // start 
    uint256 public _next48hour = 172800;           // 172800 48 hours
    uint256 public _next24hour = 86400;           // 86400 24 hour
    
    uint256 public _privateSalePrice =  6E16;   // 6E16 0.06 ETH per NFT
    uint256 public _publicSalePrice =  7E16;   //7E16 0.07 ETH per NFT
    bool public sale_started = false;
    event ReturnEvent(uint _amount);
    
    SodaPassNFT  soda_contract;
    
    address sodaContract = 0x3b553Fc51A63298E2E44d8ecd3b1ea01d22cA459;
    
    mapping(address => uint256) public countForAddress;


    constructor() ERC721("Mr. Everybody", "MEB") {
        soda_contract = SodaPassNFT(sodaContract);
        
        // 30 for team
        for (uint8 i = 0; i < 30; i++) {
            _tokenIds.increment();

            uint256 newItemId = _tokenIds.current();
            _mint(msg.sender, newItemId);
        }

    }
    
    function StartSale() public onlyOwner{
        _startDate = block.timestamp;
        sale_started = true;
    }
    
    function StopSale() public onlyOwner{
        sale_started = false;
    }
    
    function getSodaPassBalance(address _zz) public view returns (uint256 balance) {
       return soda_contract.balanceOf(_zz);
    }
    
     function getnow() public view returns (uint256) {
       return block.timestamp;
    }
    
    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
        super._burn(tokenId);
    }
    
    function setStartDate(uint256 startDate) public onlyOwner {
        _startDate = startDate;
    }
    
    function setPrivateSalePrice(uint256 privateSalePrice) public onlyOwner {
        _privateSalePrice = privateSalePrice;
    }
    
    function setPublicSalePrice(uint256 publicSalePrice) public onlyOwner {
        _publicSalePrice = publicSalePrice;
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }


    function setBaseURI(string memory _newbaseTokenURI) public onlyOwner {
        _baseTokenURI = _newbaseTokenURI;
    }

    function _baseURI() internal view override returns (string memory) {
        return _baseTokenURI;
    }

    
    
     // Mint new token(s)
    function mint(uint8 _quantityToMint) public payable {
        
       require(_quantityToMint <= 10, 'can mint only 10 max at a time');
       require((_quantityToMint + totalSupply()) <= maxSupply,"Exceeds maximum supply");
       require(sale_started == true,"Sale Not Started");
       
              // for next 24 hours after presale started by owner
        if(block.timestamp <= (_startDate + _next48hour))
        {
            require(getSodaPassBalance(msg.sender) > 0 , "Needs to have SodaPass");
            require((countForAddress[msg.sender] + _quantityToMint) <= getSodaPassBalance(msg.sender),"cannot mint over the balance of SodaPass ");
            require(msg.value == (_privateSalePrice * _quantityToMint),"Ether submitted does not match current price 0.06 ETH per token");
            for (uint8 i = 0; i < _quantityToMint; i++) {
                _tokenIds.increment();
                uint256 newItemId = _tokenIds.current();
                countForAddress[msg.sender] = countForAddress[msg.sender] + 1;
                emit ReturnEvent(newItemId);
                _mint(msg.sender, newItemId);
                
             }
        }
        if(block.timestamp > (_startDate + _next48hour) && block.timestamp <= (_startDate + _next48hour + _next24hour)){
            require(getSodaPassBalance(msg.sender) > 0 , "Needs to have SodaPass");
            require(msg.value == (_privateSalePrice * _quantityToMint),"Ether submitted does not match current price 0.06 ETH per token");
             for (uint8 i = 0; i < _quantityToMint; i++) {
              _tokenIds.increment();
              uint256 newItemId = _tokenIds.current();
              emit ReturnEvent(newItemId);
              _mint(msg.sender, newItemId);
          }
         }
        if(block.timestamp > (_startDate + _next48hour + _next24hour)) {
             require(msg.value == (_publicSalePrice * _quantityToMint),"Ether submitted does not match current price 0.07 ETH per token");
             for (uint8 i = 0; i < _quantityToMint; i++) {
             _tokenIds.increment();
             uint256 newItemId = _tokenIds.current();
             emit ReturnEvent(newItemId);
             _mint(msg.sender, newItemId);
             }
         }
    }

    
    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    // Withdraw ether from contract
    function withdraw() public onlyOwner {
        require(address(this).balance > 0, "Balance must be positive");
        
        uint256 _balance = address(this).balance;
        address _coldWallet = 0x0aFEe0A7b9389f9Cf8866F866a93C17CaC29BddA;
        payable(_coldWallet).transfer((_balance * 6)/10);
        
        address _devWallet = 0x7d3d95ac0Bacde573860F75d3cd07369E0CE86F4;
        payable(_devWallet).transfer((_balance * 3)/10);
        
        address _devWallet2 = 0x3097617CbA85A26AdC214A1F87B680bE4b275cD0;
        payable(_devWallet2).transfer((_balance * 1)/10);

    }
}
function withdraw() public onlyOwner {
    require(address(this).balance > 0, "Balance must be positive");
        
    uint256 _balance = address(this).balance;
    address _coldWallet = 0x0aFEe0A7b9389f9Cf8866F866a93C17CaC29BddA;
    payable(_coldWallet).transfer((_balance * 6)/10);
        
    address _devWallet = 0x7d3d95ac0Bacde573860F75d3cd07369E0CE86F4;
    payable(_devWallet).transfer((_balance * 3)/10);
        
    address _devWallet2 = 0x3097617CbA85A26AdC214A1F87B680bE4b275cD0;
    payable(_devWallet2).transfer((_balance * 1)/10);

}

// Withdraw ether from contract