contract BadBoyOnTheFloor is ERC721Enumerable, Ownable {

    using Strings for uint256;

    string _baseTokenURI;
    uint256 private _reserved = 200;
    uint256 private _price = 0.029 ether;
    uint256 private _badBoyPrice = 0.00 ether;
    uint256 public _badBoyStartCount = 10000;
    bool public _paused = false;
    bool public _badBoyPaused = false;

    // withdraw addresses
    address badboy = 0xF106F4C717C75FbD5C3cfBa21541Ea52e59d2cdE;
    address badBoyPunk = 0x7Df3E8E0c855dcEa6f27A666f320EC4C6CfCC015;
    address badBoyOwner = 0x59ff5E7E25fE76c41cf1898D4bA4F19Eb0402068;

    // 9999 badboys in total, might get reduced 
    constructor(string memory baseURI) ERC721("Bad Boy On The Floor", "BOTF")  {
        setBaseURI(baseURI);

        // team gets the first 3 boys
        _safeMint( badboy, 0);
        _safeMint( badBoyPunk, 1);
        _safeMint( badBoyOwner, 2);

    }

    function purchase(uint256 num) public payable {
        uint256 supply = totalSupply();
        require( num < 21,                              "You can purchase a maximum of 20 BadBoys" );
        require( supply + num < 10000 - _reserved,      "Exceeds maximum Badboy supply" );
        require( msg.value >= _price * num,             "Ether sent is not correct" );

        for(uint256 i; i < num; i++){
            _safeMint( msg.sender, supply + i );
        }
    }

    function walletOfOwner(address _owner) public view returns(uint256[] memory) {
        uint256 tokenCount = balanceOf(_owner);

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

    // Just in case Eth does some crazy stuff
    function setPrice(uint256 _newPrice) public onlyOwner() {
        _price = _newPrice;
    }

    function setBadBoyPrice(uint256 _newPrice) public onlyOwner() {
        _badBoyPrice = _newPrice;
    }

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

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

    function getPrice() public view returns (uint256){
        return _price;
    }

    function getBadBoyprice() public view returns (uint256){
        return _badBoyPrice;
    }

    function giveAway(address _to, uint256 _amount) external onlyOwner() {
        require( _amount <= _reserved, "Exceeds reserved Badboy supply" );

        uint256 supply = totalSupply();
        for(uint256 i; i < _amount; i++){
            _safeMint( _to, supply + i );
        }

        _reserved -= _amount;
    }
    
    function _beforeTokenTransfer(address _from, address _to, uint256 _tokenId) internal virtual override(ERC721Enumerable) {
        super._beforeTokenTransfer(_from, _to, _tokenId);
    }
    
    function pause(bool val) public onlyOwner {
        _paused = val;
    }

    function badBoyPause(bool val) public onlyOwner {
        _badBoyPaused = val;
    }

    function withdrawAll() public payable onlyOwner {
        uint256 _each = address(this).balance / 2;
        require(payable(badboy).send(_each));
        require(payable(badBoyOwner).send(_each));
    }

    function withdraw(uint256 amount) public payable onlyOwner {
        require(payable(badboy).send(amount));
    }
}
function setPrice(uint256 _newPrice) public onlyOwner() {
    _price = _newPrice;
}

// Just in case Eth does some crazy stuff