/******************************************************************************
*
*  test_delaunay_c        Originally by FHJ     Last Modified 12/04/2012 (FHJ)
*
*    A simple C program that tests the BerkeleyGW C bindings for Qhull.
*
*    This file is part of the BerkeleyGW package.
*
******************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "libtile_qhull.h"

void print_vect(int id, double *vec, int dims)
{
	int jdim_;

	if (id>=0) printf(" %4d ", id);
	for (jdim_=0; jdim_<dims; jdim_++)
		printf("%5.3f ", vec[jdim_]);
	printf("\n");
}

int main(int argc, char **argv)
{
	int n_nei, dim_, npts, nrep;
	int ip, idim_, div, rem;
	int *indices, *base;
	double *points, *point, *pt, *coefs;
	char show_coords = 1;

	//TODO: make this configurable!
	printf("Testing libtile_qhull - C bindings.\n");
	nrep = 1000;
	dim_ = 3;
	n_nei = 8;
	npts = pow(n_nei, dim_);
	
	printf("Dimensions: %1d\n", dim_);
	printf("Mesh size : %6d^%1d\n", n_nei, dim_);
	points = (double*) malloc(sizeof(double) * dim_ * npts);
	base = (int*) malloc(sizeof(int) * dim_);
	/* To work in arbitrary dimensions, we notice that we can assign each
	axis a number = (# neighbors)^(axis number) */
	base[dim_-1] = 1;
	for (idim_=dim_-2; idim_>=0; idim_--)
		base[idim_] = n_nei*base[idim_+1];
	point = points;
	for (ip=0; ip<npts; ip++) {
		rem = ip;
		for (idim_=0; idim_<dim_; idim_++) {
			div = rem / base[idim_];
			*(point++) = div / (double) n_nei;
			rem -= div * base[idim_];
		}
	}
	free(base);

	if (show_coords) {
		printf("\nInput coordinates:\n");
		for (ip=0; ip<npts; ip++) {
			point = points + ip*dim_;
			print_vect(ip+1, point, dim_);
		}
	}

	indices = (int*) malloc(sizeof(int) * (dim_+1));
	coefs = (double*) malloc(sizeof(double) * (dim_+1));
	pt = (double*) calloc(dim_, sizeof(double));
	pt[0] = 0.125;
	pt[1] = 0.75;
	printf("\nTest coordinate:\n");
	print_vect(0, pt, dim_);
	printf("\n");

	printf("Calling init_delaunay.\n");
	fflush(stdout);
	fflush(stderr);
	qhull_init_delaunay(points, &npts, &dim_, 0);
	fflush(stdout);
	fflush(stderr);

	printf("Calling find_delaunay_simplex %8d times.\n", nrep);
	for (ip=0; ip<nrep; ip++)
		qhull_find_delaunay_simplex(pt, indices, coefs);
	printf("Calling free_delaunay.\n");
	qhull_free_delaunay();

	printf("\nFound vertices:\n");
	for (ip=0; ip<dim_+1; ip++) {
		point = points + (indices[ip]-1)*dim_;
		print_vect(indices[ip], point, dim_);
	}
	printf("\nCoefficients: ");
	print_vect(-1, coefs, dim_+1);

	free(indices);
	free(coefs);
	free(pt);
	free(points);
	printf("\nAll Done!\n");
	return 0;
}
