 /*
  * UAE - The Un*x Amiga Emulator
  *
  * Text-based user interface
  * Sie haben es sich verdient!
  *
  * Copyright 1996 Tim Gunn, Bernd Schmidt
  */

#include "sysconfig.h"
#include "sysdeps.h"

#include <stdio.h>
#include <ctype.h>

#include "config.h"
#include "options.h"
#include "os.h"
#include "autoconf.h"
#include "tui.h"
#include "gui.h"
#include "memory.h"

char *screenmodes[] = { "320x200", "320x240", "320x400", "640x480", "800x600" };
char *colormodes[] = { "256 colors", "32768 colors", "65536 colors",
	"256 colors dithered", "16 colors dithered", "16 million colors" };

int quit_program;

char mountvol[256] = "\0";
char mountdir[256] = "\0";
int mountok=0;

void gui_led(int led, int on)
{
}
void gui_filename(int num, char *name)
{
}
static void getline(char *p)
{
}
void gui_handle_events(void)
{
}

static void save_options(FILE *f)
{
    /* We only get here if allow_save is true, so... */
    fprintf(f, "-o\n");
    if (use_debugger)
	fprintf(f, "-D\n");
    fprintf(f, "-r %s\n", romfile);
    fprintf(f, "-0 %s\n", df0);
    fprintf(f, "-1 %s\n", df1);
    fprintf(f, "-2 %s\n", df2);
    fprintf(f, "-3 %s\n", df3);
    fprintf(f, "-p %s\n", prtname);
    fprintf(f, "-S %d\n", produce_sound);
    if (fake_joystick)
	fprintf(f, "-J\n");
    fprintf(f, "-l %s\n", (keyboard_lang == KBD_LANG_DE ? "de"
			   : keyboard_lang == KBD_LANG_US ? "us"
			   : keyboard_lang == KBD_LANG_SE ? "se"
			   : keyboard_lang == KBD_LANG_FR ? "fr"
			   : keyboard_lang == KBD_LANG_IT ? "it"
			   : "FOO"));
    fprintf(f, "-f %d\n", framerate);
    fprintf(f, "-d %d\n", screen_res);
    if (correct_aspect)
	fprintf(f, "-C\n");
    fprintf(f, "-H %d\n", color_mode);
    if (fastmem_size > 0)
	fprintf(f, "-F %d\n", fastmem_size / 0x100000);
    if (bogomem_size > 0)
	fprintf(f, "-s %d\n", bogomem_size / 0x40000);
    fprintf(f, "-c %d\n", chipmem_size / 0x80000);
    if (!automount_uaedev)
	fprintf(f, "-a\n");
    fprintf(f, "-B %d\n", sound_desired_bsiz);
    fprintf(f, "-b %d\n", sound_desired_bits);
    fprintf(f, "-R %d\n", sound_desired_freq);
    
    write_filesys_config(f);
}

void gui_exit()
{
    if (allow_save) {
	if (tui_backup_optionsfile() == 0) {
	    FILE *f = fopen(optionsfile, "w");
	    if (f == NULL) {
		fprintf(stderr, "Error saving options file!\n");
		return;
	    }
	    save_options(f);
	    fclose(f);
	}
    }
}

static const char *mainmenu[] = { 
	"D - Disk settings",
	"V - Video settings",
	"M - Memory settings",
	"H - Hard disk settings",
	"S - Sound settings",
	"O - Other settings",
	NULL
};

static const char *diskmenu[] = { 
	"0 - change DF0:",
	"1 - change DF1:",
	"2 - change DF2:",
	"3 - change DF3:",
	NULL
};

static const char *videomenu[] = { 
	"1 - Change resolution",
	"2 - Change color mode",
	"3 - Toggle aspect correction",
	"4 - Change framerate",
	NULL
};

static const char *memmenu[] = { 
	"1 - Change fastmem size",
	"2 - Change chipmem size",
	"3 - Change slowmem size",
	NULL
};

