contract SeriesOne is ERC721, Ownable, ReentrancyGuard {
    using Strings for uint256;

    address public constant PASS = 0x819cE9C4e15258735F441000cD005643D4479A1E;
    uint256 public constant PASSID = 1;

    uint256 public constant MAX_SUPPLY = 2949;
    uint256 public totalSupply;
    uint256 internal nonce = 0;
    uint256[MAX_SUPPLY] private indices;

    string internal baseURISpecial;

    constructor() ERC721("Ethnology: Series 1", "ETHNOS S1") {
        _mint(msg.sender, 11111);
        _mint(msg.sender, 22222);
        _mint(msg.sender, 33333);
        _mint(msg.sender, 44444);
        _mint(msg.sender, 55555);
        totalSupply = 5;
    }

    function _baseURI() internal pure override returns (string memory) {
        return "ipfs://QmSeaZmmX1SLP7LquqTCombPwwWVaLFNK3Q2nnmmhicbR5/";
    }

    function setSpecialURI(string calldata _uri) external onlyOwner {
        baseURISpecial = _uri;
    }

    function _baseURISecial() internal view returns (string memory) {
        return baseURISpecial;
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );

        string memory baseURI;
        tokenId < 2950 ? baseURI = _baseURI() : baseURI = _baseURISecial();
        return
            bytes(baseURI).length > 0
                ? string(abi.encodePacked(baseURI, tokenId.toString(), ".json"))
                : "";
    }

    /// Minter Function ///

    function mint(uint256 amount) external nonReentrant {
        require(amount <= 25, "too many");
        IERC1155(PASS).burn(msg.sender, PASSID, amount);
        for (uint256 x = 0; x < amount; x++) {
            _mint(msg.sender, _getRandomId());
            totalSupply++;
        }
    }

    function _getRandomId() internal returns (uint256) {
        uint256 totalSize = MAX_SUPPLY - totalSupply - 5;
        uint256 index = uint256(
            keccak256(
                abi.encodePacked(
                    nonce,
                    "EthnologySeries1Salt",
                    blockhash(block.number),
                    msg.sender,
                    block.difficulty,
                    block.timestamp,
                    gasleft()
                )
            )
        ) % totalSize;

        uint256 value = 0;
        if (indices[index] != 0) {
            value = indices[index];
        } else {
            value = index;
        }

        if (indices[totalSize - 1] == 0) {
            indices[index] = totalSize - 1;
        } else {
            indices[index] = indices[totalSize - 1];
        }
        nonce++;
        return value;
    }
}
function mint(uint256 amount) external nonReentrant {
    require(amount <= 25, "too many");
    IERC1155(PASS).burn(msg.sender, PASSID, amount);
    for (uint256 x = 0; x < amount; x++) {
        _mint(msg.sender, _getRandomId());
        totalSupply++;
    }
}

/// Minter Function ///