/* メニュー関係 */

#include "bootpack.h"
#include <string.h>

struct SHEET *open_menu(struct SHTCTL *shtctl, struct MENU *menu, int menunum, int x, int y);
void close_menu(struct SHEET *sht);
void sel_menu(struct SHEET *sht, int num);
void unsel_menu(struct SHEET *sht, int num);
void exec_menu(char *command, int memtotal);

extern unsigned int mdata[4];
extern struct SHEET *sht_back;

static struct MENU main_menu[4] = {
	{ "apps     >", "<<<submenu>>>                       " },
	{ "Console   ", "<<<console>>>                       " },
	{ "Edit      ", "edit doc0.txt                       " },
	{ "Readme    ", "tview -w125 -h45 /etc/doc/readme.txt" }
};

static struct MENU sub_menu[5] = {
	{ "invader   ", "invader                             " },
	{ "guicalc   ", "guicalc                             " },
	{ "noodle3   ", "noodle3                             " },
	{ "noodle4   ", "noodle4                             " },
	{ "noodle5   ", "noodle5                             " }
};

struct SHEET *sht_menu[2];
int menu_flag[2];

void menu_task(int memtotal)
{
	struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
	struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
	struct SHTCTL *shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
	struct TASK *task = task_now();
	int x = 0, y = 0;
	int mx = mdata[0];
	int my = mdata[1];
	int exec_flag = 0;
	int buf = 0;

	task->langmode = 1;

	sht_menu[0] = open_menu(shtctl, main_menu, 4, 0, binfo->scrny - 28 - (4 * 18 + 8));
	sht_menu[1] = open_menu(shtctl, sub_menu, 4, 0, binfo->scrny - 28 - (4 * 18 + 8));
	close_menu(sht_menu[0]);
	close_menu(sht_menu[1]);

	for(;;) {
		mx = mdata[0];
		my = mdata[1];
		buf = fifo32_get(&task->fifo);
		if(mdata[2] != 0 && buf == '!') {
			if ((2 <= mx && mx <= 60 && sht_back->bysize - 24 <= my && my <= sht_back->bysize - 3) && menu_flag[0] == 0) {
				push_menu(sht_back->buf, sht_back->bxsize, sht_back->bysize);
				sht_menu[0] = open_menu(shtctl, main_menu, 4, 0, binfo->scrny - 28 - (4 * 18 + 8));
				menu_flag[0] = 1;
				sheet_refresh(sht_back, 2, sht_back->bysize - 24, 61, sht_back->bysize - 2);
				sheet_refresh(sht_menu[0], 0, 0, sht_menu[0]->bxsize - 1, sht_menu[0]->bysize - 1);
			} else if ((2 <= mx && mx <= 60 && sht_back->bysize - 24 <= my && my <= sht_back->bysize - 3) && menu_flag[0] == 1) {
				pull_menu(sht_back->buf, sht_back->bxsize, sht_back->bysize);
				close_menu(sht_menu[0]);
				close_menu(sht_menu[1]);
				menu_flag[0] = 0;
				menu_flag[1] = 0;
				sheet_refresh(sht_back, 2, sht_back->bysize - 24, 61, sht_back->bysize - 2);
			}
			
			if(menu_flag[0] == 1) {
				x = mx - sht_menu[0]->vx0;
				y = my - sht_menu[0]->vy0;
				if(x >= 4 && x <= 83 && y >= (0 * 18 + 4) && y <= ((0 + 1) * 18 + 4) && menu_flag[1] == 0) {
					if(exec_flag == 0) {
						exec_menu(main_menu[0].command, memtotal);
						menu_flag[1] = 1;
						exec_flag = 1;
					}
				}
				
				if(x >= 4 && x <= 83 && y >= (1 * 18 + 4) && y <= ((1 + 1) * 18 + 4)) {
					if(exec_flag == 0) {
						pull_menu(sht_back->buf, sht_back->bxsize, sht_back->bysize);
						close_menu(sht_menu[0]);
						close_menu(sht_menu[1]);
						menu_flag[0] = 0;
						menu_flag[1] = 0;
						sheet_refresh(sht_back, 2, sht_back->bysize - 24, 61, sht_back->bysize - 2);
						exec_menu(main_menu[1].command, memtotal);
						exec_flag = 1;
					}
				}
				
				if(x >= 4 && x <= 83 && y >= (2 * 18 + 4) && y <= ((2 + 1) * 18 + 4)) {
					if(exec_flag == 0) {
						pull_menu(sht_back->buf, sht_back->bxsize, sht_back->bysize);
						close_menu(sht_menu[0]);
						close_menu(sht_menu[1]);
						menu_flag[0] = 0;
						menu_flag[1] = 0;
						sheet_refresh(sht_back, 2, sht_back->bysize - 24, 61, sht_back->bysize - 2);
						exec_menu(main_menu[2].command, memtotal);
						exec_flag = 1;
						main_menu[2].command[8] += 0x01;
					}
				}
				
				if(x >= 4 && x <= 83 && y >= (3 * 18 + 4) && y <= ((3 + 1) * 18 + 4)) {
					if(exec_flag == 0) {
						pull_menu(sht_back->buf, sht_back->bxsize, sht_back->bysize);
						close_menu(sht_menu[0]);
						close_menu(sht_menu[1]);
						menu_flag[0] = 0;
						menu_flag[1] = 0;
						sheet_refresh(sht_back, 2, sht_back->bysize - 24, 61, sht_back->bysize - 2);
						exec_menu(main_menu[3].command, memtotal);
						exec_flag = 1;
					}
				}
			}
			
			if(menu_flag[1] == 1) {
				x = mx - sht_menu[1]->vx0;
				y = my - sht_menu[1]->vy0;
				if(x >= 4 && x <= 83 && y >= (0 * 18 + 4) && y <= ((0 + 1) * 18 + 4)) {
					if(exec_flag == 0) {
						pull_menu(sht_back->buf, sht_back->bxsize, sht_back->bysize);
						close_menu(sht_menu[0]);
						close_menu(sht_menu[1]);
						menu_flag[0] = 0;
						menu_flag[1] = 0;
						sheet_refresh(sht_back, 2, sht_back->bysize - 24, 61, sht_back->bysize - 2);
						exec_menu(sub_menu[0].command, memtotal);
						exec_flag = 1;
					}
				}
				
				if(x >= 4 && x <= 83 && y >= (1 * 18 + 4) && y <= ((1 + 1) * 18 + 4)) {
					if(exec_flag == 0) {
						pull_menu(sht_back->buf, sht_back->bxsize, sht_back->bysize);
						close_menu(sht_menu[0]);
						close_menu(sht_menu[1]);
						menu_flag[0] = 0;
						menu_flag[1] = 0;
						sheet_refresh(sht_back, 2, sht_back->bysize - 24, 61, sht_back->bysize - 2);
						exec_menu(sub_menu[1].command, memtotal);
						exec_flag = 1;
					}
				}
				
				if(x >= 4 && x <= 83 && y >= (2 * 18 + 4) && y <= ((2 + 1) * 18 + 4)) {
					if(exec_flag == 0) {
						pull_menu(sht_back->buf, sht_back->bxsize, sht_back->bysize);
						close_menu(sht_menu[0]);
						close_menu(sht_menu[1]);
						menu_flag[0] = 0;
						menu_flag[1] = 0;
						sheet_refresh(sht_back, 2, sht_back->bysize - 24, 61, sht_back->bysize - 2);
						exec_menu(sub_menu[2].command, memtotal);
						exec_flag = 1;
					}
				}
				
				if(x >= 4 && x <= 83 && y >= (3 * 18 + 4) && y <= ((3 + 1) * 18 + 4)) {
					if(exec_flag == 0) {
						pull_menu(sht_back->buf, sht_back->bxsize, sht_back->bysize);
						close_menu(sht_menu[0]);
						close_menu(sht_menu[1]);
						menu_flag[0] = 0;
						menu_flag[1] = 0;
						sheet_refresh(sht_back, 2, sht_back->bysize - 24, 61, sht_back->bysize - 2);
						exec_menu(sub_menu[3].command, memtotal);
						exec_flag = 1;
					}
				}
				
				if(x >= 4 && x <= 83 && y >= (4 * 18 + 4) && y <= ((4 + 1) * 18 + 4)) {
					if(exec_flag == 0) {
						pull_menu(sht_back->buf, sht_back->bxsize, sht_back->bysize);
						close_menu(sht_menu[0]);
						close_menu(sht_menu[1]);
						menu_flag[0] = 0;
						menu_flag[1] = 0;
						sheet_refresh(sht_back, 2, sht_back->bysize - 24, 61, sht_back->bysize - 2);
						exec_menu(sub_menu[4].command, memtotal);
						exec_flag = 1;
					}
				}
			}
			
			if(sht_menu[0] != 0) sheet_refresh(sht_menu[0], 0, 0, sht_menu[0]->bxsize, sht_menu[0]->bysize);
			if(sht_menu[1] != 0) sheet_refresh(sht_menu[1], 0, 0, sht_menu[1]->bxsize, sht_menu[1]->bysize);
		}

		else if(mdata[3] != 0) {
			if ((2 <= mx && mx <= 60 && sht_back->bysize - 24 <= my && my <= sht_back->bysize - 3) && menu_flag[0] == 1) {
				pull_menu(sht_back->buf, sht_back->bxsize, sht_back->bysize);
				close_menu(sht_menu[0]);
				close_menu(sht_menu[1]);
				menu_flag[0] = 0;
				menu_flag[1] = 0;
				sheet_refresh(sht_back, 2, sht_back->bysize - 24, 61, sht_back->bysize - 2);
			}
			
			x = mx - sht_menu[0]->vx0;
			y = my - sht_menu[0]->vy0;
			if(y <= 21 && y >= 4 && menu_flag[0] == 1) {
				close_menu(sht_menu[1]);
				menu_flag[1] = 0;
			}
		} else {
			exec_flag = 0;
				
			if(menu_flag[0] == 1) {
				x = mx - sht_menu[0]->vx0;
				y = my - sht_menu[0]->vy0;
				if(x >= 4 && x <= 83 && y >= (0 * 18 + 4) && y <= ((0 + 1) * 18 + 4)) {
					sel_menu(sht_menu[0], 1);
				}
				
				if(x >= 4 && x <= 83 && y >= (1 * 18 + 4) && y <= ((1 + 1) * 18 + 4)) {
					sel_menu(sht_menu[0], 2);
				}
				
				if(x >= 4 && x <= 83 && y >= (2 * 18 + 4) && y <= ((2 + 1) * 18 + 4)) {
					sel_menu(sht_menu[0], 3);
				}
				
				if(x >= 4 && x <= 83 && y >= (3 * 18 + 4) && y <= ((3 + 1) * 18 + 4)) {
					sel_menu(sht_menu[0], 4);
				}
			}
			
			if(menu_flag[1] == 1) {
				x = mx - sht_menu[1]->vx0;
				y = my - sht_menu[1]->vy0;
				if(x >= 4 && x <= 83 && y >= (0 * 18 + 4) && y <= ((0 + 1) * 18 + 4)) {
					sel_menu(sht_menu[1], 1);
				}
				
				if(x >= 4 && x <= 83 && y >= (1 * 18 + 4) && y <= ((1 + 1) * 18 + 4)) {
					sel_menu(sht_menu[1], 2);
				}
				
				if(x >= 4 && x <= 83 && y >= (2 * 18 + 4) && y <= ((2 + 1) * 18 + 4)) {
					sel_menu(sht_menu[1], 3);
				}
				
				if(x >= 4 && x <= 83 && y >= (3 * 18 + 4) && y <= ((3 + 1) * 18 + 4)) {
					sel_menu(sht_menu[1], 4);
				}
				
				if(x >= 4 && x <= 83 && y >= (4 * 18 + 4) && y <= ((4 + 1) * 18 + 4)) {
					sel_menu(sht_menu[1], 5);
				}
			}
			if(sht_menu[0] != 0) {
				sheet_refresh(sht_menu[0], 0, 0, sht_menu[0]->bxsize, sht_menu[0]->bysize);
				unsel_menu(sht_menu[0], 1);
				unsel_menu(sht_menu[0], 2);
				unsel_menu(sht_menu[0], 3);
				unsel_menu(sht_menu[0], 4);
			}
			if(sht_menu[1] != 0) {
				sheet_refresh(sht_menu[1], 0, 0, sht_menu[1]->bxsize, sht_menu[1]->bysize);
				unsel_menu(sht_menu[1], 1);
				unsel_menu(sht_menu[1], 2);
				unsel_menu(sht_menu[1], 3);
				unsel_menu(sht_menu[1], 4);
				unsel_menu(sht_menu[1], 5);
			}
		}
	}
}

