/*
 *  acm : an aerial combat simulator for X
 *  Copyright (C) 1991,1992  Riley Rainey
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 dated June, 1991.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program;  if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave., Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include "../util/memory.h"
#include "../util/error.h"

#define interpolate_IMPORT
#include "interpolate.h"

static void interpolate_destruct(void *p)
{
	interpolate_Table *oldp = p;
	if ( oldp != NULL ) {
		memory_dispose(oldp->entry);
	}
}


interpolate_Table * interpolate_new(int size)
{
	interpolate_Table *t = memory_allocate(sizeof(interpolate_Table), interpolate_destruct);
	t->entry = memory_allocate(size * sizeof(interpolate_Entry), NULL);
	return t;
}


double interpolate_value(interpolate_Table * table, double x)
{
	int i, count = table->count;

	if ( ! (x >= table->minX && x <= table->entry[count - 1].x) ) {
		error_internal("interpolate(..., %g): value out of the range [%g,%g]\n",
			x, table->minX, table->entry[count - 1].x);
	}

	for (i = 0; i < count; ++i) {
		if (x <= table->entry[i].x) {
			return (table->entry[i].m * x + table->entry[i].b);
		}
	}

	/* should never reach this point */
	error_internal("i=%d", i);
}


interpolate_Table * interpolate_clone (interpolate_Table *oldp)
{
	interpolate_Table * newp;
	int i;

	if ( oldp == NULL )
		return NULL;

	newp = memory_allocate(sizeof(interpolate_Table), interpolate_destruct);
	*newp = *oldp;
	newp->entry = memory_allocate(sizeof(interpolate_Entry) * (oldp->count), NULL);
	for (i=0; i<newp->count; ++i) {
		newp->entry[i] = oldp->entry[i];
	}

	return newp;
}
