#include <stdio.h>
#include <string.h>
#ifndef __USE_ISOC99
#define __USE_ISOC99
#endif
#include <math.h>
#include "zoom.h"
#include "serial-util.h"

#define zputs(s) do { if (safewrite(fd, s, strlen(s)) != strlen(s)) \
                        return -1; } while(0)
#define zputc(ch) do { const char ____c = ch; \
                if (safewrite(fd, &____c, 1) != 1) return -1; } while(0)

static int last_dac, last_adc;

static int verify_prompt(int fd)
{
	char s[128];
	int dac1, dac2, adc1, adc2;
	if (fdgets(s, 128, fd, 1000) == NULL)
		return -1;
	chomp(s);
	if (sscanf(s, "%x %d  %x %d", &dac1, &dac2, &adc1, &adc2) != 4)
		return -1;
//	if (dac1 != dac2 || adc1 != adc2)
	if (adc1 != adc2)
		return -1;
	last_dac = dac1;
	last_adc = adc1;
	return 0;
}

int zoom_init_real(int fd, int dozero)
{
	zputs(dozero ? "00000000" : "        ");
	drain(fd);
	zputc(dozero ? '0' : ' ');
	if (verify_prompt(fd) < 0)
		return -1;
	return 0;
}

int zoom_zero_start(int fd)
{
	char s[128];
	zputc('z');
	if (fdgets(s, 128, fd, 1000) == NULL)
		return -1;
	chomp(s);
	if (strcmp(s, "zeroing input...") != 0)
		return -1;
	return 0;
}

int zoom_zero_stop(int fd)
{
	zputc(' ');
	if (verify_prompt(fd) < 0)
		return -1;
	return last_dac;
}

int zoom_sweep(int fd, int dac[ZOOM_SWEEP_COUNT], int adc[ZOOM_SWEEP_COUNT])
{
	char s[128];
	int i;
	char c;
	zputc('s');
	if (fdgets(s, 128, fd, 1000) == NULL)
		return -1;
	if (strncmp(s, "sweep around", 12) != 0)
		return -1;
	for (i = 0; i < ZOOM_SWEEP_COUNT; i++) {
		if (fdgets(s, 128, fd, 1000) == NULL)
			return -1;
		chomp(s);
		if (sscanf(s, "%d %d%c", &dac[i], &adc[i], &c) != 2)
			return -2;
	}
	if (verify_prompt(fd) < 0)
		return -3;
	return 0;
}

int zoom_write_dac(int fd, int dac)
{
	char s[128];

	sprintf(s, "v%04x", dac);
	zputs(s);
	if (verify_prompt(fd) < 0)
		return -1;
	return last_dac;
}

/* Run mode: */

void zoomrun_trigger_calibrate(int fd)
{
	char c = 'c';
	write(fd, &c, 1);
	drain_timeout(fd, 0);
}
