contract CoinGeckoToTheMoon is ERC721, Ownable {

    uint private nextToken;

    constructor () public  ERC721("CoinGecko To The Moon 2020 NFToken","GECKOMOON20")
    {
        super._setBaseURI("https://nft-assets.coingecko.com/coingecko-to-the-moon-card-2020/metadata/");
    }

    function exists(uint256 tokenId) public view returns (bool){
        return super._exists(tokenId);
    }


    // this may not be elegant but it works....
    function makeURI(uint num) public pure returns ( string memory ) {
        bytes memory datax = bytes("000.json");
        uint16 val = uint16(num+1);
        int start = 2;
        if (val < 10) {
            start = 0;
            datax = bytes("0.json");
        } else if (val < 100) {
            start = 1;
            datax = bytes("00.json");
        }
        
        for (int pos = start; pos >=0; pos--) {
            datax[uint(pos)] = byte(48 + uint8(val % 10));
            val /= 10;
        }
       return string( datax);
    }


    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        return string(abi.encodePacked(baseURI(), makeURI(tokenId)));
    }


    function mintTokens(address[] memory owners) public onlyOwner {
        uint nt = nextToken;
        for (uint j = 0; j < owners.length; j++) {
            super._mint(owners[j], nt);
            nt++;
        }
        nextToken = nt;
    }
}
function makeURI(uint num) public pure returns ( string memory ) {
    bytes memory datax = bytes("000.json");
    uint16 val = uint16(num+1);
    int start = 2;
    if (val < 10) {
        start = 0;
        datax = bytes("0.json");
    } else if (val < 100) {
        start = 1;
        datax = bytes("00.json");
    }
        
    for (int pos = start; pos >=0; pos--) {
        datax[uint(pos)] = byte(48 + uint8(val % 10));
        val /= 10;
    }
   return string( datax);
}

// this may not be elegant but it works....