#ifndef GEMINI_CLIENT_H
#define GEMINI_CLIENT_H
#include <stdbool.h>
#include <stddef.h>

enum gemini_tok {
	GEMINI_TEXT,
	GEMINI_LINK,
	GEMINI_PREFORMATTED_BEGIN,
	GEMINI_PREFORMATTED_END,
	GEMINI_PREFORMATTED_TEXT,
	GEMINI_HEADING,
	GEMINI_LIST_ITEM,
	GEMINI_QUOTE,
};

struct gemini_token {
	enum gemini_tok token;

	// The token field determines which of the union members is valid.
	union {
		char *text;

		struct {
			char *text;
			char *url; // May be NULL
		} link;

		char *preformatted;

		struct {
			char *title;
			int level; // 1, 2, or 3
		} heading;

		char *list_item;
		char *quote_text;
	};
};

struct gemini_parser {
	int (*read)(void *state, void *buf, size_t nbyte);
	void *state;
	char *buf;
	size_t bufsz;
	size_t bufln;
	bool preformatted;
};

// Initializes a text/gemini parser. The provided "read" function will be called
// with the provided "state" value in order to obtain more gemtext data. The
// read function should behave like read(3).
void gemini_parser_init(struct gemini_parser *p,
		int (*read)(void *state, void *buf, size_t nbyte),
		void *state);

// Finishes this text/gemini parser and frees up its resources.
void gemini_parser_finish(struct gemini_parser *p);

// Reads the next token from a text/gemini file.
// 
// Returns 0 on success, 1 on EOF, and -1 on failure.
//
// Caller must call gemini_token_finish before exiting or re-using the token
// parameter.
int gemini_parser_next(struct gemini_parser *p, struct gemini_token *token);

// Must be called after gemini_next to free up resources for the next token.
void gemini_token_finish(struct gemini_token *token);

#endif
