contract Pixelfers is Ownable, ERC721A, ReentrancyGuard {

  uint256 public collection_Size = 3500;
  uint256 public collection_Size_Free = 700;
  uint256 public amountForDevs = 5;
  uint256 public price = 0.0077 ether;
  uint256 public freemintAmount = 20;
  uint256 public max_Batch_Size = 20;
  uint256 public mintAmount = 20;

  constructor(
  ) ERC721A("Pixelfer", "Pixelfer", max_Batch_Size, collection_Size, collection_Size_Free) {
  }

  modifier callerIsUser() {
    require(tx.origin == msg.sender, "The caller is another contract");
    _;
  }

  function Mint(uint256 quantity)
    external
    payable
    callerIsUser
  {
      require(quantity <= mintAmount, "Too many minted at once");
      require(msg.value >= price * quantity, "Need to send more ETH.");
    require(totalSupply() + quantity <= collection_Size, "reached max supply");
    _safeMint(msg.sender, quantity);
    
  }

  function MintFree(uint256 quantity)
    external
    payable
    callerIsUser
  {
    require(quantity <= freemintAmount, "Too many minted at once");
    require(totalSupply() + quantity <= collection_Size_Free, "reached max supply");
    _safeMint(msg.sender, quantity);
  }

  // For marketing etc.
  function devMint(uint256 quantity) external onlyOwner {
    
     require(totalSupply() + quantity <= amountForDevs, "reached max supply");
    _safeMint(msg.sender, quantity);
  }
    

  // // metadata URI
  string private _baseTokenURI;

  function _baseURI() internal view virtual override returns (string memory) {
    return _baseTokenURI;
  }

  function setBaseURI(string calldata baseURI) external onlyOwner {
    _baseTokenURI = baseURI;
  }

  function withdrawMoney() external onlyOwner nonReentrant {
    (bool success, ) = msg.sender.call{value: address(this).balance}("");
    require(success, "Transfer failed.");
  }

  function setOwnersExplicit(uint256 quantity) external onlyOwner nonReentrant {
    _setOwnersExplicit(quantity);
  }

  function numberMinted(address owner) public view returns (uint256) {
    return _numberMinted(owner);
  }

  function getOwnershipData(uint256 tokenId)
    external
    view
    returns (TokenOwnership memory)
  {
    return ownershipOf(tokenId);
  }

function setprice(uint256 _newprice) public onlyOwner {
	    price = _newprice;
	}

  function setfreemints(uint256 _newfreemints) public onlyOwner {
	    collection_Size_Free = _newfreemints;
	}

    function setcollectionSize(uint256 _newcollectionSize) public onlyOwner {
	    collection_Size = _newcollectionSize;
	}

    function setamountForDevs(uint256 _newamountForDevs) public onlyOwner {
	    amountForDevs = _newamountForDevs;
	}

    function setfreemintAmount(uint256 _newfreemintAmount) public onlyOwner {
	    freemintAmount = _newfreemintAmount;
	}

    function setmintAmount(uint256 _newmintAmount) public onlyOwner {
	    mintAmount = _newmintAmount;
	}


}
function devMint(uint256 quantity) external onlyOwner {
    
   require(totalSupply() + quantity <= amountForDevs, "reached max supply");
  _safeMint(msg.sender, quantity);
}

// For marketing etc.