/***   [wcall.c]
*
*	ウィンドウ呼び出しウィンドウ		(C)ささがわ
*
*	For GNU C Compiler (GCC)   Version 1.39
*
***/

#include <stdio.h>
#include "graph.h"
#include "mos.h"
#include "window.h"
#include "windmgr.h"
#include "others.h"
#include "txwind.h"
#include "icn.h"

#define WH_TITLE	1
#define WH_CAN		2
#define WH_SCUP		3
#define WH_SCDW		4
#define WH_SCDR		5
#define WH_FILE		6
#define WH_OTHER	0

extern int	PAL_Back, PAL_Black;
static int	wx, wy, Sx, Sy, topLine;
static struct sb_t	SB;

static int	SUB_cancel(void);
static void	SUB_move(int, int);
static void	Draw_window(void);
static int	Where(int, int);
static void	Windiag(void);
static int	Map(int, int);
static void	Write_line(int);
static void	drawScrollbar(void);
static void	SUB_scupdw(int);
static int	SUB_scupdw_sub(int);
static void	SUB_scdr(int);
static int	SUB_file(int, int);
static void	SUB_file_rev(int);
static int	SUB_file_where(int, int);

int WIND_callWin(int x, int y) {
	int		ret = 0;
	struct RECT	a, b;
	
	Sx = x;		Sy = y;
	SB.tl = WMGR_nWind();	SB.lpp = 8;
	SB.blen = 128;			SB.bml = 15;
	wx = 106;	wy = 144;
	topLine = 0;
	
	a.x1 = 319;	a.y1 = 259;
	a.x2 = 320;	a.y2 = 260;
	b.x1 = wx;	b.y1 = wy;
	b.x2 = wx + 428;	b.y2 = wy + 192;
	afterImage(&a, &b);
	
	Draw_window();
	while (!ret) {
		char	mb;
		int		mx, my;
		
		CLOCK(0);
		if (MOS_rdpos(&mb, &mx, &my), !(mb & 1))
			continue;
		
		switch (Where(mx, my)) {
			case WH_CAN:
				if (SUB_cancel())
					ret = -1;
				break;
			case WH_TITLE:	SUB_move(mx, my);	break;
			case WH_SCUP:	SUB_scupdw(0);		break;
			case WH_SCDW:	SUB_scupdw(1);		break;
			case WH_SCDR:	SUB_scdr(my);		break;
			case WH_FILE:
				if ((ret = SUB_file(mx, my)) >= 0)
					ret++;
				else
					ret = 0;
				break;
			default:	while (MOS_rdpos(&mb, &mx, &my), mb & 1);	break;
		}
	}
	
	return (ret > 0 ? ret - 1 + topLine : -1);
}

static int SUB_cancel(void) {
	return Button(wx + 6, wy + 6, wx + 25, wy + 25);
}

static void SUB_move(int x, int y) {
	struct RECT	s, w;
	
	w.x1 = wx;			w.y1 = wy;
	w.x2 = wx + 428;	w.y2 = wy + 192;
	s.x1 = 0;	s.y1 = 40;
	s.x2 = 639;	s.y2 = 463;
	if (dragWindow(x, y, &w, &s, 0, 0)) {
		wx = w.x1;	wy = w.y1;
		MOS_disp(0);
		EGB_cls(0);
		MOS_disp(1);
		Draw_window();
	}
}

static void Draw_window(void) {
	int		i;
	struct opnwin_t	opw;
	
	opw.title = "ウィンドウ・呼び出し";
	opw.x1 = wx;
	opw.y1 = wy;
	opw.x2 = opw.x1 + 428;
	opw.y2 = opw.y1 + 192;
	opw.shdw = 1;
	opw.canb = 1;
	opw.nopt = 0;
	opw.wopt = NULL;
	opw.expb = 0;
	opw.ord = 0;
	
	MOS_disp(0);
	drawWindow(&opw);
	EGB_line(wx + 206, wy + 26, wx + 206, wy + 187, PAL_Black);
	EGB_str2("ウィンドウ総数", wx + 14, wy + 54, PAL_Black);
	EGB_str2("縮尺              1 : 5", wx + 14, wy + 74, PAL_Black);
	EGB_box(wx + 11, wy + 86, wx + 200, wy + 181, PAL_Black);
	DrawScrollbar(0, wx + 407, wy + 26, 162);
	Windiag();
	for (i = 0; i < 8; i++)	Write_line(i);
	drawScrollbar();
	MOS_disp(1);
}

static int Where(int x, int y) {
	int		ret;
	
	x -= wx;
	y -= wy;
	if (5 < x && x < 26 && 5 < y && y < 26)
		ret = WH_CAN;
	else if (26 < x && x < 423 && 5 < y && y < 26)
		ret = WH_TITLE;
	else if (407 < x && x < 423 && 26 < y && y < 42)
		ret = WH_SCUP;
	else if (407 < x && x < 423 && 171 < y && y < 187)
		ret = WH_SCDW;
	else if (407 < x && x < 423 && 42 < y && y < 171)
		ret = WH_SCDR;
	else if (206 < x && x < 407 && 26 < y && y < 187)
		ret = WH_FILE;
	else
		ret = WH_OTHER;
	
	return ret;
}

