
#include <stdlib.h>

#include <grass/gis.h>
#include "globals.h"
#include "expression.h"
#include "func_proto.h"

/****************************************************************
graph(x, x1,y1, x2,y2, ... xn,yn)  returns y value based on graph
described by the x,y pairs.
****************************************************************/

int 
c_graph(int argc, int *argt)
{
	int i;

	if (argc < 3)
		return E_ARG_LO;

	if (argc % 2 == 0)
		return E_ARG_NUM;

	for (i = 0; i <= argc; i++)
		argt[i] = DCELL_TYPE;

	return 0;
}

int 
f_graph(int argc, const int *argt, void **args)
{
	DCELL **argz = (DCELL **) args;
	DCELL *res = argz[0];
	int n = (argc - 1) / 2;
	int i, j;

	if (argc < 3)
		return E_ARG_LO;

	if (argc % 2 == 0)
		return E_ARG_NUM;

	if (argt[0] != DCELL_TYPE)
		return E_RES_TYPE;

	for (i = 1; i <= argc; i++)
		if (argt[i] != DCELL_TYPE)
			return E_ARG_TYPE;

	for (i = 0; i < columns; i++)
	{
#define X(j) (argz[2 + 2 * (j) + 0][i])
#define Y(j) (argz[2 + 2 * (j) + 1][i])
#define x (argz[1][i])

		if (IS_NULL_D(&x))
			goto null;

		for (j = 0; j < n; j++)
			if (IS_NULL_D(&X(j)))
				goto null;

		for (j = 0; j < n-1; j++)
			if (X(j+1) <= X(j))
				goto null;

		if (x <= X(0))
		{
			if (IS_NULL_D(&Y(0)))
				goto null;
			res[i] = Y(0);
			continue;
		}

		if (x >= X(n-1))
		{
			if (IS_NULL_D(&Y(n-1)))
				goto null;
			res[i] = Y(n-1);
			continue;
		}

		for (j = 0; j < n-1; j++)
		{
			if (x > X(j+1))
				continue;

			if (IS_NULL_D(&Y(j)) || IS_NULL_D(&Y(j+1)))
				goto null;

			res[i] = Y(j) + (x - X(j)) * (Y(j+1) - Y(j)) / (X(j+1) - X(j));

			break;
		}

		continue;

	null:
		SET_NULL_D(&res[i]);
	}

	return 0;
}

