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

    string public PANDA_PROVENANCE = ""; // IPFS URL WILL BE ADDED WHEN PANDAS ARE ALL SOLD OUT
    
    string public LICENSE_TEXT = ""; // IT IS WHAT IT SAYS
    
    bool licenseLocked = false; // TEAM CAN'T EDIT THE LICENSE AFTER THIS GETS TRUE

    uint256 public constant pandaPrice = 40000000000000000; // 0.04 ETH

    uint public constant maxPandaPurchase = 15;

    uint256 public constant MAX_PANDAS = 5000;

    bool public dropIsActive = false;

    address t1 = 0xBC11c14f20B972BC2b4eb34F034bA2D996524bAc;
    address t2 = 0x9D096539D98B4bD35a5a3a5587edb2E8534170F7;
    address t3 = 0x98f1CB4CA11465a707Efb4Cdd430d3e4B855b72b;
    address t4 = 0x65b9FBc2f455E19D92EcD78De7f373a11A99E8cE;
    
    // Reserve 30 Pandas for team - Giveaways/Prizes etc
    uint public pandasReserved = 30;
    
    event pandaNameChange(address _by, uint _tokenId, string _name);
    
    event licenseisLocked(string _licenseText);

    constructor() ERC721("Posh Pandas", "Panda") { }
    
    function withdraw() public onlyOwner {
        uint balance = address(this).balance;
        msg.sender.transfer(balance);
    }

    function withdraw_all() public onlyOwner {
        uint _each = address(this).balance / 4;
        require(payable(t1).send(_each));
        require(payable(t2).send(_each));
        require(payable(t3).send(_each));
        require(payable(t4).send(_each));

    }
    
    function reservePandas(address _to, uint256 _reserveAmount) public onlyOwner{
        uint supply = totalSupply();
        require(_reserveAmount > 0 && _reserveAmount <= pandasReserved, "NOT ENOUGH PANDAS FOR GIVEAWAYS");
        for (uint i = 0; i < _reserveAmount; i++){
            _safeMint(_to, supply + i);
        }
        pandasReserved = pandasReserved.sub(_reserveAmount);
    }


    function setProvenanceHash(string memory provenanceHash) public onlyOwner {
        PANDA_PROVENANCE = provenanceHash;
    }

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


    function flipDropState() public onlyOwner {
        dropIsActive = !dropIsActive;
    }
    
    
    function tokensOfOwner(address _owner) external view returns(uint256[] memory ) {
        uint256 tokenCount = balanceOf(_owner);
        if (tokenCount == 0) {
            // Return an empty array
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](tokenCount);
            uint256 index;
            for (index = 0; index < tokenCount; index++) {
                result[index] = tokenOfOwnerByIndex(_owner, index);
            }
            return result;
        }
    }
    
    // Returns the license for tokens
    function tokenLicense(uint _id) public view returns(string memory) {
        require(_id < totalSupply(), "CHOOSE A PANDA WITHIN RANGE");
        return LICENSE_TEXT;
    }
    
    // Locks the license to prevent further changes 
    function lockLicense() public onlyOwner {
        licenseLocked =  true;
        emit licenseisLocked(LICENSE_TEXT);
    }
    
    // Change the license
    function changeLicense(string memory _license) public onlyOwner {
        require(licenseLocked == false, "License already locked");
        LICENSE_TEXT = _license;
    }
    
    
    function mintPoshPanda(uint numberOfTokens) public payable{
        require(dropIsActive, "Drop must be active to mint a Panda");
        require(numberOfTokens > 0 && numberOfTokens <= maxPandaPurchase, "Only 15 Pandas can be minted at once");
        require(totalSupply().add(numberOfTokens) <= MAX_PANDAS, "Purchase would exceed max supply of Pandas");
        require(msg.value >= pandaPrice.mul(numberOfTokens), "Ether value sent is incorrect");

        for (uint i = 0; i < numberOfTokens; i++){
            uint mintIndex = totalSupply();
            if (totalSupply() < MAX_PANDAS){
                _safeMint(msg.sender, mintIndex);
            }
        }
    } 
}
function changeLicense(string memory _license) public onlyOwner {
    require(licenseLocked == false, "License already locked");
    LICENSE_TEXT = _license;
}

// Change the license