contract CanvasRegistry is ERC1155, Ownable {
    using Strings for uint;
    string private _uri;

    event TransferCanvasOwnership(address indexed from, address indexed to, uint indexed tokenId);

    mapping (uint => address) public canvasOwners;
    ERC1155 presaleMintPass;
    uint public mintPrice = 0.01 ether;

    bool publicSale;
    bool mintingPaused;

    constructor(address presaleMintPassAddress, string memory initialURI) {
        presaleMintPass = ERC1155(presaleMintPassAddress);
        _uri = initialURI;
    }

    function transferCanvasOwnership(uint tokenId, address newOwner) public {
        require(canvasOwners[tokenId] == msg.sender);
        canvasOwners[tokenId] = newOwner; 
        emit TransferCanvasOwnership(msg.sender, newOwner, tokenId);
    }

    function mint(uint label, uint amount) public payable {
        require(publicSale && !mintingPaused, "Presale active");
        require(msg.value >= mintPrice * amount, "Requires more Ether");
        require(canvasOwners[label] == address(0), "This CNVS already exists.");

        canvasOwners[label] = msg.sender; 
        _mint(msg.sender, label, amount, "");
    }

    function gift(uint label, uint amount, address to) public payable {
        require(publicSale && !mintingPaused, "Presale active");
        require(msg.value >= mintPrice * amount, "Requires more Ether");
        require(canvasOwners[label] == address(0), "This CNVS already exists.");

        canvasOwners[label] = to; 
        _mint(to, label, amount, "");
    }

    function mintPresale(uint label, uint amount) public {
        require(
            !publicSale && 
            !mintingPaused && 
            (presaleMintPass.balanceOf(msg.sender, 1) > 0 || presaleMintPass.balanceOf(msg.sender, 2) > 0),
             "You are not elligible for presale."
        );
        require(canvasOwners[label] == address(0), "This CNVS already exists.");

        canvasOwners[label] = msg.sender; 
        _mint(msg.sender, label, amount, "");
    }

    function setMintPrice(uint newMintPrice) public onlyOwner {
        mintPrice = newMintPrice;
    }

    function setURI(string memory newURI) public onlyOwner {
        _uri = newURI;
    }

    /// @dev Can only be activated once, on purpose
    function setPublicSale() public onlyOwner {
        publicSale = true;
    }

    function setMintingPaused(bool paused) public onlyOwner {
        mintingPaused = paused;
    }

    function uri(uint id) public view virtual override returns (string memory) {
        return string(abi.encodePacked(_uri, id.toString()));
    } 

    function withdrawal(address receiver) public onlyOwner {
        payable(receiver).transfer(address(this).balance);
    }
}
/* import "../lib/solmate/src/tokens/ERC1155.sol"; */
function setPublicSale() public onlyOwner {
    publicSale = true;
}

/// @dev Can only be activated once, on purpose