/***   [wstype.c]
*
*	メイン		(C)ささがわ
*
*	For GNU C Compiler (GCC)   Version 1.39
*
***/

#include <stdio.h>
#include <stdlib.h>
#include <mos.h>
#include <kyb.h>
#include <bios.h>
#include "graph.h"
#include "optparse.h"
#include "dropdm.h"
#include "icn.h"
#include "windmgr.h"
#include "beep.h"
#include "others.h"
#include "backg.h"
#include "window.h"
#include "txwind.h"
#include "disp.h"

#define WH_MENU		0
#define WH_HELP		1
#define WH_EXIT		2
#define WH_TITLE	3
#define WH_BOX		4
#define WH_OTHER	5

int	PAL_Black = 3;
int	PAL_Button = 11;
int PAL_Back = 7;
int PAL_MOJI = 3;
static int	wx, wy;
static char	titl[12800];

extern void	Errhdl(void);
extern void	CtrlC_ignore(void);
extern int	WIND_callWin(int, int);
extern void	WIND_filesel_init(void);
extern void	WIND_eyes(void);
extern void	WIND_clock(void);
extern void	WIND_schroll(void);
extern void	WIND_help(void);
extern void	SCR_init(void);

static int	SUB_exit(void);
static void	SUB_help(void);
static void	MENU_Win(int);
static void	MENU_Setting(int);
static void	MENU_Others(int);
static void	CloseWinall(void);
static void	CallWin(void);
static void	PutWinorder(void);
static void	OpenWin_init(void);
static void	ScreenInitialize(void);
static void	ScreenDisposeof(void);
static void	Set_palette(void);
static int	Menubar(int *, int *);
static int	Where(int, int);
static void	OpenWin(void);
static void	Title_open(void);
static void	Title_close(void);
static void	SUB_move_scope(int, int);
static void	SUB_Window(int, int);
static void	MoveScope_start(void);
static void	MoveScope_end(int, int);
static void	activeWin(int, int, int);

void main(int argc, char *argv[]) {
	int		ret = 0;
	
	fprintf(stderr, "ＷＳＴｙｐｅ  Version 1.0   (C)ささがわ  Aug. 1991\n");
	
	CtrlC_ignore();
	Errhdl();
	ScreenInitialize();
	
	OPT_init(argc, argv);
	BEP_init();
	BACKG_init();
	WIND_filesel_init();
	DSP_init();
	SCR_init();
	
	MOS_disp(0);
	BACKG_draw(0, 0);
	Title_open();
	MOS_disp(1);
	CLOCK(1);
	
	OpenWin_init();
	
	while (!ret) {
		char	mb;
		int		mx, my, d;
		
		CLOCK(0);
		if (MOS_rdpos(&mb, &mx, &my), !(mb & 1))
			continue;
		MOS_rdon(0, &mb, &d, &d, &d);
		
		switch (Where(mx, my)) {
			case WH_EXIT:	ret = SUB_exit();	break;
			case WH_HELP:	SUB_help();		break;
			case WH_MENU:
				if (!Menubar(&mx, &my))	break;
				switch (mx) {
					case 0:		MENU_Win(my);		break;
					case 1:		MENU_Setting(my);	break;
					default:	MENU_Others(my);	break;
				}
				break;
			case WH_BOX:	SUB_move_scope(mx, my);	break;
			case WH_OTHER:	SUB_Window(mx, my);		break;
			default:	while (MOS_rdpos(&mb, &mx, &my), mb & 1);	break;
		}
	}
	
	ScreenDisposeof();
	if (OPT_Cons())	MOS_screenterm(EGB_work);
}

static int SUB_exit(void) {
	int		r, cw;
	static const char	*a[] = {
		"ＷＳＴｙｐｅを終了します",
		""
	};
	
	if (!Button(wx + 603, wy + 3, wx + 634, wy + 34))
		return 0;
	
	cw = WMGR_cWind();
	WMGR_close();
	Xpage(0, wx, wy);
	r = WIND_confirm("終  了", a);
	Xpage(1, wx, wy);
	EGB_rev(1, wx + 603, wy + 3, wx + 634, wy + 34);
	if (cw >= 0)	WMGR_open(0, cw, wx, wy);
	
	return r;
}

static void SUB_help(void) {
	int		cw;
	
	if (!Button(wx + 563, wy + 3, wx + 594, wy + 34))
		return;
	
	cw = WMGR_cWind();
	WMGR_close();
	Xpage(0, wx, wy);
	WIND_help();
	Xpage(1, wx, wy);
	EGB_rev(1, wx + 563, wy + 3, wx + 594, wy + 34);
	if (cw >= 0)	WMGR_open(0, cw, wx, wy);
}

