#include <v_lib.h>
#include "rgcache.h"
#include "genparse.h"

/*
 * Filler particle: fiber.
 */
typedef struct fp_s
{
	vec3_t	p1, p2;
	vec_t	len, diameter;
	vec_t	volume;
}	fp_t, fp_p;

/*
 * Contact point
 */
typedef struct fc_s
{
	int fn1, fn2;	/* pointers to contacting fibers */
	vec_t dist;		/* minimal distance between fibers */
	vec3_t cp;		/* contact point */
}	fc_t, *fc_p;

/*
 * System to be modeled.
 */
typedef struct tsys_s
{
	vec3_t		bbox[2];
	vec_t		volume;
	vec_t		volumetric_content;
	bstack_t	fs; /* of fp_t */
	bstack_t	cs; /* of fc_t */
}	tsys_t, *tsys_p;

typedef struct tseq_s
{
	/*
	 * Number of iterators among generators.
	 * 0 - one experiment;
	 * 1 - non-nested loop;
	 * 2 - doubly nested loop;
	 * 3 - triply-nested loop.
	 */
	int nesting_level;
	/*
	 * #0 - volumetric content;
	 * #1 - fiber length;
	 * #2 - fiber diameter.
	 */
	float_generator_p generators[3];
	/*
	 * Actual number of elements is equal to 'nesting_level'.
	 */
	u32_t iterators[3];
	/*
	 * There are 2 stages of modeling process.
	 * 1. Generation of the test systems. Here non-reentrant code
	 * (generators are shared between all tasks) is used.
	 *
	 * 2. Computing number of contacts. Computation-intensive stage,
	 * subject to later parallelization.
	 *
	 * Thus, total number of test systems depends on 'nesting_level' and
	 * parameters of iterators (fg->u.ilinear.steps + 1).
	 * The tseqSysAmount() is for initial determination of the former.
	 * Upon completion of the stage 1, it is in stackCount(&seq->ts).
	 */
	bstack_t	ts;
}	tseq_t, *tseq_p;

tseq_p	V_GLOBAL
seqParse(vhandle_t lex,bstack_p generators)
{
}

vboolean	V_GLOBAL
seqCreateSystems(tseq_p seq)
{
}

/*
 * TODO for near holiday: seqParallelScheduler().
 */
vboolean	V_GLOBAL
seqSequentialScheduler(tseq_p *seqs, u32_t num_seqs)
{
}

/*
 * Saving the results, visualization, etc.
 */
vboolean	V_GLOBAL
seqPostprocess()
{
}

vhandle_t in;

vp_stack_t floatgens = TYPED_STACK_EMPTY_INITIALIZER;

static void
clean_floatgens()
{
	float_generator_p g;
	while(vpsPop(&floatgens,(void_p*)&g))
		g->destroy(g);
	vpsClear(&floatgens);
} 

int main(int argc, char *argv[])
{
	CALLER_NAME(main);
	logStartConsoleLog();
	logUpperLevel(LOG_TRACE);
	in = lexParseFile("test.fcic", "{}()[];");
	lexSetInteger(in,LEX_COMMENT_CHAR, '#');
	lexEnable(in, LEX_ONE_CHAR_COMMENTS);
	while(lexNext(in))
	{
		if(lexLastWas(in, "generators"))
		{
			parseGenerators(in, &floatgens);
		}
	}
    printf("parsed %u generators\n", vpsCount(&floatgens));
    if(vpsCount(&floatgens))
    {
    	int i;
    	vec_t f;
    	float_generator_p g;
    	g = (float_generator_p)vpsGet(&floatgens,0);
    	for(i=0;i<10;i++)
    	{
    		if(!g->next(g,&f))
    			break;
    		printf("%g\n",f);
    	}
    }
    clean_floatgens();
	lexDestroy(in);
	memPrintStats();
	return 0;
}
