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

    uint256 public pricePresale = 140000000000000000; //0.14 ETH
    uint256 public pricePublicSale = 350000000000000000; //0.35 ETH

    uint public maxPurchasePresale = 5;
    uint public maxPurchasePublicSale = 10;


    uint256 public constant MAX = 5555;
    uint256 public  MAX_PRESALE = 500;

    bool public saleIsActive = false;
    
    bool public presale = true;
    
    

    constructor() ERC721("MetaSkeletons", "MSK") {
    }
    

    function withdraw() public onlyOwner {
        uint balance = address(this).balance;
        
        address payable one = payable(owner());
        one.transfer(balance);
    }

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

    /*
    * Pause sale if active, make active if paused
    */
    function flipSaleState() public onlyOwner {
        saleIsActive = !saleIsActive;
    }


    function changePresalePrice(uint256 price) public onlyOwner {
        pricePresale = price;
    }

    function changePublicSalePrice(uint256 price) public onlyOwner {
        require(price >= 140000000000000000, "Price cant go below 0.14");
        pricePublicSale = price;
    }

    function changePublicSaleMaxMintPerTx(uint256 maxMint) public onlyOwner {
        maxPurchasePublicSale = maxMint;
    }

    function changePreSaleMaxMintPerTx(uint256 maxMint) public onlyOwner {
        maxPurchasePresale = maxMint;
    }
    
      /*
    * Include so everyone can participate
    */
    function endPresaleStartPublicSale() public onlyOwner {
        presale = false;
    }

      /**
    * Mints MSK Presale
    */
    function mintPresale(uint numberOfTokens) public payable {
        require(saleIsActive, "Sale must be active to mint MSK");
        require(presale , "Presale Must be active");
        require(numberOfTokens <= maxPurchasePresale, "Can only mint 5 tokens at a time");
        require(pricePresale.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        require(totalSupply().add(numberOfTokens) <= MAX_PRESALE, "Purchase would exceed pre sale limit of MSK");
        
        for(uint i = 0; i < numberOfTokens; i++) {
            uint mintIndex = totalSupply() + 1;
            if (mintIndex <= MAX) {
                _safeMint(msg.sender, mintIndex);
            }
        }
    }
    
    
    /**
    * Mints MSK Public Sale
    */
    function mintMSK(uint numberOfTokens) public payable {
        require(saleIsActive, "Sale must be active to mint MSK");
        require(!presale , "Public Sale Must be active");
        require(numberOfTokens <= maxPurchasePublicSale, "Can only mint 10 tokens at a time");
        require(totalSupply().add(numberOfTokens) <= MAX, "Purchase would exceed Max Supply of MSK");
        require(pricePublicSale.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        
        
        for(uint i = 0; i < numberOfTokens; i++) {
            uint mintIndex = totalSupply() + 1;
            if (mintIndex <= MAX) {
                _safeMint(msg.sender, mintIndex);
            }
        }
    }
}
/**
 * @title MSK Contract
 * @dev Extends ERC721 Non-Fungible Token Standard basic implementation
 */
function mintMSK(uint numberOfTokens) public payable {
        require(saleIsActive, "Sale must be active to mint MSK");
        require(!presale , "Public Sale Must be active");
        require(numberOfTokens <= maxPurchasePublicSale, "Can only mint 10 tokens at a time");
        require(totalSupply().add(numberOfTokens) <= MAX, "Purchase would exceed Max Supply of MSK");
        require(pricePublicSale.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        
        
        for(uint i = 0; i < numberOfTokens; i++) {
            uint mintIndex = totalSupply() + 1;
            if (mintIndex <= MAX) {
                _safeMint(msg.sender, mintIndex);
            }
        }
    }
/**
 * Mints MSK Public Sale
 */