/*
	cmdmask.c
*/

#include <stdlib.h>
#include <stdlib.h>
#include <math.h>

#include "ge.h"
#include "imageman.h"
#include "dispman.h"
#include "mask.h"

#define	MASKOFF		mask_setswitch(NO)
#define	MASKON		mask_setswitch(YES)

#define	MASK_DEBUG 0

/*--------------------------------------------------------*/
/*               マスクの反転表示・反転消去               */
/*--------------------------------------------------------*/

static void erasemask(void)
{
	int xlen,ylen;
	xlen = EIMgetxsize();
	ylen = EIMgetysize();
	int i;
	mask_setswitch(YES);
	for (i=0; i<ylen; i++)
	{
		int ix = 0;
		while (ix < xlen)
		{
			int l = mask_chkxylen(ix,xlen-1,i,YES);
			ix += l;
			if (ix >= xlen)
				break;
			l = mask_chkxylen(ix,xlen-1,i,NO);
			if (l > 0)
			{
				mask_setswitch(NO);
				EIMhline(ix,ix+l-1,i,white,DrawXOR);
				mask_setswitch(YES);
			}
			ix += l;
		}
	}
	mask_setswitch(NO);
}

static void dispmask(bool first)
{
#if MASK_DEBUG
	first = YES;
#endif
	int xlen,ylen;
	xlen = EIMgetxsize();
	ylen = EIMgetysize();
	int i;
	mask_setswitch(YES);
	for (i=0; i<ylen; i++)
	{
		int ix = 0;
		while (ix < xlen)
		{
			int ix2;
			int l = mask_chkxylen(ix,xlen-1,i,YES);
			if (!first && l > 0)
			{
				ix2 = ix;
				while (ix2 < ix+l)
				{
					int l2 = mask_chkxylen_back(ix2,ix+l-1,i,YES);
					ix2 += l2;
					l2 = mask_chkxylen_back(ix2,ix+l-1,i,NO);
					if (l2 > 0)
					  {MASKOFF;EIMhline(ix2,ix2+l2-1,i,white,DrawXOR);MASKON;}
					ix2 += l2;
				}
			}
			ix += l;
			if (ix >= xlen)
				break;
			l = mask_chkxylen(ix,xlen-1,i,NO);
			if (first)
			{
				MASKOFF;  EIMhline(ix,ix+l-1,i,white,DrawXOR);  MASKON;
			}
			else if (l > 0)
			{
				ix2 = ix;
				while (ix2 < ix+l)
				{
					int l2 = mask_chkxylen_back(ix2,ix+l-1,i,YES);
					if (l2 > 0)
					  {MASKOFF;EIMhline(ix2,ix2+l2-1,i,white,DrawXOR);MASKON;}
					ix2 += l2;
					l2 = mask_chkxylen_back(ix2,ix+l-1,i,NO);
					ix2 += l2;
				}
			}
			ix += l;
		}
	}
	mask_setswitch(NO);
}

/*--------------------------------------------------------*/
/*       領域指定によるマスクのセット・クリア・反転       */
/*--------------------------------------------------------*/

static void area_mask(int type)
// type 0,1,2: それぞれセット、クリア、反転
{
	for (;;)
	{
		if (area_input(AREA_POLYGON) != 0)
			break;
#if MASK_DEBUG
		erasemask();
#endif
		mask_backup();
		int ax1,ay1,ax2,ay2;
		area_getboundxy(&ax1,&ay1,&ax2,&ay2);
		int x,y;
		ax1 = _lim(ax1, 0, EIMgetxsize());
		ax2 = _lim(ax2, 0, EIMgetxsize());
		ay1 = _lim(ay1, 0, EIMgetysize());
		ay2 = _lim(ay2, 0, EIMgetysize());
		for (y=ay1; y<=ay2; y++)
		{
			x = ax1 + area_chkxylen(ax1,ax2,y,YES);
			while (x<=ax2)
			{
				int l;
				if ((l = area_chkxylen(x,ax2,y,NO)) == 0)
					break;
				mask_hline(x,x+l-1,y, type);
				x += l + area_chkxylen(x+l,ax2,y,YES);
			}
		}
		dispmask(NO);
	}
}

/*--------------------------------------------------------*/
/*           全体指定によるマスクのクリア・反転           */
/*--------------------------------------------------------*/

static void all_mask(int type)
// type 0,1,2: それぞれセット、クリア、反転
{
	int i,xlen,ylen;
#if MASK_DEBUG
		erasemask();
#endif
	mask_backup();
	xlen = EIMgetxsize();
	ylen = EIMgetysize();
	for (i=0; i<ylen; i++)
		mask_hline(0,xlen-1,i, type);
	dispmask(NO);
}

/*--------------------------------------------------------*/
/*                マスク指定メニューの定義                */
/*--------------------------------------------------------*/

#define	MYLEN	160

/*
#define	itemSetMask		2
#define	itemClrMask		3
#define	itemXchgMask	4
#define	itemAllXchgMask	5
#define	itemAllClrMask	6
*/

#include "cmdmask.md"

void commandMask()
{
	// #define	SELPARA(n)		(maskmenu_sels[n].var)
	menu_selector_setvar(menu_selector(&maskmenu,selID0),
						 (mask_getswitch() ? 1 : 0));
	mask_setswitch(NO);
	dispmask(YES);
	menu_disp(&maskmenu);
	for (;;)
	{
		DMdispcsr(ms.x,ms.y);
		for (;;)
		{
			ms_get(&ms);
			if (ms.dx!=0||ms.dy!=0||ms.btn1!=OFF||ms.btn2!=OFF||key_chk()!=0)
				break;
		}
		DMerasecsr();
		scrollForCsr(1,1);
		if (ms.btn1 == OFFON)
		{
			int a;
			a = menu_where(ms.x,ms.y,&maskmenu, NULL,NULL,NULL);
			switch (a)
			{
			case itemSetMask:
				menu_erase();
				area_mask(0);
				menu_disp(&maskmenu);
				break;
			case itemClrMask:
				menu_erase();
				area_mask(1);
				menu_disp(&maskmenu);
				break;
			case itemXchgMask:
				menu_erase();
				area_mask(2);
				menu_disp(&maskmenu);
				break;
			case itemAllXchgMask:
				menu_erase();
				all_mask(2);
				menu_disp(&maskmenu);
				break;
			case itemAllClrMask:
				if (check_yes_no("マスクの設定を全部消去します。よろしいですか？") == 0)
				{
					menu_erase();
					all_mask(1);
				}
				else
					menu_erase();
				menu_disp(&maskmenu);
				break;
			case itemMoveMenu:
				menu_move();
				break;
			case itemSelector:
				menu_touchselector(&maskmenu);
				break;
			}
		}
		if (ms.btn2 == OFFON)
			break;
	}
exitloop:
	menu_erase();
end:
	erasemask();
	mask_setswitch(
		menu_selector_getvar(menu_selector(&maskmenu,selID0)) == 0 ?
		NO : YES);
	return;
}