static void Windiag(void) {
	int		i;
	char	s[10];
	struct RECT	w;
	
	sprintf(s, "%3d", SB.tl);
	EGB_str2(s, wx + 174, wy + 54, PAL_Black);
	for (i = 0; i < SB.tl; i++) {
		WMGR_cord(i, &w);
		EGB_boxf(Map(0, w.x1), Map(1, w.y1), Map(0, w.x2), Map(1, w.y2), PAL_Black, 15);
	}
	EGB_color(EGB_work, EGB_COL_BACK, 7);
	EGB_writeMode(EGB_work, 9);
	EGB_linePattern(EGB_work, 0, 0xf0f0f0f0);
	EGB_box(Map(0, Sx), Map(1, Sy), Map(0, Sx + 639), Map(1, Sy + 479), PAL_Black);
	EGB_line(Map(0, Sx), Map(1, Sy + 40), Map(0, Sx + 639), Map(1, Sy + 40), PAL_Black);
	EGB_linePattern(EGB_work, 0, 0xffffffff);
	EGB_writeMode(EGB_work, 0);
}

static int Map(int m, int a) {
	return (m ? a * 93 / 511 + wy + 87 : a * 187 / 1023 + wx + 12);
}

static void Write_line(int l) {
	char	s[30], p[20];
	
	if (l >= 8 || topLine + l >= SB.tl)
		return;
	
	Cont_path(((struct txinfo_t *)WMGR_inf(topLine + l))->name, 18, p);
	sprintf(s, " %03d  %-18s ", WMGR_no(topLine + l), p);
	EGB_str3(s, wx + 207, wy + 44 + 20 * l, PAL_Black, 7);
}

static void drawScrollbar(void) {
	int		u, l;
	
	SCRB_page(&SB, topLine, &u, &l);
	
	if (u > 0)
		EGB_boxf(wx + 408, wy + 43, wx + 422, wy + 43 + u - 1, 6, 6);
	DrawButton(0, wx + 408, wy + 43 + u, wx + 422, wy + 43 + l);
	if (l < 127)
		EGB_boxf(wx + 408, wy + 43 + l + 1, wx + 422, wy + 170, 6, 6);
}

static void SUB_scupdw(int w) {
	int		mx, my, xx, yy, fllast, flpush = 1;
	char	mb;
	
	xx = wx + 408;
	yy = wy + (w ? 172 : 27);
	
	EGB_rev(1, xx, yy, xx + 14, yy + 14);
	fllast = SUB_scupdw_sub(w);
	TIMER_set(20);
	
	while (MOS_rdpos(&mb, &mx, &my), mb & 1) {
		int		whres;
		
		whres = Where(mx, my) == (w ? WH_SCDW : WH_SCUP);
		if (!whres && flpush || whres && !flpush) {
			EGB_rev(1, xx, yy, xx + 14, yy + 14);
			flpush = !flpush;
		}
		
		if (flpush && TIMER() && !fllast)
			fllast = SUB_scupdw_sub(w);
	}
	
	if (flpush)
		EGB_rev(1, xx, yy, xx + 14, yy + 14);
}

static int SUB_scupdw_sub(int w) {
	if (!(!w && topLine > 0 || w && topLine + 8 < SB.tl))
		return 1;
	
	w ? topLine++ : topLine--;
	MOS_disp(0);
	drawScrollbar();
	EGB_color(EGB_work, EGB_COL_BACK, 7);
	EGB_scrl(1, wx + 207, wy + 27, wx + 406, wy + 186, 0, w ? -20 : 20);
	Write_line(w ? 7 : 0);
	MOS_disp(1);
	
	return 0;
}

static void SUB_scdr(int my) {
	int		i, mx;
	char	mb;	
	
	ICN_mos(3);
	SCRB_bar(&SB, my - (wy + 43), &topLine);
	
	MOS_disp(0);
	drawScrollbar();
	for (i = 0; i < 8; i++)	Write_line(i);
	MOS_disp(1);
	
	while (MOS_rdpos(&mb, &mx, &my), mb & 1) {
		int		a, f;
		
		if (Where(mx, my) != WH_SCDR)
			continue;
		if (SCRB_bar(&SB, my - (wy + 43), &a), a == topLine)
			continue;
		
		f = a < topLine;
		topLine += f ? -1 : 1;
		
		MOS_disp(0);
		drawScrollbar();
		EGB_color(EGB_work, EGB_COL_BACK, 7);
		EGB_scrl(1, wx + 207, wy + 27, wx + 406, wy + 186, 0, f ? 20 : -20);
		Write_line(f ? 0 : 7);
		MOS_disp(1);
	}
	ICN_mos(0);
}

static int SUB_file(int mx, int my) {
	int		ret;
	int		i, sc, psc = -1;
	char	mb;
	
	do {
		if (psc == (sc = SUB_file_where(mx, my)))
			continue;
		
		if (psc != -1)
			SUB_file_rev(psc);
		if (sc != -1)
			SUB_file_rev(sc);
		psc = sc;
	} while (MOS_rdpos(&mb, &mx, &my), mb & 1);
	
	if (psc == -1)
		ret = -1;
	else {
		for (i = 0; i < 4; i++) {
			for (TIMER_set(5); !TIMER(); );
			SUB_file_rev(psc);
		}
		ret = psc;
	}
	
	return ret;
}

static void SUB_file_rev(int a) {
	struct RECT	w;
	
	MOS_disp(0);
	EGB_rev(0, wx + 207, wy + 27 + a * 20, wx + 406, wy + 27 + (a + 1) * 20 - 1);
	WMGR_cord(a + topLine, &w);
	EGB_rev(0, Map(0, w.x1), Map(1, w.y1), Map(0, w.x2), Map(1, w.y2));
	MOS_disp(1);
}

static int SUB_file_where(int x, int y) {
	int		ret;
	
	if (Where(x, y) == WH_FILE) {
		ret = (y - (wy + 27)) / 20;
		if (topLine + ret >= SB.tl)
			ret = -1;
	} else
		ret = -1;
	
	return ret;
}