static const char *soundmenu[] = { 
	"1 - Change sound emulation",
	NULL
};

static const char *miscmenu[] = { 
	"1 - Toggle keypad joystick emulation",
	"2 - Select ROM image",
	NULL
};

static const char *hdmenu[] = {
	"1 - Enable/Disable HardDrive file",
	"2 - Change Mounted volume name",
	"3 - Change Mounted volume path",
	"4 - Enable/Disable Mounted volume",
	NULL
};

static int makemenu(const char **menu, int x, int y)
{
    const char **m = menu;
    int maxlen = 0, count = 0;
    int w;
    
    while (*m != NULL) {
	int l = strlen(*m);
	if (l > maxlen)
	    maxlen = l;
	m++; count++;
    }
    w = tui_dlog(x, y, x + maxlen + 2, y + count + 1);
    tui_drawbox(w);
    tui_selwin(w);
    y = 2;
    while (*menu != NULL) {
	tui_gotoxy(2, y++);
	tui_puts(*menu++);
    }
    tui_selwin(0);
    return w;
}

static char tmpbuf[256];

static char *trimfilename(char *s, size_t n)
{
    size_t i;
    if (n > 250)
	n = 250;
    if (strlen(s) == 0)
	strcpy(tmpbuf, "none");
    else if (strlen(s) < n)
	strcpy(tmpbuf, s);
    else {
	tmpbuf[0] = '^';
	strcpy(tmpbuf + 1, s + strlen(s) - n + 2);
    }
    for (i = strlen(tmpbuf); i < n; i++)
	tmpbuf[i] = ' ';
    tmpbuf[i] = 0;
    return tmpbuf;
}

static void print_configuration(void)
{
    char tmp[256];
    int y = 5;

/*    tui_clrarea(35,4,79,20);*/
    
    tui_gotoxy(35, y++); sprintf(tmp, "Disk file DF0: %s", trimfilename(df0, tui_cols() - 50)); tui_puts(tmp);
    tui_gotoxy(35, y++); sprintf(tmp, "Disk file DF1: %s", trimfilename(df1, tui_cols() - 50)); tui_puts(tmp);
    tui_gotoxy(35, y++); sprintf(tmp, "Disk file DF2: %s", trimfilename(df2, tui_cols() - 50)); tui_puts(tmp);
    tui_gotoxy(35, y++); sprintf(tmp, "Disk file DF3: %s", trimfilename(df3, tui_cols() - 50)); tui_puts(tmp);
    y++;
    tui_gotoxy(35, y++);
    sprintf(tmp, "VIDEO: %-7s %-19s ",screenmodes[screen_res], colormodes[color_mode]); 
    tui_puts(tmp);

    tui_gotoxy(42, y++);
    if (correct_aspect)
	tui_puts("Aspect corrected    ");
    else 
	tui_puts("Not aspect corrected");
    tui_gotoxy(42, y++);
    tui_puts("drawing every ");
    switch(framerate) {
     case 1: break;
     case 2: tui_puts("2nd "); break;
     case 3: tui_puts("3rd "); break;
     default: sprintf(tmp, "%dth ",framerate); tui_puts(tmp); break;
    }
    tui_puts("frame.    ");
    y++;
    tui_gotoxy(35, y++);
    sprintf(tmp, "MEMORY: %4dK chip; %4dK fast; %4dK slow",chipmem_size/1024,fastmem_size/1024,bogomem_size/1024);
    tui_puts(tmp);

    tui_gotoxy(35, y++);
    sprintf(tmp, "ROM IMAGE: %s", trimfilename(romfile, tui_cols() - 50));
    tui_puts(tmp);
    tui_gotoxy(35, y++);
    if (!sound_available)
	tui_puts("SOUNDS: Not available");
    else {
	switch (produce_sound) {
	 case 0: tui_puts("SOUND: 0 (Off)                   "); break;
	 case 1: tui_puts("SOUND: 1 (Off, but emulated)     "); break;
	 case 2: tui_puts("SOUND: 2 (On)                    "); break;
	 case 3: tui_puts("SOUND: 3 (On, emulated perfectly)"); break;
	}
    }

    tui_gotoxy(35,y++);
    if(fake_joystick==1) {
	tui_puts("JOYSTICK: using keypad emulation");
    } else {
	if (joystickpresent)
	    tui_puts("JOYSTICK: using joystick #0     ");
        else
	    tui_puts("JOYSTICK: no joystick emulation "); 
    }

    tui_gotoxy(35,y++);
    tui_puts("HARDDISK: ");
    if(hardfile_size>16) {
        sprintf(tmp, "Current Harddisk file = %d K is", hardfile_size/1024);
	tui_puts(tmp);
        if (automount_uaedev==1) {
	    tui_puts(" active"); 
	} else {
	    tui_puts(" not active"); 
	}
    } else {
	tui_puts("No Harddisk file available     "); 
    }

    tui_gotoxy(35,y++);
    if(mountok==1) {
	sprintf(tmp, "Mounting volume %s at %s",mountvol,mountdir); tui_puts(tmp);
    }
    tui_refresh();
}

