contract ShittyFuckingToken is ERC721, Ownable {

    uint256 public tokenCounter = 0;
    uint256 public currentSftCount = 200;
    bool public saleIsActive = false;

    // Base URI
    string private baseURI;

    //Minting Price of SFT
    uint256 public sftPrice = 10000000000000000; // 0.01 ETH
    
    constructor () ERC721 ("Shitty Fucking Tokens", "SFT"){}

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

    // Enable/Disable the ability to mint
    function flipSaleState() public onlyOwner {
        saleIsActive = !saleIsActive;
    }

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

    function _baseURI() internal view override returns(string memory){
        return baseURI;
    }

    // Enable/Disable the ability to mint
    function setSftCount(uint256 count) public onlyOwner {
        currentSftCount = count;
    }

    // Enable/Disable the ability to mint
    function setSftPrice(uint256 price) public onlyOwner {
        sftPrice = price;
    }



    //Public Mint Shitty Fucking Token
    function mintShittyFuckingToken(uint sftTokenId) public payable {
        require(saleIsActive, "Sale must be active to mint SFT");
        require(sftTokenId > 0 && sftTokenId <=currentSftCount, "Must Pick an sft within valid range");
        require(msg.value >= sftPrice, "Ether value sent is not correct");
        require(!_exists(sftTokenId), "This SFT was already minted");
        
        _safeMint(msg.sender, sftTokenId);
        tokenCounter = tokenCounter + 1;
    }


    // Special Mint 
    function specialMint(uint sftTokenId) public onlyOwner {
        require(sftTokenId > 0 && sftTokenId <=currentSftCount, "Must Pick an sft within valid range");
        require(!_exists(sftTokenId), "This SFT was already minted");
        
        _safeMint(msg.sender, sftTokenId);
        tokenCounter = tokenCounter + 1;
    }




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

// Withdraw