/*
	Created for Netfuel Design (http://www.netfueldesign.com/) 
	To do user management and billing.

	-- Roy Keene [0200220002117] rkeene@netfueldesign.com
*/

#include "encrypt.h"
#include "screenio.h"
#include "billing.h"
#include "variable.h"
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <signal.h>
#include <ctype.h>
#include <string.h>
#ifndef NO_TCL
#include <tclExtend.h>
#include <tcl.h>
#endif

#ifndef GO32
int tty_fd=1, old_clflags;
#endif

void resetdisplay(int signal) {
#ifndef GO32
        struct termios terminfo;
        tcgetattr(tty_fd, &terminfo);
        terminfo.c_lflag=old_clflags;
        tcsetattr(tty_fd, TCSADRAIN, &terminfo);
#endif
	return;
}


int main(int argc, char **argv) {
#ifndef GO32
	struct termios terminfo;
#endif
	if ( signal(SIGTERM, (void *) resetdisplay)==SIG_ERR || \
		signal(SIGINT, (void *) resetdisplay)==SIG_ERR) {
		perror("main: signal");
		printf("Something might happen to your display.\n");
	}
	clear();
#ifndef GO32
	tty_fd=open("/dev/tty", O_RDWR);
	ioctl(tty_fd, TCGETS, &terminfo);
	old_clflags=terminfo.c_lflag;
	terminfo.c_lflag=0;
	ioctl(tty_fd, TCSETS, &terminfo);
#endif

	playmenu("main.mnu");
        resetdisplay(-1);
#ifndef GO32
        close(tty_fd);
#endif
	return(0);
}

int drawmenu(char *title, struct menulist menuitems[], int numitems, int selected) {
	int i;
	gohome();
	printf("%40s\n\n", title);
	for (i=0; i<numitems; i++) {
		if (menuitems[i].exec_cmd.type==BILLING_EXEC_INPT) {
			printf("\033[%im%c - %-20s [%29s] \033[0m\n",(i==selected)*7,menuitems[i].hotkey, menuitems[i].name, menuitems[i].value);
		} else {
			printf("\033[%im%c - %-50s\033[0m\n", (i==selected)*7, menuitems[i].hotkey, menuitems[i].name);
		}
	}
	return(0);
}

/*
	Menu file format:
	[title (TITLE_LEN bytes)]([menu (sizeof struct menulist)]*)
*/
int playmenu(char *file) {
	struct menulist menuitems[10];
	struct stat finfo;
	char title[TITLE_LEN];
	char ch, tmp_key;
	char tmp_buf[50];
	int selected=0, oselected=0, fd, item_cnt=0, i,x;
#ifndef NO_TCL
	Tcl_Interp *interp=NULL;
#endif
	fd=open(file, O_RDONLY);
	fstat(fd, &finfo);
	if (finfo.st_size<TITLE_LEN) {
		item_cnt=0;
	} else {
		item_cnt=(int) ((finfo.st_size-TITLE_LEN)/sizeof(struct menulist));
	}
	read(fd, &title, TITLE_LEN);
	for (i=0;i<item_cnt;i++) {
		read(fd, &menuitems[i], sizeof(struct menulist));
	}
	close(fd);
	clear();
	drawmenu(title, menuitems, item_cnt, selected);
	while(1) {
		read(STDIN_FILENO, &ch, 1);
		if (ch==65) selected--;
		if (ch==66) selected++;
		if (ch==3) return(0);
		if (selected<0) selected=0;
		if (selected>(item_cnt-1)) selected=(item_cnt-1);
		if (ch==13 || ch==10) ch=tolower(menuitems[selected].hotkey);
		ch=tolower(ch);
		for (i=0;i<item_cnt;i++) {
			if (ch==tolower(menuitems[i].hotkey)) {
#ifdef DEBUG
				printf("%i -- %s\n", menuitems[i].exec_cmd.type, menuitems[i].exec_cmd.exec_file);
#endif
				switch (menuitems[i].exec_cmd.type) {
					case BILLING_EXEC_MENU:
						playmenu(menuitems[i].exec_cmd.exec_file);
						clear();
						oselected=-1;
						break;
					case BILLING_EXEC_TCL:
#ifndef NO_TCL
						if (interp==NULL) {
							interp=Tcl_CreateInterp();
						}

/* We must export our variables and re-import them here. */

						Tcl_EvalFile(interp, menuitems[i].exec_cmd.exec_file);
						printf("Retval=\"%s\"\n",interp->result);
#endif
						break;
					case BILLING_EXEC_QUIT:
						return(0);
						break;
					case BILLING_EXEC_INPT:
						locate(i+3,27);
						memset(&tmp_buf, '_', 29);
						write(STDOUT_FILENO, &tmp_buf, 29);
						fsync(STDOUT_FILENO);
						locate(i+3,27);
						x=0;
						while (1) {
							tmp_key=getchar();
							if (tmp_key==10 || tmp_key==13 || x==29) { 
								locate(item_cnt+3,1);
								tmp_buf[x]=0;
								strcpy(menuitems[i].value,tmp_buf);
								setvar(menuitems[i].exec_cmd.exec_file,tmp_buf);
								drawmenu(title, menuitems, item_cnt, selected);
								break; 
							}
							write(STDOUT_FILENO, &tmp_key, 1);
							fsync(STDOUT_FILENO);
							tmp_buf[x++]=tmp_key;
						}
						break;
				}
			}
		}

		if (selected!=oselected) {
			gohome();
			drawmenu(title, menuitems, item_cnt, selected);
			oselected=selected;
		}

	}
}
