contract thelilguys is ERC721Enumerable, Ownable {

	using Strings for uint256;

	string _baseTokenURI;
	uint256 private _reserved = 50;
	uint256 private _price = 0.045 ether;
	bool public _paused = true;

	string private _passPhrase;
	bool public _claimPaused = true;

	// withdraw address
	address t1;

	constructor(string memory baseURI, string memory passPhrase) ERC721("thelilguys", "LILGUYS")  {
		setBaseURI(baseURI);
		_passPhrase = passPhrase;
		t1 = msg.sender;

		// team gets the first lilguy
		_safeMint(t1, 0);
	}

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

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

	function claimLilguy(string memory passCode) public {
		require( !_claimPaused, "OG free mint is over");
		uint256 supply = totalSupply();
		require( supply < 501, "OG freemint sold out");
		require( keccak256(bytes(passCode)) == keccak256(bytes(_passPhrase)), "Wrong passcode");
		address sender = msg.sender;
		require( balanceOf(sender) < 1, "OGs can only claim 1 lilguy");
		_safeMint(sender, supply);
	}

	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 giveAway(address _to, uint256 _amount) external onlyOwner {
		require( _amount <= _reserved, "Exceeds reserved lilguy supply" );

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

		_reserved -= _amount;
	}

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

	function pauseClaim(bool val) public onlyOwner {
		_claimPaused = val;
	}

	function setPassPhrase(string memory newPass) public onlyOwner {
		_passPhrase = newPass;
	}

	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