#pragma once

#include "error.hpp"

enum TokenType
{
	// Basic syntax
	TOK_ASSIGN,		// =
	TOK_BLOCK_BEGIN, // {
	TOK_BLOCK_END,	// }
	TOK_LIST_BEGIN,	// [
	TOK_LIST_END,	// ]
	TOK_NUMBER,
	TOK_NAME,		// Unquoted, no-spaces string
	TOK_STRING,		// Quoted string
	TOK_REFERENCE,	// String that began with '@'

	// RovScript tokens
	TOK_REGISTER,	// String that began with '$'
	TOK_PARAMS_BEGIN,		 // (
	TOK_PARAMS_SEPARATOR,	 // ,
	TOK_PARAMS_END,	 // )
	TOK_PLUS, // +
	TOK_MINUS, // -
	TOK_PLUSEQU, // +=
	TOK_MINUSEQU, // -=
	TOK_COMPARE, // ==
	TOK_LESSTHAN, // <
	TOK_GREATERTHAN, // >
	TOK_LESSEQU, // <=
	TOK_GREATEREQU, // >=

	_TOK_ANY
};

struct token
{
	TokenType type;
	std::string contents;
	FilePos filepos;
};

class TokenReader
{
public:
	TokenReader(const char *filepath);
	//TokenReader(const char *src, size_t len, filepos pos);
	~TokenReader();

	token ReadToken(TokenType type = _TOK_ANY);
	token PeekToken(); // TODO: Should be const

	int ReadChar();
	int PeekChar(size_t ahead = 0) const;

	// Advances the read head until one of the characters in 'chars' is encountered,
	// or the end of the file is reached.
	void SkipUntil(const char *chars);

	// Like SkipUntil, but returns the number of chars
	// until a char is found instead of reading ahead.
	size_t FindNext(const char *chars) const;

	// Returns true if there are no more tokens in the file
	bool EndOfFile() const;
	FilePos GetFilePos() const { return { filename, linenum }; };

private:
	char *read, *end;
	char *buffer;
	const char *filename;
	int linenum;
};