#include <v_lib.h>

/*
 * Example of using spline interpolator.
 */

V_LOCAL vector_p
vecCreateFromStack(bstack_t *in)
{
	vector_p out;
	out=vecAlloc(stackCount(in));
	memCopy(out->elements,stackGetStorage(in),out->size * sizeof(vec_t));
	stackClear(in);
	return out;
}
	
int main(int argc,char *argv[])
{
	vhandle_t out;
	vhandle_t in;
	vector_p ax, ay;
	vec_t x, dx, y;
	bstack_t in_x, in_y;
	u32_t out_size;
	vhandle_t interp;
	
	logStartConsoleLog();
	logUpperLevel(LOG_TRACE);
	
	if(argc != 4)
	{
		conPrintf(
			"Spline-based data resampler. Version 1.0.\n"
			"Copyright (C) 2002 Vladimir A. Smirnov.\n"
			"This program is free software; you can redistribute it and / or modify it\n"
			"under the terms of the GNU GPL.\n\n"
			"Usage: %s <text input> <text output> <output size>\n\n"
			"First argument must be the name of file with pairs of floats;\n"
			"output stored in file <text output> in tab - separated format.",
			argv[0]);
		return -1;
	}
	out_size = atoi(argv[3]);
	if(out_size < 2)
	{
		conlPrintf(LOG_ERROR,
			"%s: exected '2' or more as third argument, got '%s'.\n",
			argv[0],argv[3]);
		return -1;
	}
	/*
	 * Read in input data
	 */
	stackInit(&in_x,sizeof(vec_t));
	stackInit(&in_y,sizeof(vec_t));
	in = lexParseFile(argv[1],"\n ;'");
	if(in == NULL)
	{
		conlPrintf(LOG_ERROR,
			"Unable to open '%s'\n",argv[1]);
		return -1;
	}
	while(lexNext(in) != NULL)
	{
		x = (vec_t)atof(lexLast(in));
		if(lexNext(in) == NULL)
			break;
		y = (vec_t)atof(lexLast(in));
		stackPush(&in_x,&x);
		stackPush(&in_y,&y);
	}
	lexDestroy(in);
	if(stackCount(&in_x) < 2)
	{
		conlPrintf(LOG_ERROR,
			"%s: input file must contain at least two pairs of floats.\n",
			argv[0]);
		stackClear(&in_x);
		stackClear(&in_y);
		return -1;
	}
	/* Now, convert temporary storages to vectors */
	ax = vecCreateFromStack(&in_x);
	ay = vecCreateFromStack(&in_y);
	/* Vectors, in turn, should be coverted to interpolator */
	interp = cspCreate(ax, ay);
	cspSetBoundaryCondition(interp,3,0,0);
	x = ax->elements[0];
	dx = (ax->elements[ax->size - 1] - x) / (vec_t)(out_size - 1);
	memFree(ax);
	memFree(ay);
	
	if(interp == NULL)
	{
		conlPrintf(LOG_ERROR,
			"%s: internal error: coudn't create spline.\n",
			argv[0]);
		return -1;
	}
	/* It's time to do main work */
	out = fileOpenWrite(argv[2]);
	if(out == NULL)
	{
		conlPrintf(LOG_ERROR,
			"%s: coudn't create '%s'.\n",argv[0],argv[2]);
		cspDestroy(interp);
		return -1;
	}
	while(out_size--)
	{
		y = cspInterpolate(interp,x);
		filePrintf(out,"%g\t%g\n", x, y);
		x += dx;
	}
	fileClose(out);
	cspDestroy(interp);
	return 0;
}
