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

    string public SLOTH_PROVENANCE = "";

    uint256 public constant slothPrice = 66000000000000000; //0.066 ETH

    uint public constant maxSlothPurchase = 20;

    uint256 public MAX_SLOTHS;

    bool public saleIsActive = false;

    bool public sealedMetadata = false;
    

    address payable private devAddress = 0xB90A3395eA2baf1b2e5C01E3A5Cf1AaE0Dd95D2d;// 4%;
    
    address payable private treasuryAddress = 0xb39f278FC22393569b0341Bd407C5feCab0fce52; // 21%

    address payable private coreteamAddress = 0xDCC901529c4FF557156d56D7f7dc980ebfA9e754; // 24%
    address payable private artist1Address = 0xe0B1532ecd193637662a8dFAE2495354d54556E1; // 20%
    address payable private team2Address = 0x343FCEbEF2366f5E15a225F5b4564C2b7cc388E4; // 20%
    address payable private strategicAddress = 0x0E621e8146b009e6428EcC39E5c3B82AA097FE61; // 6%
    address payable private artist2Address = 0x032e70c32f7f9d463cd30a141a20f7EbF4360964; // 5%

    constructor() ERC721("SleazySlothSyndicate", "SLOTH") {
        MAX_SLOTHS = 10000;

        setBaseURI('https://sleazysloth.com/api/sleazysloth/');
    }

    function withdraw() public onlyOwner {
        uint balance = address(this).balance;
                
        uint256 devFee = balance.mul(4).div(100);
        uint256 coreteamFee = balance.mul(24).div(100);
        uint256 treasuryFee = balance.mul(21).div(100);
        uint256 artist1Fee = balance.mul(20).div(100);
        uint256 team2Fee = balance.mul(20).div(100);
        uint256 strategicFee = balance.mul(6).div(100);
        uint256 artist2Fee = balance.mul(5).div(100);

        devAddress.transfer(devFee);
        coreteamAddress.transfer(coreteamFee);
        treasuryAddress.transfer(treasuryFee);
        artist1Address.transfer(artist1Fee);
        team2Address.transfer(team2Fee);
        strategicAddress.transfer(strategicFee);
        artist2Address.transfer(artist2Fee);
    }

    function withdrawTokens(address _tokenAddr, address _to) public onlyOwner {
        require(_tokenAddr != address(this), "Cannot transfer out own tokens from contract!");
        IERC20(_tokenAddr).transfer(_to, IERC20(_tokenAddr).balanceOf(address(this)));
    }

    /*     
    * Set provenance once it's calculated
    */
    function setProvenanceHash(string memory provenanceHash) public onlyOwner {
       SLOTH_PROVENANCE = provenanceHash;
    }

    function setBaseURI(string memory baseURI) public onlyOwner {
        require(!sealedMetadata, "Metadata is sealed forever.");
        _setBaseURI(baseURI);
    }

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

    /*
    * Seals the Metadata 
    */
    function sealMetadata() public onlyOwner {
        sealedMetadata = true;
    }


    /**
    * Mints Sloths
    */
    function mintSloth(uint numberOfTokens) public payable {
        require(saleIsActive, "Sale must be active to mint Sloth");
        require(numberOfTokens <= maxSlothPurchase, "Can only mint 20 tokens at a time");
        require(totalSupply().add(numberOfTokens) <= MAX_SLOTHS, "Purchase would exceed max supply of Sloths");
        require(slothPrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        

        for(uint i = 0; i < numberOfTokens; i++) {
            uint mintIndex = totalSupply().add(1);
            if (totalSupply() < MAX_SLOTHS) {
                _safeMint(msg.sender, mintIndex);
            }
        }

    }

    
}
/**
 * @title SleazySloth contract
 * @dev Extends ERC721 Non-Fungible Token Standard basic implementation
 */
function flipSaleState() public onlyOwner {
    saleIsActive = !saleIsActive;
}

/*
 * Pause sale if active, make active if paused
 */