static void MENU_Win(int a) {
	switch (a) {
		case 0:		OpenWin();	break;
		case 1:		CallWin();	break;
		case 2:		PutWinorder();	break;
		default:	CloseWinall();	break;
	}
}

static void MENU_Setting(int a) {
	int		cw;
	
	cw = WMGR_cWind();
	WMGR_close();
	Xpage(0, wx, wy);
	switch (a) {
		case 0:	DSP_change();	break;
		case 1:	WIND_schroll();	break;
		default:	WIND_beep();	break;
	}
	Xpage(1, wx, wy);
	if (cw >= 0)	WMGR_open(0, cw, wx, wy);
}

static void MENU_Others(int a) {
	int		cw;
	
	cw = WMGR_cWind();
	WMGR_close();
	Xpage(0, wx, wy);
	switch (a) {
		case 0:	WIND_error(5, NULL);	break;
		case 1:	WIND_clock();		break;
		default:	WIND_eyes();	break;
	}
	Xpage(1, wx, wy);
	if (cw >= 0)	WMGR_open(0, cw, wx, wy);
}

static void CloseWinall(void) {
	int		r, cw;
	static const char	*a[] = {
		"     すべて閉じます",
		""
	};
	
	cw = WMGR_cWind();
	WMGR_close();
	Xpage(0, wx, wy);
	r = WIND_confirm("ウィンドウ", a);
	Xpage(1, wx, wy);
	if (!r) {
		if (cw >= 0)	WMGR_open(0, cw, wx, wy);
		return;
	}
	
	while (WMGR_nWind() > 0)	WMGR_unregi(0);
	
	MOS_disp(0);
	EGB_actPage(0);
	EGB_cls(0);
	EGB_Hscrl(0, 0);
	BACKG_draw(0, 0);
	
	EGB_actPage(1);
	Title_close();
	EGB_cls(0);
	BACKG_draw(wx, wy);
	Title_open();
	MOS_disp(1);
	CLOCK(1);
}

static void PutWinorder(void) {
	int		i, n, r, cw;
	static const char	*a[] = {
		"       整頓します",
		""
	};
	
	cw = WMGR_cWind();
	WMGR_close();
	Xpage(0, wx, wy);
	r = WIND_confirm("ウィンドウ", a);
	Xpage(1, wx, wy);
	if (!r) {
		if (cw >= 0)	WMGR_open(0, cw, wx, wy);
		return;
	}
	
	MOS_disp(0);
	EGB_actPage(0);
	EGB_cls(0);
	EGB_Hscrl(0, 0);
	BACKG_draw(0, 0);
	
	EGB_actPage(1);
	Title_close();
	EGB_cls(0);
	BACKG_draw(wx, wy);
	for (i = 0, n = WMGR_nWind(); i < n; i++) {
		int		a;
		struct RECT	c;
		struct txinfo_t	*inf;
		
		inf = WMGR_inf(i);
		WMGR_place(i, n, wx, wy, &c);
		WMGR_change(i, &c);
		a = (c.x2 - c.x1 - 31) / (inf->fontx / 2);
		if (inf->lgcolw)
			BMGR_change(a, inf->tab, &inf->file, &inf->line);
		else {
			if (inf->col >= (inf->lgcolw ? a : inf->lgcol))
				inf->col = (inf->lgcolw ? a : inf->lgcol) - 1;
		}
		WMGR_draw(i);
	}
	Title_open();
	MOS_disp(1);
	CLOCK(1);
}

static void CallWin(void) {
	int		r, cw, mx, my;
	char	mb;
	
	cw = WMGR_cWind();
	WMGR_close();
	Xpage(0, wx, wy);
	r = WIND_callWin(wx, wy);
	Xpage(1, wx, wy);
	if (r < 0) {
		if (cw >= 0)
			WMGR_open(0, cw, wx, wy);
		return;
	}
	
	MOS_rdpos(&mb, &mx, &my);
	activeWin(r, mx - wx, my - wy);
}

