#include <stdlib.h>
#include <stdio.h>

#include "../src/libio/io.h"


typedef struct part_struct part_struct_t;
typedef part_struct_t *part_t;

struct part_struct {
	float x, y, z;
	float vx, vy, vz;
	uint32_t id;
};

int
main(int argc, char **argv)
{
	io_file_strg_struct_t strg;
	io_file_type_t ftype;
	io_logging_t log;
	io_file_t file;
	uint64_t num_part, pskip, pread, i;
	part_t part;

	if (argc != 3) {
		printf("Usage: %s <fname> <ftype>\n"
		       "  <fname>:  Name of the snapshot\n"
		       "  <ftype>:  Type of the snapshot\n\n",
		       argv[0]);

		exit(EXIT_FAILURE);
	}

	log = io_logging_start(NULL, 4, 0);

	ftype = (io_file_type_t)atoi(argv[2]);
	file = io_file_open(log, argv[1], ftype,
	                    IO_FILE_UNKOWN_SWAPPING,
	                    IO_FILE_READ, 1);
	if (file == NULL) {
		fprintf(stderr, "FAILED.\n\n");
		exit(EXIT_FAILURE);
	}
	io_file_init(log, file);

	pskip = UINT64_C(0);
	pread = UINT64_MAX;

	fflush(NULL);

	num_part = io_file_get_numpart(log, file, &pskip, &pread);

	part = malloc(sizeof(part_struct_t)*num_part);
	if (part == NULL) {
		io_file_close(log, &file);
		fprintf(stderr, "Could not allocate storage for particles.\n\n");
		exit(EXIT_FAILURE);
	}

	strg.posx.val = (void *)&(part->x);
	strg.posx.stride = (char *)(&((part+1)->x)) - (char *)(&((part)->x));
	strg.posy.val = (void *)&(part->y);
	strg.posy.stride = (char *)(&((part+1)->y)) - (char *)(&((part)->y));
	strg.posz.val = (void *)&(part->z);
	strg.posz.stride = (char *)(&((part+1)->z)) - (char *)(&((part)->z));
	strg.momx.val = (void *)&(part->vx);
	strg.momx.stride = (char *)(&((part+1)->vx)) - (char *)(&((part)->vx));
	strg.momy.val = (void *)&(part->vy);
	strg.momy.stride = (char *)(&((part+1)->vy)) - (char *)(&((part)->vy));
	strg.momz.val = (void *)&(part->vz);
	strg.momz.stride = (char *)(&((part+1)->vz)) - (char *)(&((part)->vz));
	strg.weight.val = NULL;
	strg.weight.stride = (ptrdiff_t)0;
	strg.id.val = (void *)&(part->id);
	strg.id.stride = (char *)(&((part+1)->id)) - (char *)(&((part)->id));
	strg.u.val = NULL;
	strg.u.stride = (ptrdiff_t)0;
	strg.bytes_float = sizeof(part->x);
	strg.bytes_int = sizeof(part->id);

	io_file_readpart(log, file, pskip, pread, strg);

	io_file_close(log, &file);
	io_logging_stop(&log);

	for (i=0; i<num_part; i++) {
		printf("%g\t%g\t%g\t%g\t%g\t%g\t%"PRIu32"\n",
		       (part+i)->x, (part+i)->y, (part+i)->z,
		       (part+i)->vx, (part+i)->vy, (part+i)->vz,
		       (part+i)->id);
	}


	free(part);

	return EXIT_SUCCESS;
}
