#ifndef MISC_H_PARSER_DEF
#define MISC_H_PARSER_DEF

#include <stdio.h>
#include "util.h"
#include "template.h"
#include "dico.h"
#include "parser.h"

/*
 Parser sctructure
*/
typedef struct Twig_TOKEN
{
	int type;	// Token type (see parser.h file)
	char *buf;	// buffer of the token value
	u32 line;
	u32 collum;
} Twig_TOKEN;

typedef struct Twig_EXPR
{
	int number;
	const char *key; // key in dico
	InterfaceExprNode *node;
} Twig_EXPR;

typedef struct Twig_INSTR
{
	Twig_EXPR *expr;
	InterfaceExprNode *node;
} Twig_INSTR;

typedef struct Twig_PRIMARY
{
	union
	{
		//Twig_ID *id;
		int number;
		char *string;
	} data;
	const char *key; // key in dico
	Twig_Type type;
} Twig_PRIMARY;

typedef struct Twig_ARGS // simple linked list
{	
	Twig_PRIMARY *node;
	struct Twig_ARGS *next;
} Twig_ARGS;

typedef struct Twig_FUNCTION
{	
	const char *name; // name of the function example: nl2br
	Twig_ARGS *args;
} Twig_FUNCTION;

typedef struct Twig_Bracket
{
	char *carac;
	u32 line;
	u32 collum;
	struct Twig_Bracket *next;
} Twig_Bracket;

typedef struct Twig_StackBracket
{
	size_t size;
	Twig_Bracket *next;
} Twig_StackBracket;


/*
 Logic, Mathematic and Comparaison operator
*/
typedef struct NodeExpr
{
	Twig_NodeCallback *interpret;
	int result;
	Twig_EXPR *leftOp, *rightOp;
} NodeExpr;

typedef struct NodeInstr
{
	Twig_NodeCallback *interpret;
	Twig_EXPR *result;
} NodeInstr;

/*
 Other node
*/
typedef struct NodeFILTER
{
	Twig_NodeCallback *interpret;
	Twig_PRIMARY *data;
	Twig_FUNCTION *func;
} NodeFILTER;

typedef struct NodeID
{
	Twig_NodeCallback *interpret;
	int number;
} NodeID;

typedef struct NodeCONCANATE
{
	Twig_NodeCallback *interpret;
} NodeCONCANATE;

typedef struct NodeOPEN_BRACKET
{
	Twig_NodeCallback *interpret;
} NodeOPEN_BRACKET;

typedef struct NodeCLOSE_BRACKET
{
	Twig_NodeCallback *interpret;
} NodeCLOSE_BRACKET;

typedef struct NodeCOMMA
{
	Twig_NodeCallback *interpret;
} NodeCOMMA;

typedef struct NodeIN
{
	Twig_NodeCallback *interpret;
} NodeIN;

typedef struct NodeSTRING
{
	Twig_NodeCallback *interpret;
} NodeSTRING;

typedef struct NodeBLOCK_START
{
	Twig_NodeCallback *interpret;
} NodeBLOCK_START;

typedef struct NodeBLOCK_END
{
	Twig_NodeCallback *interpret;
} NodeBLOCK_END;

typedef struct NodeVAR_START
{
	Twig_NodeCallback *interpret;
} NodeVAR_START;

typedef struct NodeVAR_END
{
	Twig_NodeCallback *interpret;
} NodeVAR_END;

typedef struct NodeCOMMENT_START
{
	Twig_NodeCallback *interpret;
} NodeCOMMENT_START;

typedef struct NodeCOMMENT_END
{
	Twig_NodeCallback *interpret;
} NodeCOMMENT_END;

typedef struct NodeEOF
{
	Twig_NodeCallback *interpret;
} NodeEOF;

typedef struct NodeTAG_BLOCK
{
	Twig_NodeCallback *interpret;
} NodeTAG_BLOCK;

typedef struct NodeTAG_SET
{
	Twig_NodeCallback *interpret;
} NodeTAG_SET;

typedef struct NodeTAG_RAW
{
	Twig_NodeCallback *interpret;
} NodeTAG_RAW;

typedef struct NodeTAG_FOR
{
	Twig_NodeCallback *interpret;
} NodeTAG_FOR;

typedef struct NodeTAG_IF
{
	Twig_NodeCallback *interpret;
} NodeTAG_IF;

typedef struct NodeTAG_ELSE
{
	Twig_NodeCallback *interpret;
} NodeTAG_ELSE;

typedef struct NodeTAG_ELSEIF
{
	Twig_NodeCallback *interpret;
} NodeTAG_ELSEIF;

typedef struct NodeTAG_EXTENDS
{
	Twig_NodeCallback *interpret;
} NodeTAG_EXTENDS;

typedef struct NodeTAG_INCLUDE
{
	Twig_NodeCallback *interpret;
} NodeTAG_INCLUDE;

typedef struct NodeENDTAG
{
	Twig_NodeCallback *interpret;
} NodeENDTAG;

typedef struct Twig_Parser
{
	Twig_Dictionnary *dico;					// Symbole table provide by the user
	Twig_Template *temp;					// result of the parser
	Twig_Bracket *var, *block, *comment;	// Stack where bracket are pushed and poped
//	Twig_ParserState state;
	bool isInBlock, isInVar;
	char *errMsg;
	u16 nbError;
	u32 visibility;
} Twig_Parser;

void *ParseAlloc(void *(*mallocProc)(size_t));
void ParseFree(void *p, void (*freeProc)(void*));
int ParseStackPeak(void *p);
void ParseTrace(FILE *TraceFILE, char *zTracePrompt);
void Parse(void *yyp, int yymajor,  Twig_TOKEN  yyminor,  Twig_Parser *parser );


Twig_Parser* initParser();
void destroyParser(Twig_Parser *parser);

inline Twig_EXPR* initParserExpr(NodeExpr *node);

// Comparaison operator
NodeExpr* initEQ(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initNE(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initLT(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initGT(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initGE(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initLE(Twig_EXPR *leftOp, Twig_EXPR *rightOp);

// Binary operator
NodeExpr* initB_AND(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initB_XOR(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initB_OR(Twig_EXPR *leftOp, Twig_EXPR *rightOp);

// Logic operator
NodeExpr* initAND(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initOR(Twig_EXPR *leftOp, Twig_EXPR *rightOp);

// Mathematic operator
NodeExpr* initPLUS(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initMINUS(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initMULTIPLIE(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initDIVIDE(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initMODULO(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
NodeExpr* initPOWER(Twig_EXPR *leftOp, Twig_EXPR *rightOp);
void destroy(NodeExpr *node);

NodeFILTER* initFILTER(Twig_PRIMARY *data, Twig_FUNCTION *func);
void destroyFILTER(NodeFILTER *node);

#endif