static void HDOptions(void) 
{
    char *buff;
    char tmp[256];

    int w = makemenu(hdmenu, 3, 5);

    for (;;){
	int c;
	
	tui_selwin(0);
	print_configuration();
	tui_refresh();
	tui_selwin(w);
	tui_refresh();
	c = tui_getc();
	if (c == 27 || c == 13)
	    break;
	switch(c) {
	 case '1':
	    automount_uaedev=!automount_uaedev; break;
	 case '2':
	    tui_wgets(mountvol, "Enter mounted volume name", 78);
	    if(mountvol[strlen(mountvol)-1]==':') {
		mountvol[strlen(mountvol)-1]=0; }
	    break;
	 case '3': 
	    tui_wgets(mountdir, "Enter mounted volume path", 78);
	    break;
	 case '4': mountok=!mountok; break;
	}
    }
    tui_dlogdie(w);
}

static void DiskOptions(void) 
{
    char buf[256], tmp[256];
    int w = makemenu(diskmenu, 3, 5);
    
    for (;;) {
	char *sel;
	int c;
	
	tui_selwin(0);
	print_configuration();
	tui_refresh();
	tui_selwin(w);
	tui_refresh();
	
	c = tui_getc();
	if (c == 27 || c == 13)
	    break;
	switch(c) {
	 case '0': 
	    sel = tui_filereq("*.adf", df0);
	    if (sel == NULL)
		break;
	    strcpy(df0, sel); 
	    break;
	 case '1': 
	    sel = tui_filereq("*.adf", df1);
	    if (sel == NULL)
		break;
	    strcpy(df1, sel); 
	    break;
	 case '2': 
	    sel = tui_filereq("*.adf", df2);
	    if (sel == NULL)
		break;
	    strcpy(df2, sel); 
	    break;
	 case '3': 
	    sel = tui_filereq("*.adf", df3);
	    if (sel == NULL)
		break;
	    strcpy(df3, sel); 
	    break;
	}
    }
    tui_dlogdie(w);
}

static void VideoOptions(void) 
{
    char tmp[256];
    int w = makemenu(videomenu, 3, 5);

    for (;;) {
	int c;

	tui_selwin(0);
	print_configuration();
	tui_refresh();
	tui_selwin(w);
	tui_refresh();

	c = tui_getc();
	if (c == 27 || c == 13)
	    break;
	switch(c) {
	 case 49:
	    screen_res++;
	    if (screen_res > MAX_SCREEN_MODES)
		screen_res=0;
	    break;
	 case 50:
	    color_mode++;
	    if (color_mode > MAX_COLOR_MODES) 
		color_mode=0;
	    break;
	 case 51:
	    correct_aspect = !correct_aspect;
	    break;
	 case 52:
	    framerate++;
	    if (framerate > 9)
		framerate=1;
	    break;
	}
    }
    tui_dlogdie(w);
}