static void OpenWin_init(void) {
	int		i, nt;
	struct RECT	p, af1;
	
	ICN_mos(1);
	af1.x1 = wx + 319;	af1.y1 = wy + 259;
	af1.x2 = wx + 320;	af1.y2 = wy + 260;
	p.x1 = wx;	p.y1 = wy + 40;
	p.x2 = wx + 639;	p.y2 = wy + 479;
	nt = OPT_txt_n();
	
	for (i = 0; i < nt; i++) {
		int		r;
		const char	*fname;
		struct RECT	c, af2;
		
		WMGR_place(i, nt, wx, wy, &c);
		af2 = c;
		afterImage(&af1, &af2);
		
		fname = OPT_txt();
		r = WMGR_regi(0, fname, &c, nt <= 8 ? &p : &c);
		if (r >= 0)
			WMGR_draw(r);
		else {
			Xpage(0, wx, wy);
			switch (r) {
				case -1:	WIND_error(1, NULL);	break;
				case -2:	WIND_error(0, fname);	break;
				default:	WIND_error(2, NULL);	break;
			}
			Xpage(1, wx, wy);
			MOS_disp(0);
			EGB_writeMode(EGB_work, 4);
			EGB_box(af2.x1, af2.y1, af2.x2, af2.y2, 15);
			EGB_writeMode(EGB_work, 0);
			MOS_disp(1);
			if (r != -2)	break;
		}
	}
	ICN_mos(0);
}

static void OpenWin(void) {
	int		cw, w, ret;
	char	path[85];
	struct RECT	c, p, z;
	
	cw = WMGR_cWind();
	WMGR_close();
	Xpage(0, wx, wy);
	ret = WIND_filesel("ウィンドウ・開く", path);
	Xpage(1, wx, wy);
	
	if (ret != 1) {
		if (cw >= 0)	WMGR_open(0, cw, wx, wy);
		return;
	}
	
	if (WMGR_nWind() == 0) {
		c.x1 = wx;			c.y1 = wy + 40;
		c.x2 = wx + 639;	c.y2 = wy + 479;
		p.x1 = wx + 160;	p.y1 = wy + 150;
		p.x2 = wx + 479;	p.y2 = wy + 369;
	} else {
		c.x1 = wx + 160;	c.y1 = wy + 150;
		c.x2 = wx + 479;	c.y2 = wy + 369;
		p.x1 = wx;			p.y1 = wy + 40;
		p.x2 = wx + 639;	p.y2 = wy + 479;
	}
	
	z.x1 = wx + 319;	z.y1 = wy + 259;
	z.x2 = wx + 320;	z.y2 = wy + 260;
	afterImage(&z, &c);
	
	w = WMGR_regi(0, path, &c, &p);
	if (w >= 0) {
		WMGR_open(1, w, wx, wy);
	} else {
		Xpage(0, wx, wy);
		switch (w) {
			case -1:	WIND_error(1, NULL);	break;
			case -2:	WIND_error(0, path);	break;
			default:	WIND_error(2, NULL);	break;
		}
		Xpage(1, wx, wy);
		MOS_disp(0);
		EGB_writeMode(EGB_work, 4);
		EGB_box(c.x1, c.y1, c.x2, c.y2, 15);
		EGB_writeMode(EGB_work, 0);
		MOS_disp(1);
	}
}

static void ScreenInitialize(void) {
	static char	mwork[4 * 1024];
	static char	swork[16 * 1024];
	
	KYB_init();
	KYB_clic(1);
	
	EGB_int();
	EGB_resolution(EGB_work, 0, 3);
	EGB_resolution(EGB_work, 1, 3);
	EGB_displayPage(EGB_work, 1, 3);
	
	SND_init(swork);
	SND_pcm_mode_set(1);
	
	MOS_start(mwork, 4 * 1024);
	MOS_resolution(0, 3);
	MOS_resolution(1, 3);
	MOS_writePage(1);
	MOS_horizon(0, 639);
	MOS_vertical(0, 479);
	ICN_mos(0);
	
	EGB_actPage(0);
	Set_palette();
	EGB_actPage(1);
	Set_palette();
	
	MOS_setpos(320, 240);
	MOS_disp(1);
}

static void Title_open(void) {
	int		i;
	
	EGB_get(titl, wx, wy, wx + 639, wy + 39);
	EGB_boxf(wx, wy, wx + 639, wy + 39, 13, 13);
	for (i = 0; i < 2; i++)
		EGB_str2(" ＷＳＴｙｐｅ   Version 1.0", wx + 40 + i, wy + 16, PAL_Black);
	
	EGB_boxf(wx + 4, wy + 4, wx + 37, wy + 37, PAL_Black, PAL_Black);
	EGB_boxf(wx + 2, wy + 2, wx + 35, wy + 35, PAL_Black, 15);
	ICN_put(3, wx + 3, wy + 3, PAL_Black);
	
	EGB_boxf(wx + 42, wy + 19, wx + 299, wy + 38, PAL_Black, PAL_Black);
	EGB_boxf(wx + 40, wy + 17, wx + 297, wy + 36, PAL_Black, 15);
	EGB_str2(" ウィンドウ ", wx + 41, wy + 34, PAL_Black);
	EGB_str2(" 設    定 ", wx + 137, wy + 34, PAL_Black);
	EGB_str2(" そ の 他 ", wx + 217, wy + 34, PAL_Black);
	
	EGB_boxf(wx + 564, wy + 4, wx + 597, wy + 37, PAL_Black, PAL_Black);
	EGB_boxf(wx + 562, wy + 2, wx + 595, wy + 35, PAL_Black, 15);
	ICN_put(98, wx + 563, wy + 3, PAL_Black);
	EGB_boxf(wx + 604, wy + 4, wx + 637, wy + 37, PAL_Black, PAL_Black);
	EGB_boxf(wx + 602, wy + 2, wx + 635, wy + 35, PAL_Black, 15);
	ICN_put(126, wx + 603, wy + 3, PAL_Black);
}

