/*
 * gnuplot.c - Gnuplot file input/output
 *
 * Written 2010 by Werner Almesberger
 * Copyright 2010 Werner Almesberger
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 */


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

#include "path.h"
#include "gnuplot.h"


struct path *gnuplot_read(const char *name, double r_tool_default)
{
	FILE *file;
	int lineno = 0;
	char buf[1024];
	double x, y, z, tmp;
	double r_tool = r_tool_default;
	int outside = 0, notch = 0;
	int n;
	struct path *paths = NULL, *path = NULL;
	struct path **lnk = &paths;

	file = name ? fopen(name, "r") : stdin;
	if (!file) {
		perror(name);
		exit(1);
	}

	while (fgets(buf, sizeof(buf), file)) {
		lineno++;
		if (sscanf(buf, "#%%r_tool=%lf\n", &tmp) == 1)
			r_tool = tmp;
		if (!strcmp(buf, "#%outside\n"))
			outside = 1;
		if (!strcmp(buf, "#%notch\n"))
			notch = 1;
		if (*buf == '#')
			continue;
		n = sscanf(buf, "%lf %lf %lf\n", &x, &y, &z);
		switch (n) {
		case -1:
			path = NULL;
			r_tool = r_tool_default;
			outside = notch = 0;
			continue;
		case 2:
			z = 0;
			/* fall through */
		case 3:
			break;
		default:
			fprintf(stderr, "invalid data at %s line %d\n",
			    name ? name : "(stdin)", lineno);
			exit(1);
		}

		if (!path) {
			path = path_new(r_tool);
			path->outside = outside;
			path->notch = notch;
			*lnk = path;
			lnk = &path->next;
		}
		path_add(path, x, y, z);
	}
	fclose(file);
	return paths;
}


static int gnuplot_do_write(FILE *file, const struct path *paths)
{
	const struct path *path;
	const struct point *p;

	for (path = paths; path; path = path->next) {
		if (path != paths)
			if (fprintf(file, "\n") < 0)
				return 0;
		if (path->r_tool &&
		    fprintf(file, "#%%r_tool=%f\n", path->r_tool) < 0)
			return 0;
		if (path->outside && fprintf(file, "#%%outside\n") < 0)
			return 0;
		if (path->notch && fprintf(file, "#%%notch\n") < 0)
			return 0;
		for (p = path->first; p; p = p->next)
			if (fprintf(file, "%f %f %f\n", p->x, p->y, p->z) < 0)
				return 0;
	}
	if (file != stdout && fclose(file) < 0)
		return 0;
	return 1;
}


void gnuplot_write(const char *name, const struct path *paths)
{
	FILE *file;

	file = name ? fopen(name, "w") : stdout;
	if (!file) {
		perror(name);
		exit(1);
	}
	if (!gnuplot_do_write(file, paths)) {
		perror(name ? name : "(stdout)");
		exit(1);
	}
}