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

    string public BitMatesRecord = "";

    uint256 public constant bitMatePrice = 70000000000000000; //0.07 ETH

    uint public constant maxApePurchase = 20;

    uint256 public maxBitMates;

    bool public saleIsActive = false;
    
    // addresses
    
    // founder address
    address t1 = 0x2ae929FD768bE055d5B39eb8140F5Ba537362fC8;
    address t2 = 0xCe43925a55c876e7904C3ea262b29Eecd0D0109b;
    
    
    //BitMates multisig
    address t3 = 0x44513A31cA10750F1FF4B7bDAf00591c183802a2;
   

    constructor(string memory name, string memory symbol, uint256 maxNftSupply) ERC721(name, symbol) {
        maxBitMates = maxNftSupply;
        
        // Setting the first 2 BitMates
        _safeMint( t2, 0);
        _safeMint( t1, 1);
        

    }
    
    /* 
    Withdrawing the funds from the contract
    */
    function withdrawAll() public payable onlyOwner {
        uint256 _each = address(this).balance;
        require(payable(t3).send(_each));
    }

    /*
    * Set some BitMates aside
    */
    function reserveApes(uint numberOfTokens) public onlyOwner {  
        require(totalSupply().add(numberOfTokens) <= maxBitMates, "Purchase would exceed max supply of BitMates");
        
        for (uint i = 0; i < numberOfTokens; i++) {
            uint mintIndex = totalSupply();
            if (totalSupply() < maxBitMates) {
                _safeMint(msg.sender, mintIndex);
            }
        }
    }


    /*     
    * Set IPFS pointer after conclusion of sale
    */
    function setProvenanceHash(string memory provenanceHash) public onlyOwner {
        BitMatesRecord = provenanceHash;
    }

    /* 
    Sets the pointer for the metadata
    */
    function setBaseURI(string memory baseURI) public onlyOwner {
        _setBaseURI(baseURI);
    }

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

    /*
    * Mints BitMates
    */
    function mintApe(uint numberOfTokens) public payable {
        require(saleIsActive, "Sale must be active to mint BitMate");
        require(numberOfTokens <= maxApePurchase, "Can only mint 20 tokens at a time");
        require(totalSupply().add(numberOfTokens) <= maxBitMates, "Purchase would exceed max supply of BitMates");
        require(bitMatePrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        
        for(uint i = 0; i < numberOfTokens; i++) {
            uint mintIndex = totalSupply();
            if (totalSupply() < maxBitMates) {
                _safeMint(msg.sender, mintIndex);
            }
        }
    }
    
    
    /*
    Allows calldata to be used to store metadata on-chain
    Credits to @0xmons // for more info: https://blog.0xmons.xyz/79081566310
    */
    function uploadBitMateImage(bytes calldata s) external onlyOwner {}
    
    
    /*
    Allows calldata to be used to store metadata on-chain
    Credits to @0xmons // for more info: https://blog.0xmons.xyz/79081566310
    */
    function uploadBitMateAttributes(bytes calldata s) external onlyOwner {}

}
/**
 * @title BitMates contract
 * https://bitmates.io
 * @dev Extends ERC721 Non-Fungible Token Standard basic implementation
 */
function flipSaleState() public onlyOwner {
    saleIsActive = !saleIsActive;
}

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