contract HyenaHouse is ERC721, Ownable {
    using SafeMath for uint256;

    uint256 private _price = 50000000000000000;

    bool private _paused = true;

    uint private _reserve = 300;

    address _withdrawAddress = 0x963E0f3129fFeabE40516087Ed8739fe1070B589;

    constructor(string memory _baseURI) ERC721('Hyena House', 'HyenaHouse') {
        setBaseURI(_baseURI);
    }

    //MINT x amount of hyenas
    function mint(uint256 _num) public payable {
        uint supply = totalSupply();
        require(!_paused, "Minting is currently paused!");
        require(_num < 21, "You can only mint 20 Hyena's with each transaction!");
        require(supply + _num < 10000-_reserve, "Supply exceeded!");
        require(msg.value >= _price * _num, "ETH sent not correct!");

        for(uint i = 0; i < _num; i++) {
            _safeMint(msg.sender, supply+i);
        }
    }

    //GIVEAWAY x tokens to specific address
    function giveAway(address _to, uint256 _num) external onlyOwner() {
        require(_num <= _reserve, "Reserve is empty!" );

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

        _reserve -= _num;
    }


    //CHANGE PAUSE STATE
    function pause(bool _value) public onlyOwner {
        _paused = _value;
    }

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


    //RETURN ALL TOKENS OF A SPECIFIC ADDRESS
    function walletOfOwner(address _owner)
    external
    view
    returns (uint256[] memory)
    {
        uint256 tokenCount = balanceOf(_owner);

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

        return tokensId;
    }

    //RETURNS THE AMOUNT OF TOKES THAT HAVE BEEN MINTED ALREADY
    function returnSupply() external view returns (uint256) {
        return totalSupply();
    }

    //WITHDRAW CONTRACT BALANCE TO DEFINED ADDRESS
    function withdraw() public onlyOwner {
        uint balance = address(this).balance;
        payable(_withdrawAddress).transfer(balance);
    }

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

}
//TODO
// CHANGE WITHDRAW ADDRESS
function mint(uint256 _num) public payable {
    uint supply = totalSupply();
    require(!_paused, "Minting is currently paused!");
    require(_num < 21, "You can only mint 20 Hyena's with each transaction!");
    require(supply + _num < 10000-_reserve, "Supply exceeded!");
    require(msg.value >= _price * _num, "ETH sent not correct!");

    for(uint i = 0; i < _num; i++) {
        _safeMint(msg.sender, supply+i);
    }
}

//MINT x amount of hyenas