/* E-Run is a simple epplet i wrote so i didn't have to     */
/* open a new eterm everytime i wanted to run some program  */
/*                                                          */
/* you might be able to find a newer version of this epplet */
/* at http://mattk.nccw.net/~jacob/c0de/	            */
/*                                                          */
/* E-Run.c v1.2 1999 jacob kuenzel - jacob@mattk.nccw.net   */

#include <stdio.h>
#include <epplet.h>

#define toggle(x) { x = (x ? 0 : 1); }
#define LEN 512 /* maximum length of program[] and stuff. */

/* define this for some fun little messages */
/* #define DEBUG */

/* global stuff */
int i = 0; /* pointer into program[] */
int shifted = 0; /* 1 if shift is being pressed down. */

char program[LEN]; /* name of program to be run. */

Epplet_gadget program_label; /* so we see what we're typing */
Epplet_gadget close_button; /* close down the epplet.. */

/* for key conversions */
struct key {
	char *name;
	int lower;
	int upper;
};

/* stuff that needs to be converted */
struct key keys[] = {
	{"grave", '`', '~'},
	{"1", '1', '!'},
	{"2", '2', '@'},
	{"3", '3', '#'},
	{"4", '4', '$'},
	{"5", '5', '%'},
	{"6", '6', '^'},
	{"7", '7', '&'},
	{"8", '8', '*'},
	{"9", '9', '('},
	{"0", '0', '}'},
	{"minus", '-', '_'},
	{"equal", '=', '+'},
	{"Tab", '\t', '\t'},
	{"bracketleft", '[', '{'},
	{"bracketright", ']', '}'},
	{"backslash", '\\', '|'},
	{"semicolon", ';', ':'},
	{"apostrophe", '\'', '"'},
	{"comma", ',', '<'},
	{"period", '.', '>'},
	{"slash", '/', '?'},
	{"space", ' ', ' '},
	NULL	
};

void close_up(); /* shut down the epplet */
int convert(char *key); /* convert from what e gives me */
void key_pressed(char *data, Window win, char *key);
void key_released(char *data, Window win, char *key);

void close_up()
{
	Epplet_cleanup();
	exit(0);
}

int convert(char *key)
{
	int e;
	
	for(e = 0; keys[e].name; ++e)
		if (strcmp(key, keys[e].name) == 0)
			if (shifted)
				return(keys[e].upper);
			else
				return(keys[e].lower);
	return(-1);
}

void key_pressed(char *data, Window win, char *key)
{
	int c, w, h;
	char *tmp = malloc(LEN+1), *tmp2;

#ifdef DEBUG	
	printf("pressed %s\n", key);
#endif	
	if (! key)
		return;
	
	if (strlen(key) > 1 || *key > '0' && *key < '9') {
		if (strncmp( "Return", key, 6 ) == 0) {
			i = 0;
			Epplet_spawn_command(program);
			bzero(program, sizeof(program));
			goto update;
		}
		
		if (strncmp("Shift", key, 5) == 0) {
			toggle(shifted);
			return;
		} else if (strcmp("Caps_Lock", key) == 0) {
			toggle(shifted);
			return;
		} else if (strcmp("BackSpace", key) == 0) {
			if ( i > 0 )
				program[--i] = '\0';
			goto update;
		} else
			c = convert(key);
	} else
		if (shifted)
			c = toupper(*key);
		else
			c = *key;
		
	if (c == -1) /* what the hell? */
		return;
	
	if (i < LEN)
		program[i++] = c;
	else
		return;

update: 
	strcpy(tmp, program);
	Epplet_textclass_get_size("EPPLET_LABEL", &w, &h, tmp);
	
	tmp2 = tmp;
	while ( w > 100 ) 
		Epplet_textclass_get_size("EPPLET_LABEL", &w, &h, ++tmp);
	Epplet_change_label(program_label, tmp);

	free(tmp2);
	return;
}

void key_released(char *data, Window win, char *key)
{
#ifdef DEBUG
	printf( "released %s\n", key );
#endif
	if (! key)
		return;
		
	if (strncmp("Shift", key, 5) == 0) {
		toggle(shifted);
		return;
	}
	return;
}

int main(int argc, char **argv)
{	
	Window w;

	Epplet_Init("E-Run", "1.0", "I like to run stuff.", 9, 1, argc, argv, 0);
	
	Epplet_register_key_press_handler((void *) key_pressed, NULL);
	Epplet_register_key_release_handler((void *) key_released, NULL);
	
	Epplet_gadget_show(Epplet_create_label(5,3, "RUN:", 1));
	Epplet_gadget_show(program_label = Epplet_create_label(27, 3, "", 1));
	Epplet_gadget_show(close_button = Epplet_create_button(NULL,  NULL, 130, 2, 5, 4, "CLOSE", (Window) NULL, NULL, (void *) close_up, NULL));
	
	Epplet_show();
	Epplet_Loop();
	
	Epplet_cleanup();
	exit( 0 );
}	