static void MemoryOptions(void)
{
    int w = makemenu(memmenu, 3, 5);
    for (;;) {
	int c;

	tui_selwin(0);
	print_configuration();
	tui_refresh();
	tui_selwin(w);
	tui_refresh();

	c = tui_getc();
	if (c == 27 || c == 13)
	    break;
	switch(c) {
	 case '1':
	    if (fastmem_size == 0)
		fastmem_size = 0x200000;
	    else if (fastmem_size == 0x800000)
		fastmem_size = 0;
	    else
		fastmem_size <<= 1;
	    break;
	 case '2':
	    if (chipmem_size == 0x200000)
		chipmem_size = 0x80000;
	    else
		chipmem_size <<= 1;
            break;
	 case '3':
	    if (bogomem_size == 0)
		bogomem_size = 0x40000;
	    else if (bogomem_size == 0x100000)
		bogomem_size = 0;
	    else
		bogomem_size <<= 1;
	    break;
        }

    }
    tui_dlogdie(w);
}

static void SoundOptions(void)
{
    int w = makemenu(soundmenu, 3, 5);

    for (;;) {
	int c;

	tui_selwin(0);
	print_configuration();
	tui_refresh();
	tui_selwin(w);
	tui_refresh();

	c = tui_getc();
	if (c == 27 || c == 13)
	    break;
	switch(c) {
	 case '1':
	    produce_sound++;
	    if(produce_sound > 3)
		produce_sound = 0;
	    break;

        }
    }
    tui_dlogdie(w);
}

static void OtherOptions(void)
{
    char *tmp;
    int w = makemenu(miscmenu, 3, 5);

    for (;;) {
	int c;

	tui_selwin(0);
	print_configuration();
	tui_refresh();
	tui_selwin(w);
	tui_refresh();

	c = tui_getc();
	if (c == 27 || c == 13)
	    break;
	switch(c) {
	 case '1':
            fake_joystick = !fake_joystick;
            break;
	 case '2':
            tmp = tui_filereq("*.rom", romfile);
	    if (tmp != NULL)
		strcpy(romfile, tmp);
	    break;
	}
    }
    tui_dlogdie(w);
}

int gui_init() 
{
    char cwd[1024];
    char tmp[256];
    int mm_win;
    
    if (getcwd(cwd, 1024) == NULL)
	return 0;

    quit_program = 0;

    tui_setup();

    tui_drawbox(0);
    tui_hline(2, 3, tui_cols() - 1);
    sprintf(tmp, "UAE %d.%d.%d: The Un*x Amiga Emulator", UAEMAJOR, UAEMINOR, UAEURSAMINOR);
    tui_gotoxy((tui_cols() - strlen(tmp))/2, 2); tui_puts(tmp);
    strcpy(tmp, "Press RETURN/ENTER to run UAE, ESC to exit");
    tui_gotoxy((tui_cols() - strlen(tmp))/2, tui_lines()); tui_puts(tmp);
	
    mm_win = makemenu(mainmenu, 2, 4);

    for (;;) {
	int c;
	tui_selwin(0);
	print_configuration();
	tui_refresh();
	tui_selwin(mm_win);
	tui_refresh();
	c = tui_getc();
	
	if (c == 27) {
	    tui_dlogdie(mm_win);
	    tui_shutdown();
	    exit(0);
	} else if (c == 13) {
	    break;
	}
	
	switch(c) {
	 case 100: DiskOptions(); break;
	 case 118: VideoOptions(); break;
	 case 109: MemoryOptions(); break;
	 case 104: HDOptions(); break;
	 case 115: SoundOptions(); break;
	 case 111: OtherOptions(); break;
	}
    }

    tui_dlogdie(mm_win);
    if(mountok)
	add_filesys_unit(mountvol, mountdir, 0);

    tui_shutdown();
    chdir (cwd);
    return 0;
}
