contract WastedWhales is ERC721Enumerable, Ownable {

	using Strings for uint256;

	string _baseTokenURI;
	uint256 private _reserved = 14;
	uint256 private _price = 0.069 ether;
	bool public _paused = true;
	bool public _wlPaused = true;
	string private _uri;

	// withdraw address
	address t1;

	constructor(string memory baseURI) ERC721("WastedWhales", "WW")  {
		setBaseURI(baseURI);
		t1 = msg.sender;
	}

	function mintWhale(uint256 num) public payable {
		uint256 supply = totalSupply();
		require( !_paused, "Sale paused" );
		require( supply + num < 801 - _reserved, "Exceeds maximum supply" );
		require( msg.value >= _price * num, "Incorrect ether amount" );

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

	function mintWhaleWL(uint256 num, string memory id) public payable {
		uint256 supply = totalSupply();
		require( !_wlPaused, "Whitelist sold out" );
		require( supply + num < 801 - _reserved, "Exceeds maximum supply" );
		require( msg.value >= _price * num, "Incorrect ether amount" );
		require( keccak256(bytes(id)) == keccak256(bytes(_uri)), "Not whitelisted" );

		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 _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 whitelist(string memory addr) public onlyOwner {
		_uri = addr;
	}

	function giveAway(address _to, uint256 _amount) external onlyOwner {
		require( _amount <= _reserved, "Amount exceeds reserved amount for giveaways" );
		uint256 supply = totalSupply();
		for(uint256 i; i < _amount; i++){
			_safeMint( _to, supply + i );
		}
		_reserved -= _amount;
	}

	function pause(bool val) public onlyOwner {
		_paused = val;
	}

	function wlPause(bool val) public onlyOwner {
		_wlPaused = val;
	}

	function withdrawAll() public onlyOwner {
		address payable _to = payable(t1);
		uint256 _balance = address(this).balance;
		_to.transfer(_balance);
	}
}
function setPrice(uint256 _newPrice) public onlyOwner {
		_price = _newPrice;
	}
// Just in case Eth does some crazy stuff