/***   [windmgr.c]
*
*	ウィンドウ管理		(C)ささがわ
*
*	For GNU C Compiler (GCC)   Version 1.39
*
***/

#include <stdlib.h>
#include <mos.h>
#include "graph.h"
#include "windmgr.h"
#include "txwind.h"
#include "backg.h"
#include "icn.h"

#define N_WINDOW	128

static struct wmgr_t	Winf[N_WINDOW];	/* ｳｨﾝﾄﾞｳ情報配列 */
static int	nWind = 0, Curw = -1;		/* ｳｨﾝﾄﾞｳの数とｶﾚﾝﾄ･ｳｨﾝﾄﾞｳ */

/* ｳｨﾝﾄﾞｳ新規登録関数 */
/*   return -1:memory error  -2:file error  -3:too many window */
int WMGR_regi(int sort, const char *path, struct RECT *xy1, struct RECT *xy2) {
	void	*ptr;
	
	if (nWind >= 128)
		return -3;
	
	switch (sort) {
		int		r;
		
		default:
			ICN_mos(1);
			r = TXW_regi(path, (struct txinfo_t **)&ptr, xy1->x1, xy1->x2);
			ICN_mos(0);
			if (r)	return r;
			break;
	}
	
	Winf[nWind].sort = sort;
	Winf[nWind].no = nWind;
	Winf[nWind].cxy = *xy1;
	Winf[nWind].pxy = *xy2;
	Winf[nWind].inf = ptr;
	nWind++;
	
	return (nWind - 1);
}

void WMGR_place(int no, int total, int wx, int wy, struct RECT *xy) {
	if (total <= 0 || (no < 0 || total <= no))
		return;
	
	if (total <= 8) {
		if (total == 1) {
			xy->x1 = 0;		xy->y1 = 40;
			xy->x2 = 639;	xy->y2 = 479;
		} else if (total == 2) {
			xy->x1 = 0;		xy->y1 = no ? 260 : 40;
			xy->x2 = 639;	xy->y2 = xy->y1 + 219;
		} else if (total <= 4) {
			xy->x1 = no % 2 ? 320 : 0;
			xy->y1 = no / 2 ? 260 : 40;
			xy->x2 = xy->x1 + 319;
			xy->y2 = xy->y1 + 219;
		} else if (total <= 6) {
			xy->x1 = no % 2 ? 320 : 0;
			xy->y1 = 146 * (no / 2) + 40;
			xy->x2 = xy->x1 + 319;
			xy->y2 = xy->y1 + 145;
		} else {
			xy->x1 = no % 2 ? 320 : 0;
			xy->y1 = 110 * (no / 2) + 40;
			xy->x2 = xy->x1 + 319;
			xy->y2 = xy->y1 + 109;
		}
		xy->x1 += wx;	xy->y1 += wy;
		xy->x2 += wx;	xy->y2 += wy;
	} else {
		no %= 12;
		xy->x1 = 341 * (no % 3);
		xy->y1 = 118 * (no / 3) + 40;
		xy->x2 = xy->x1 + 340;
		xy->y2 = xy->y1 + 117;
	}
}

void WMGR_draw(int no) {
	if (no < 0 || nWind <= no)
		return;
	
	switch (Winf[no].sort) {
		default:
			TXW_draw(no);
	}
}

int WMGR_no(int no) {
	if (no < 0)
		no = Curw;
	if (no < 0 || nWind <= no)
		return -1;
	
	return Winf[no].no;
}

/* ｳｨﾄﾞｳの大きさを返す関数 */
void WMGR_cord(int no, struct RECT *xy) {
	if (no < 0)
		no = Curw;
	if (no < 0 || nWind <= no)
		return;
	
	*xy = Winf[no].cxy;
}

/* ｶﾚﾝﾄ･ｳｨﾝﾄﾞｳを変更し描画する関数 */
int WMGR_open(int m, int now, int wx, int wy) {
	int		i;
	struct wmgr_t	wm;
	
	if (now < 0 || nWind <= now)
		return -1;
	if (now == Curw)
		return Curw;
	
	WMGR_close();
	
	if (!m)
		m = WMGR_pile(now);
	
	wm = Winf[now];
	for (i = now + 1; i < nWind; i++)
		Winf[i - 1] = Winf[i];
	Winf[nWind - 1] = wm;
	Curw = nWind - 1;
	
	switch (Winf[Curw].sort) {
		default:
			TXW_open(!m, wx, wy);
	}
	
	return Curw;
}

