pragma solidity ^0.8.0;



contract chaoticDJs is OERC721 {
    using Strings for uint256;

    bytes32 private _glRoot;
    uint256 private _glPrice;
    uint256 private _glUserMintLimit;
    uint256 private _glMintLimit;
    uint256 private _glActive;

    mapping(address => uint256) _glUserMints; //Amount of mints performed by this user
    uint256 private _glMints; //Amount of mints performed in this mint


    bytes32 private _wlRoot;
    uint256 private _wlPrice;
    uint256 private _wlUserMintLimit;
    uint256 private _wlMintLimit;
    uint256 private _wlActive;

    mapping(address => uint256) _wlUserMints; //Amount of mints performed by this user
    uint256 private _wlMints; //Amount of mints performed in this mint


    uint256 private _pmPrice;
    uint256 private _pmUserMintLimit;
    uint256 private _pmActive;

    mapping(address => uint256) _pmUserMints; //Amount of mints performed by this user

    uint256 _maxSupply;

    uint256 private _reveal;

    constructor() {
        _name = "Chaotic DJs";
        _symbol = "CDS";
    }

    //Read Functions===========================================================================================================================================================

    function tokenURI(uint256 tokenId) external view override returns (string memory) {
        if(_reveal == 1) {return string(abi.encodePacked(uriLink, tokenId.toString(), ".json"));}

        return string(abi.encodePacked(uriLink, "secret.json"));
    }

    function glData(address user) external view returns(uint256 userMints, uint256 mints, uint256 price, uint256 userMintLimit, uint256 mintLimit, bytes32 root, bool active) {
        userMints = _glUserMints[user];
        mints = _glMints;
        price = _glPrice;
        userMintLimit = _glUserMintLimit;
        mintLimit = _glMintLimit;
        active = _glActive == 1;
        root = _glRoot;
    }

    function wlData(address user) external view returns(uint256 userMints, uint256 mints, uint256 price, uint256 userMintLimit, uint256 mintLimit, bytes32 root, bool active) {
        userMints = _wlUserMints[user];
        mints = _wlMints;
        price = _wlPrice;
        userMintLimit = _wlUserMintLimit;
        mintLimit = _wlMintLimit;
        active = _wlActive == 1;
        root = _wlRoot;
    }

    function pmData(address user) external view returns(uint256 userMints, uint256 price, uint256 userMintLimit, bool active) {
        userMints = _pmUserMints[user];
        price = _pmPrice;
        userMintLimit = _pmUserMintLimit;
        active = _pmActive == 1;
    }

    function maxSupply() external view returns(uint256) {return _maxSupply;}

    //Moderator Functions======================================================================================================================================================

    function setGlData(uint256 price, uint256 userMintLimit, uint256 mintLimit, bytes32 root, uint256 active) external Manager {
        _glPrice = price;
        _glUserMintLimit = userMintLimit;
        _glMintLimit = mintLimit;
        _glActive = active;
        _glRoot = root;
    }

    function setWlData(uint256 price, uint256 userMintLimit, uint256 mintLimit, bytes32 root, uint256 active) external Manager {
        _wlPrice = price;
        _wlUserMintLimit = userMintLimit;
        _wlMintLimit = mintLimit;
        _wlActive = active;
        _wlRoot = root;
    }

    function setPmData(uint256 price, uint256 userMintLimit, uint256 active) external Manager {
        _pmPrice = price;
        _pmUserMintLimit = userMintLimit;
        _pmActive = active;
    }

    function setMaxSupply(uint256 maxSupply) external Manager {
        _maxSupply = maxSupply;
    }

    function setReveal(uint256 reveal) external Manager {
        _reveal = reveal;
    }

    //User Functions======================================================================================================================================================

    function glMint(bytes32[] calldata _merkleProof) external payable {
        require(_glMints < _glMintLimit, "CDS: WL has sold out");
        require(_glActive == 1, "CDS: WL minting is closed");

        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
        require(MerkleProof.verify(_merkleProof, _glRoot, leaf), "NOT_GOLD_LISTED");

        uint256 price = _glPrice;

        require(msg.value % price == 0, "CDS: Wrong Value");

        uint256 amount = msg.value / price;

        require((_glMints += amount) <= _glMintLimit, "CDS: Mint Limit Exceeded");
        require((_glUserMints[msg.sender] += amount) <= _glUserMintLimit, "CDS: User Mint Limit Exceeded");

        _mint(msg.sender, amount);

        require(_totalSupply <= _maxSupply, "CDS: Supply Exceeded");
    }

    function wlMint(bytes32[] calldata _merkleProof) external payable {
        require(_wlMints < _wlMintLimit, "CDS: WL has sold out");
        require(_wlActive == 1, "CDS: WL minting is closed");

        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
        require(MerkleProof.verify(_merkleProof, _wlRoot, leaf), "NOT_GOLD_LISTED");

        uint256 price = _wlPrice;

        require(msg.value % price == 0, "CDS: Wrong Value");

        uint256 amount = msg.value / price;

        require((_wlMints += amount) <= _wlMintLimit, "CDS: Mint Limit Exceeded");
        require((_wlUserMints[msg.sender] += amount) <= _wlUserMintLimit, "CDS: User Mint Limit Exceeded");

        _mint(msg.sender, amount);

        require(_totalSupply <= _maxSupply, "CDS: Supply Exceeded");
    }

    function pmMint() external payable {
        require(_pmActive == 1, "CDS: WL minting is closed");

        uint256 price = _pmPrice;

        require(msg.value % price == 0, "CDS: Wrong Value");

        uint256 amount = msg.value / price;

        require((_pmUserMints[msg.sender] += amount) <= _pmUserMintLimit, "CDS: User Mint Limit Exceeded");

        _mint(msg.sender, amount);

        require(_totalSupply <= _maxSupply, "CDS: Supply Exceeded");
    }



}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"SetManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"_operatorApprovals","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_tokenApprovals","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"to","type":"address[]"},{"internalType":"uint256[]","name":"amount","type":"uint256[]"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"adminMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"name":"changeData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newUri","type":"string"}],"name":"changeURIlink","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"glData","outputs":[{"internalType":"uint256","name":"userMints","type":"uint256"},{"internalType":"uint256","name":"mints","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"userMintLimit","type":"uint256"},{"internalType":"uint256","name":"mintLimit","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"bool","name":"active","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"glMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"manager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"pmData","outputs":[{"internalType":"uint256","name":"userMints","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"userMintLimit","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pmMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"userMintLimit","type":"uint256"},{"internalType":"uint256","name":"mintLimit","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"uint256","name":"active","type":"uint256"}],"name":"setGlData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"setManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"setNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"userMintLimit","type":"uint256"},{"internalType":"uint256","name":"active","type":"uint256"}],"name":"setPmData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"reveal","type":"uint256"}],"name":"setReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"userMintLimit","type":"uint256"},{"internalType":"uint256","name":"mintLimit","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"uint256","name":"active","type":"uint256"}],"name":"setWlData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"tokensOf","outputs":[{"internalType":"uint256[]","name":"nfts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"withdrawERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"wlData","outputs":[{"internalType":"uint256","name":"userMints","type":"uint256"},{"internalType":"uint256","name":"mints","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"userMintLimit","type":"uint256"},{"internalType":"uint256","name":"mintLimit","type":"uint256"},{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"bool","name":"active","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"wlMint","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]