struct SHEET *open_menu(struct SHTCTL *shtctl, struct MENU *menu, int menunum, int x, int y)
{
	struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
	struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
	struct SHTCTL *shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
	struct SHEET *sht = sheet_alloc(shtctl);
	int i = 0;

	unsigned char *buf = (unsigned char *) memman_alloc_4k(memman, (88) * (menunum * 18 + 8) * 4 + 256);
	sheet_updown(sht, -1);
	sheet_setbuf(sht, buf, 88, menunum * 18 + 8, -1); /* 透明色なし */
	sht->flag2 = 2;
	boxfill8(sht->buf, sht->bxsize, COL8_000000, 0    , 0    , sht->bxsize - 1, sht->bysize - 1);
	boxfill8(sht->buf, sht->bxsize, COL8_333333, 1    , 1    , sht->bxsize - 2, sht->bysize - 2);
	for(i = 0;i < menunum;i++) {
		putfonts8_asc_sht(sht, 4, (i * 18 + 4), COL8_FFFFFF, COL8_333333, menu[i].label, 10);
	}
	sheet_slide(sht, x, y);
	sheet_updown(sht, shtctl->top);
	sheet_refresh(sht, 0, 0, sht_back->bxsize, sht_back->bysize);
	return sht;
}

void close_menu(struct SHEET *sht)
{
	struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
	sheet_updown(sht, -1);
	memman_free_4k(memman, (int) sht->buf, sht->bxsize * sht->bysize * 4 + 256);
	sheet_free(sht);
}

