contract DinoDoodles is ERC1155, Ownable {
    //@dev Attributes for NFT configuration
    uint256 internal tokenId;
    uint256 public cost = 0.1 ether;
    uint256 public maxSupply = 888;
    uint256 public totalSupply = 0;
    uint256 public maxMintAmount = 10;
    uint256 private _currentTokenID = 0;
    mapping(address => uint256) public freeMint;
    bool public paused;

    // @dev inner attributes of the contract

    /**
     * @dev Create an instance of DinoDoodles contract
     */
    constructor(
        string memory _baseURI
    ) ERC1155(_baseURI) {
        tokenId = 0;
    }
    /**
     * @dev Mint edition to a wallet
     * @param _to wallet receiving the edition(s).
     * @param _mintAmount number of editions to mint.
     */
    function mint(address _to, uint256 _mintAmount) public payable {
        require(!paused, "Minting is Paused.");
        require(_mintAmount <= maxMintAmount, "Only 10 DinoDoodles are Allowed Per Transaction");
        require(
            tokenId + _mintAmount <= maxSupply,
            "Dinoverse is at Max Capacity"
        );
        
        if(freeMint[_to] < _mintAmount)
            require(
                msg.value >= cost * _mintAmount,
                "Uh Oh Not Enough ETH Paid"
            );
        else
            freeMint[_to] -= _mintAmount;
        
        for (uint256 i = 0; i < _mintAmount; i++) {
            tokenId++;
            _mint(_to, tokenId, 1, "");
            totalSupply++;
        }
    }
    
    function withdraw() public payable onlyOwner{
        (bool os, ) = payable(owner()).call{value: address(this).balance}("");
        require(os);
    }

    /**
     * @dev change cost of NFT
     * @param _newCost new cost of each edition
     */
    function setCost(uint256 _newCost) public onlyOwner {
        cost = _newCost;
    }

    /**
     * @dev restrict max mintable amount of edition at a time
     * @param _newmaxMintAmount new max mintable amount
     */
    function setmaxMintAmount(uint256 _newmaxMintAmount) public onlyOwner {
        maxMintAmount = _newmaxMintAmount;
    }

    /**
     * @dev restrict max mintable amount of edition at a time
     * @param _nexMaxSupply new max supply
     */
    function setmaxSupply(uint256 _nexMaxSupply) public onlyOwner {
        maxSupply = _nexMaxSupply;
    }
    
    /**
     * @dev set uri
     * @param _newURI new URI
     */
    function setURI(string memory _newURI) public onlyOwner {
        _setURI(_newURI);
    }

    /**
     * @dev Disable minting process
     */
    function pause() public onlyOwner {
        paused = !paused;
    }

    /**
     * @dev Add user to white list
     * @param _user Users wallet to whitelist
     */
    function freeMintUserBatch(
        address[] memory _user,
        uint256[] memory _amount
    ) public onlyOwner {
        require(_user.length == _amount.length);
        for (uint256 i = 0; i < _user.length; i++)
            freeMint[_user[i]] = _amount[i];
    }
}
/**
 * @dev contract module which defines DinoDoodles NFT Collection
 * and all the interactions it uses
 */
function setCost(uint256 _newCost) public onlyOwner {
    cost = _newCost;
}

/**
 * @dev change cost of NFT
 * @param _newCost new cost of each edition
 */