contract ProceduralSpace is ERC721, Ownable {
    uint256 public count = 0;
    
    event Increment(address who);

    using SafeMath for uint256;
    uint256 public planetPrice = 100000000000000000; //0.1 ETH
    uint public constant maxPlanetPurchase = 20;
    uint256 public MAX_PLANETS;
    bool public saleIsActive = false;

    constructor(string memory name, string memory symbol, uint256 maxNftSupply) ERC721(name, symbol) {
        MAX_PLANETS = maxNftSupply;
    }

    function withdraw() public onlyOwner {
        uint balance = address(this).balance;
        msg.sender.transfer(balance);
    }

    // Reserves 30 planets
    function reservePlanets() public onlyOwner {        
        uint supply = totalSupply();
        uint i;
        for (i = 0; i < 30; i++) {
            _safeMint(msg.sender, supply + i);
            count += 1;
        }
        emit Increment(msg.sender);
    }

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

    function flipSaleState() public onlyOwner {
        saleIsActive = !saleIsActive;
    }

    function discoverPlanet(uint numberOfTokens) public payable {
        require(saleIsActive, "Sale must be active to mint Planet");
        require(numberOfTokens <= maxPlanetPurchase, "Can only mint 20 tokens at a time");
        require(totalSupply().add(numberOfTokens) <= MAX_PLANETS, "Purchase would exceed max supply of Planets");
        require(planetPrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        
        for(uint i = 0; i < numberOfTokens; i++) {
            uint mintIndex = totalSupply();
            if (totalSupply() < MAX_PLANETS) {
                _safeMint(msg.sender, mintIndex);
                count += 1;
            }
        }

        emit Increment(msg.sender);
    }

    function getCount() public view returns(uint256) {
        return count;
    }

    // Emergency: can be changed to account for large fluctuations in ETH price
    function emergencyChangePrice(uint256 newPrice) public onlyOwner {
        planetPrice = newPrice;
    }
}
/**
 * @title ProceduralSpace contract
 * @dev Extends ERC721 Non-Fungible Token Standard basic implementation
 */
function reservePlanets() public onlyOwner {        
        uint supply = totalSupply();
        uint i;
        for (i = 0; i < 30; i++) {
            _safeMint(msg.sender, supply + i);
            count += 1;
        }
        emit Increment(msg.sender);
    }
// Reserves 30 planets