void sel_menu(struct SHEET *sht, int num)
{
	int x, y;
	int c, tc_new, tbc_new, tc_old, tbc_old, an1_old, an2_old, an1_new, an2_new, *buf = sht->buf;
	
	tc_new  = COL8_000000;
	tbc_new = COL8_ffffff;
	tc_old  = COL8_FFFFFF;
	tbc_old = COL8_333333;

	if(sht->flag2 == 2) {
		for (y = (((num * 18) - 18) + 4); y <= num * 18 + 2; y++) {
			for (x = 4; x <= 83; x++) {
				c = sht->buf[y * sht->bxsize + x];
				if (c == tc_old) {
					c = tc_new;
				} else if (c == tbc_old) {
					c = tbc_new;
				}
				sht->buf[y * sht->bxsize + x] = c;
			}
		}
	}
}

void unsel_menu(struct SHEET *sht, int num)
{
	int x, y;
	int c, tc_new, tbc_new, tc_old, tbc_old, an1_old, an2_old, an1_new, an2_new, *buf = sht->buf;
	
	tc_new  = COL8_FFFFFF;
	tbc_new = COL8_333333;
	tc_old  = COL8_000000;
	tbc_old = COL8_ffffff;

	if(sht->flag2 == 2) {
		for (y = (((num * 18) - 18) + 4); y <= num * 18 + 2; y++) {
			for (x = 4; x <= 83; x++) {
				c = sht->buf[y * sht->bxsize + x];
				if (c == tc_old) {
					c = tc_new;
				} else if (c == tbc_old) {
					c = tbc_new;
				}
				sht->buf[y * sht->bxsize + x] = c;
			}
		}
	}
}

void exec_menu(char *command, int memtotal)
{
	struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
	struct FIFO32 *sys_fifo = (struct FIFO32 *) *((int *) 0x0fec);
	struct SHTCTL *shtctl = (struct SHTCTL *) *((int *) 0x0fe4);
	struct TASK *task;
	struct SHEET *key_win;
	struct FIFO32 *fifo;
	int i;

	if (strncmp(command, "<<<submenu>>>", 13) == 0) {
		sht_menu[1] = open_menu(shtctl, sub_menu, 5, 88, (((binfo->scrny - 28 - (4 * 18 + 8)) - (18 * 4)) - 2));
		return;
	} else if (strncmp(command, "<<<console>>>", 13) == 0) {
		key_win = open_console(shtctl, memtotal);
		keywin_on(key_win);
		sheet_slide(key_win, 8, 8);
		sheet_updown(key_win, shtctl->top);
		key_win->flag2 = 0;
	} else {
		task = open_constask(0, memtotal);
		fifo = &task->fifo;
		for (i = 0; command[i] != 0; i++) {
			fifo32_put_io(fifo, command[i] + 256);
		}
		fifo32_put_io(fifo, 10 + 256);	/* Enter */
	}

	return;
}