static void Title_close(void) {
	EGB_put(0, titl, wx, wy, wx + 639, wy + 39);
}

static void ScreenDisposeof(void) {
	MOS_end();
	SND_end();
	EGB_displayPage(EGB_work, 0, 0);
}

static void Set_palette(void) {
	EGB_pal(3, 0, 0, 0, 1);
	EGB_pal(4, 112, 0, 0, 1);
	EGB_pal(6, 112, 160, 64, 1);
	EGB_pal(7, 181, 181, 181, 1);
	EGB_pal(11, 128, 128, 128, 1);
	EGB_pal(13, 172, 50, 223, 1);
}

static int Menubar(int *x, int *y) {
	struct dropdm_t	dp;
	struct menu_t	m[3];
	static const char	*a[] = {
		" 開  く       ",
		" 呼び出し     ",
		" 整理整頓     ",
		" ────── ",
		" すべて閉じる ",
		NULL
	}, *b[] = {
		" 表示方法   ",
		" スクロール ",
		" 警 告 音   ",
		NULL
	}, *c[] = {
		" ＣＤプレイヤー ",
		" Ｃｌｏｃｋ     ",
		" Ｅｙｅｓ       ",
		NULL
	};
	char	am[] = {
		0, 0, 0, 0, 0
	}, bm[] = {
		0, 0, 0
	}, cm[] = {
		0, 0, 0
	};
	
	if (WMGR_nWind() == 0) {
		am[1] = 1;	am[2] = 1;	am[4] = 1;
	}
	
	m[0].xt = wx + 41;	m[0].wt = 96;
	m[0].xm = m[0].xt;	m[0].wm = 14;
	m[0].name = a;		m[0].mask = am;
	m[1].xt = wx + 137;	m[1].wt = 80;
	m[1].xm = m[1].xt;	m[1].wm = 12;
	m[1].name = b;		m[1].mask = bm;
	m[2].xt = wx + 217;	m[2].wt = 80;
	m[2].xm = m[2].xt;	m[2].wm = 16;
	m[2].name = c;		m[2].mask = cm;
	
	dp.ntitle = 3;	dp.yt1 = wy + 18;
	dp.yt2 = dp.yt1 + 17;	dp.ym = dp.yt1 + 24;
	dp.m = m;	dp.shadow = 1;
	
	return DRPDM_main(x, y, &dp);
}

static int Where(int x, int y) {
	int		wh;
	
	x -= wx;
	y -= wy;
	if (40 < x && x < 297 && 17 < y && y < 36)
		wh = WH_MENU;
	else if (562 < x && x < 595 && 2 < y && y < 35)
		wh = WH_HELP;
	else if (602 < x && x < 635 && 2 < y && y < 35)
		wh = WH_EXIT;
	else if (2 < x && x < 35 && 2 < y && y < 35)
		wh = WH_BOX;
	else if (0 < x && x < 640 && 0 < y && y < 40)
		wh = WH_TITLE;
	else
		wh = WH_OTHER;
	
	return wh;
}

static void MoveScope_start(void) {
	int		i, n;
	struct RECT	xy;
	static char	mask[65536];
	
	WMGR_close();
	MOS_disp(0);
	EGB_actPage(0);
	EGB_cls(0);
	EGB_Hscrl(0, 0);
	BACKG_draw(0, 0);
	
	EGB_actPage(1);
	Title_close();
	EGB_maskRegion(EGB_work, mask);
	EGB_mask(EGB_work, 0x02);
	EGB_writeMode(EGB_work, 13);
	
	for (i = 0, n = WMGR_nWind(); i < n; i++) {
		WMGR_cord(i, &xy);
		EGB_boxf(xy.x1, xy.y1, xy.x2, xy.y2, 0, 0);
	}
	
	EGB_mask(EGB_work, 0x80);
	EGB_writeMode(EGB_work, 0);
	EGB_boxf(wx, wy, wx + 639, wy + 479, 0, 0);
}

