/*
 * irctrl-cl.c:	A general IR control client
 *
 *	By:	Alan Yates <alany@ay.com.au>
 */
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#include "irctrl-cl.h"
#define cmd_delay 100000

int DEV = 0;
char *PROG = 0;
char rxbuffer[BUFSIZE];
unsigned int recv_cursor = 0;
unsigned int decode_cursor = 0;


/* user select() to delay for a while */
void delay() {
	struct timeval tv;
	tv.tv_sec = 0;
	tv.tv_usec = cmd_delay;
	select(0, 0, 0, 0, &tv);
}	


/* process a collected command line */
int
process_cmdline() {
	char buf[BUFSIZE], *p1, *p2;
	
	if(!fgets(buf, BUFSIZE, stdin)) return 0;
	buf[strlen(buf)-1] = 0;
	if(strlen(buf)) {
		p1 = buf;
		p2 = buf;
		while((p2 = strsep(&p1, " "))) {
			foxtel_tx(p2);
			delay();
		}
	}
	return 1;
}

/* get input data and try to decode it */
int
process_rxbuffer() {
	char buf[BUFSIZE];
	unsigned int ret, i;

	ret = read(DEV, buf, BUFSIZE);
	for(i = 0; i < ret; i++) {
		rxbuffer[(recv_cursor+i)%BUFSIZE] = buf[i];
	}
	recv_cursor += ret;
	recv_cursor %= BUFSIZE;

	return foxtel_rx(&decode_cursor);
}

/* select loop for input from console and device */
int
interactive() {
	fd_set fds;
	int ret;
	struct timeval tv;

	fprintf(stdout, "%s> ", PROG);
	fflush(stdout);
	while(-1) {
		FD_ZERO(&fds);
		FD_SET(0, &fds);
		FD_SET(DEV, &fds);
		tv.tv_sec = 0;
		tv.tv_usec = 500;
		ret = select(DEV+1, &fds, 0, 0, &tv);
		if(ret < 0) {
			perror("select()");
			return -1;
		} else {
			if(FD_ISSET(0, &fds)) {
				if(!process_cmdline()) return 0;
				fprintf(stdout, "%s> ", PROG);
			} else if(FD_ISSET(DEV, &fds)) {
				if(process_rxbuffer())
					fprintf(stdout, "%s> ", PROG);
			} else foxtel_rx(&decode_cursor);
			fflush(stdout);
		}
	}
}


/* init */
int
init() {
	if((DEV = open(IR_DEV, O_RDWR)) < 0) {
		perror(IR_DEV);
		return -1;
	}
	return 0;
}

/* main */
int
main(int argc, char **argv) {
	PROG = argv[0];
	if(init()) return -1;
	interactive();
	return 0;
}
