#ifndef _TEX_PARSER_H
#define _TEX_PARSER_H

#include <sys/types.h>

#include "zerror.h"

#define TEX_PARSER_DOMAIN 0

/**
 * enum tex_parser_error - the LaTeX parser error codes
 *
 * @TEX_PARSER_NOERROR:                 Default state indicates no error.
 * @TEX_PARSER_ERROR_UNKNOWN:           Uncontrolled error happen
 * @TEX_PARSER_ERROR_STACK:             Stack overflow
 * @TEX_PARSER_ERROR_PLACE_UNKNOWN:     Unknown place (internal error)
 * @TEX_PARSER_ERROR_UNEXPECTED_SYMBOL: Unexpected symbol for current place
 *
 * Defines parser error codes, @TEX_PARSER_NOERROR = %0 is equivalent to no errors.
 */
enum tex_parser_error {
	TEX_PARSER_NOERROR = 0,
	TEX_PARSER_ERROR_UNKNOWN,
	TEX_PARSER_ERROR_STACK,
	TEX_PARSER_ERROR_PLACE_UNKNOWN,
	TEX_PARSER_ERROR_UNEXPECTED_SYMBOL,
};

/**
 * struct tex_table_row_s - LaTeX table row
 *
 * @over_line:                          Text over row (\hline for ex.)
 * @cells:                              Row cells
 * @under_line:                         Text under row (\cline{2-4} for ex.)
 *
 * @over_line, @cells, @under_line uses zalloc*() functions which stores
 * array dimensions.
 */
struct tex_table_row_s {
	char *over_line;  // \hline, \cline{4-5} etc.
	char **cells;     // cells devided by &
	char *under_line; // \hline, \cline{4-5} etc.
};

/**
 * struct tex_table_s - LaTeX table
 *
 * @document_offset:                    Table offset (in symbols) in the LaTeX document
 * @document_size:                      Table size (in symbols) in the LaTeX document
 * @id:                                 Id in report generator context (Request.Drossel1.Table1 for ex.)
 * @col_props:                          Column properties devided by '>' symbol
 * @head_table:                         Top rows devided by & and automaticaly added on page break
 * @foot_table:                         Bottom rows devided by & and automaticaly added on page break
 * @main_table:                         Central rows which can be devided horizontally and vertically
 *
 * @col_props, @head_table, @foot_table, @main_table uses zalloc*() functions to
 * determine array dimensions.
 */
struct tex_table_s {
	size_t document_offset;
	size_t document_size;
	char *id;
	char **col_props;
	struct tex_table_row_s *head_table;
	struct tex_table_row_s *foot_table;
	struct tex_table_row_s *main_table;
};

/**
 * struct tex_graphics - LaTeX graphics
 *
 * @prestr:                             Preceding string
 * @path:                               Path to image file
 * @poststr:                            Descendant string
 *
 * Need some description here...
 */
struct tex_graphics {
	char *prestr;
	char *path;
	char *poststr;
};

/**
 * enum tex_element_type - Type of LaTeX element
 *
 * @TEX_ELEM_TEXT:                       Text containing non-arable code
 * @TEX_ELEM_TABLE:                      LaTeX table or longtable
 * @TEX_ELEM_GRAPHICS:                   LaTeX graphics (images, plots)
 *
 * Need some description here...
 */
enum tex_elem_type {
	TEX_ELEM_TEXT,
	TEX_ELEM_TABLE,
	TEX_ELEM_GRAPHICS
};

/**
 * struct tex_elem_s - Element of LaTeX code
 *
 * @type:                               LaTeX element type
 * @data:                               Element data structure
 *
 * Need some description here...
 */
struct tex_elem_s {
	enum tex_elem_type type;

	union {
		char *text;
		struct tex_table_s *table;
		struct tex_graphics_s *graphics;
	} data;
};

/**
 * struct tex_struct_s - LaTeX code structure
 *
 * @elems:                              List of LaTeX elements
 *
 * Need some description here...
 */
struct tex_struct_s {
	struct tex_elem_s *elems;
};

/**
 * tex_parse() - Parse the LaTeX code
 *
 * @source:                             LaTeX code string
 * @len:                                Length of LaTeX string
 * @tex_struct:                         A return location for a #tex_struct_s
 * @error:                              A return location for a #zerror_s
 *
 * Parses LaTeX text string @source of length len to *@tex_struct.
 * If some error occurs, parser returns immediatly with error info in *@error.
 * @tex_struct or @error can't be %NULL; *@tex_struct *@error must be %NULL.
 */
void tex_parse(const char *source, size_t len, struct tex_struct_s **tex_struct, struct zerror_s **error);

#endif