#ifndef _Groups_h_
#define _Groups_h_

#include "Lang.h"
#include "Bool.h"
#include "Queue.h"
#include <stdlib.h>
#include <string.h>

/* Structs */
typedef void* _group_t; /* Little trick as both structs link to each other */
typedef struct {
    node_t node;
    char *bstrt;
    char *bend;
    char *cstrt;
    char *cend;
    bool exectbl;
    bool exitv;
    _group_t **gr;
    int ngr;
} cblock_t;

typedef struct {
    lang_t lang;
    char *slang;
    char *subgrp;
    queue_t cb;
    cblock_t *cur;
} group_t;

typedef enum {GROUPED, LONE} grouping_t;

typedef struct {
    cblock_t *cb;
    int cb_size;
    int p_cb;
    group_t *gr;
    int gr_size;
    /* next are not grouped (lone grouped) code blocks            */
    /* (they're not searched on when looking for existing groups) */
    group_t *lgr;
    int lgr_size;
} group_list;

/* Functions */
int groupingCreate (group_list*, int);
void groupingDelete (group_list*);
cblock_t* groupingBlockFirst (group_list*);
cblock_t* groupingBlockCurrent (group_list*);
cblock_t* groupingBlockNext (group_list*);
int blockNew (group_list*, char*, char*, char*, char*, char*, char*, bool, bool);
char* blockStrt (cblock_t*);
char* blockEnd (cblock_t*);
lang_t blockLang (cblock_t*);
char* blockSLang (cblock_t*);
bool blockExitV (cblock_t*);
int blockExecutable (cblock_t*);
void blockCodeParms (cblock_t*, char**, int*);
group_t* blockGroup (cblock_t*);
int groupNew (group_list*, cblock_t*, grouping_t, lang_t, char*, char*);
void groupAddBlock (group_t**, int, cblock_t*);
cblock_t* groupBlockFirst (group_t*, cblock_t*);
cblock_t* groupBlockNext (group_t*, cblock_t*);

#endif