static void MoveScope_end(int x, int y) {
	BACKG_draw(wx, wy);
	EGB_mask(EGB_work, 0);
	MOS_horizon(wx, wx + 639);
	MOS_vertical(wy, wy + 479);
	if (x >= 0 && y >= 0)
		MOS_setpos(wx + x, wy + y);
	Title_open();
	MOS_disp(1);
	CLOCK(1);
}

static void SUB_move_scope(int xx, int yy) {
	int		mx, my;
	char	mb;
	
	MoveScope_start();
	MOS_horizon(xx - wx, 1024 - (wx + 640 - xx));
	MOS_vertical(yy - wy, 512 - (wy + 480 - yy));
	do {
		MOS_rdpos(&mb, &mx, &my);
		EGB_Hscrl(mx - (xx - wx), my - (yy - wy));
	} while (mb & 1);
	wx = mx - (xx - wx);
	wy = my - (yy - wy);
	MoveScope_end(-1, -1);
}

static void SUB_Window(int mx, int my) {
	int		w;
	struct RECT	xy;
	
	TIMER_set(40);
	if ((w = WMGR_onWind(mx, my)) < 0)
		return;
	
	WMGR_cord(w, &xy);
	if (xy.x1 < wx || wx + 639 < xy.x2 || xy.y1 < wy + 40 || wy + 479 < xy.y2) {
		int		a, i, x, y;
		char	mb;
		
		if (MOS_rdon(0, &mb, &a, &x, &y), !a) {
			while (MOS_rdon(0, &mb, &a, &x, &y), i = TIMER(), !a && !i);
			if (i)	return;
		}
		if (w != WMGR_onWind(x, y))	return;
		
		activeWin(w, -1, -1);
	} else {
		activeWin(w, -1, -1);
		WMGR_main(mx, my);
	}
}

static void activeWin(int w, int mx, int my) {
	int		a, i;
	struct RECT	xy;
	
	WMGR_cord(w, &xy);
	if (xy.x1 < wx || wx + 639 < xy.x2 || xy.y1 < wy + 40 || wy + 479 < xy.y2) {
		MoveScope_start();
		
		if ((a = xy.x1 - wx) >= 0) {
			if ((a = xy.x2 - (wx + 639)) <= 0)
				a = 0;
		}
		i = a > 0 ? 10 : -10;
		while (abs(i) < abs(a)) {
			EGB_Hscrl(wx + i, wy);
			i += a > 0 ? 10 : -10;
		}
		EGB_Hscrl(wx += a, wy);
		
		if ((a = xy.y1 - (wy + 40)) >= 0) {
			if ((a = xy.y2 - (wy + 479)) <= 0)
				a = 0;
		}
		i = a > 0 ? 10 : -10;
		while (abs(i) < abs(a)) {
			EGB_Hscrl(wx, wy + i);
			i += a > 0 ? 10 : -10;
		}
		EGB_Hscrl(wx, wy += a);
		
		MoveScope_end(mx, my);
	}
	WMGR_open(0, w, wx, wy);
}

void CLOCK(int m) {
	int		i = 0, p;
	unsigned char	buf[20];
	struct calender_t	cal;
	static struct calender_t	pcal;
	const static char	*week[] = {
		"日", "月", "火", "水", "木", "金", "土"
	}, *tzone[] = {
		"深夜", "早朝", " 朝 ", "午前", " 昼 ", "午後", "夕方", " 夜 "
	}, tz[] = {
		3, 6, 9, 11, 13, 15, 18, 23
	};
	
	_bios_timeofday(_TIME_GETCLOCK, &cal);
	if (!m && pcal.hour == cal.hour && pcal.minute == cal.minute)
		return;
	
	MOS_disp(0);
	p = EGB_readactPage();
	EGB_actPage(1);
	sprintf((char *)buf, "%4u-%2u-%2u.%s", cal.year, cal.month, cal.day, week[cal.week]);
	EGB_str3((char *)buf, wx + 410, wy + 17, PAL_Black, 13);
	while (cal.hour > tz[i])	i++;
	sprintf((char *)buf, "  %2u:%2u %s", cal.hour, cal.minute, tzone[i]);
	EGB_str3((char *)buf, wx + 410, wy + 37, PAL_Black, 13);
	EGB_actPage(p);
	MOS_disp(1);
	pcal = cal;
}