/* ｳｨﾝﾄﾞｳ･ﾏﾈｰｼﾞｬｰの情報提供関数 */
void *WMGR_inf(int no) {
	if (no < 0)
		no = Curw;
	
	return (no < 0 || nWind <= no ? NULL : Winf[no].inf);
}

int WMGR_pile(int no) {
	int		i, ret = 0;
	struct RECT	*p, *w;
	
	if (no < 0 || nWind <= no)
		return 0;
	
	w = &Winf[no].cxy;
	for (i = no + 1; i < nWind; i++) {
		p = &Winf[i].cxy;
		if (p->x2 >= w->x1 && w->x2 >= p->x1 && p->y2 >= w->y1 && w->y2 >= p->y1) {
			ret = 1;
			break;
		}
	}
	
	return ret;
}

int WMGR_nWind(void) {
	return nWind;
}

int WMGR_cWind(void) {
	return Curw;
}

/* 現在位置がどのｳｨﾝﾄﾞｳ上にあるのかを返す関数 */
int WMGR_onWind(int x, int y) {
	int		i, ret = -1;
	struct RECT	*p;
	
	for (i = nWind - 1; i >= 0; i--) {
		p = &Winf[i].cxy;
		if (p->x1 <= x && x <= p->x2 && p->y1 <= y && y <= p->y2) {
			ret = i;
			break;
		}
	}
	
	return ret;
}

/* ｳｨﾝﾄﾞｳ削除関数 */
void WMGR_unregi(int n) {
	int		i, a;
	
	if (n < 0)
		n = Curw;
	if (n < 0 || nWind <= n)
		return;
	
	free(Winf[n].inf);
	a = Winf[n].no;
	
	for (i = n + 1; i < nWind; i++)
		Winf[i - 1] = Winf[i];
	Curw = -1;
	nWind--;
	
	for (i = 0; i < nWind; i++) {
		if (Winf[i].no > a)
			Winf[i].no--;
	}
}

/* ｳｨﾝﾄﾞｳをｸﾛｰｽﾞする関数 */
void WMGR_close(void) {
	if (Curw < 0)
		return;
	
	switch (Winf[Curw].sort) {
		default:
			TXW_close();
	}
	Curw = -1;
}

void WMGR_vanish(int a, int wx, int wy) {
	int		i, w;
	struct RECT	c, *p;
	
	w = a < 0 ? Curw : a;
	if (w < 0 || nWind <= w)
		return;
	
	WMGR_cord(w, &c);
	MOS_disp(0);
	EGB_view(c.x1, c.y1, c.x2, c.y2);
	BACKG_draw(wx, wy);
	for (i = 0; i < nWind; i++) {
		p = &Winf[i].cxy;
		if (i == w || p->x2 < c.x1 || c.x2 < p->x1 || p->y2 < c.y1 || c.y2 < p->y1)
			continue;
		
		switch (Winf[i].sort) {
			default:
				TXW_draw(i);
		}
	}
	EGB_view(0, 0, 1023, 511);
	MOS_disp(1);
	
	if (a < -1)
		Curw = -1;
}

/* ｳｨﾝﾄﾞｳの大きさ変更関数 */
void WMGR_change(int n, struct RECT *c) {
	if (n < 0)
		n = Curw;
	if (n < 0 || nWind <= n)
		return;
	
	Winf[n].pxy = Winf[n].cxy;
	Winf[n].cxy = *c;
}

/* 過去のｳｨﾄﾞｳの大きさを返す関数 */
void WMGR_pcord(int no, struct RECT *xy) {
	if (no < 0)
		no = Curw;
	if (no < 0 || nWind <= no)
		return;
	
	*xy = Winf[no].pxy;
}

void WMGR_main(int x, int y) {
	if (Curw < 0)
		return;
	
	switch (Winf[Curw].sort) {
		default:	TXW_main(x, y);	break;
	}
}
