/*
	colspace.c : 色空間からの色選択
*/

// #define	DEBUG

#include <stdlib.h>
#include <stdlib.h>
#include <msdos.cf>
#include <string.h>

#include "ge.h"
#include "imageman.h"
#include "dispman.h"
#include "mainmenu.h"

#define	METHOD	1		/* 0=HLSサークル 1=HLS△形 */
#define	TRIMETHOD	1

#define	SPCSIZ1	176	/* 画面拡大率が１倍のときの HSV サークルの大きさ */
						

static	int		curcol;

/*--------------------------------------------------------*/
/*                      色相系の変換                      */
/*--------------------------------------------------------*/

void hls_rgb(deci h,deci l,deci s, int *r, int *g, int *b)
{
	deci h2v(deci h, deci cmin, deci cmax)
	{
		while (h<0)			h+=ID(1);
		while (h>=ID(1)) 	h-=ID(1);
		h*=6;
		int t=h/ID(1); deci r=h%ID(1);
		if (t==0)				return cmin+DMUL(cmax-cmin,r);
		else if (t==1||t==2)	return cmax;
		else if (t==3)			return cmin+DMUL(cmax-cmin,ID(1)-r);
		else					return cmin;
	}
	deci cmin,cmax;
	if(l<0) l=0; if(l>ID(1)) l=ID(1);
	if(s<0) s=0; if(s>ID(1)) s=ID(1);
	while (h<0)			h+=ID(1);
	while (h>=ID(1)) 	h-=ID(1);
	h*=6;
	if(l<=ID(1)/2)	cmin=DMUL(l,ID(1)-s),cmax=2*l-cmin;
	else			cmax=DMUL(l,ID(1)-s)+s,cmin=2*l-cmax;
	*r = (31*h2v((h+ID(2))/6,cmin,cmax) + ID(1)/2) / ID(1);
	*g = (31*h2v(h/6,cmin,cmax)         + ID(1)/2) / ID(1);
	*b = (31*h2v((h-ID(2))/6,cmin,cmax) + ID(1)/2) / ID(1);
}

void rgb_hls(int _r, int _g, int _b, deci *h, deci *l, deci *s)
{
	deci r,g,b,cmin,cmax,cd;
	r = (IntToDeci(_r) + FD(0.5)) / 31;
	g = (IntToDeci(_g) + FD(0.5)) / 31;
	b = (IntToDeci(_b) + FD(0.5)) / 31;
	cmax = _max(r,g,b);
	cmin = _min(r,g,b);
	*l = (cmax+cmin)/2;
	cd = cmax-cmin;
	if (cd==0) {*h=*s=0; return;}
	if (*l<=ID(1)/2)	*s=DivDeci(cd,cmax+cmin);
	else				*s=DivDeci(cd,ID(2)-(cmax+cmin));
		 if(r==cmax) *h=DivDeci(g-b,cd);
	else if(g==cmax) *h=ID(2)+DivDeci(b-r,cd);
	else if(b==cmax) *h=ID(4)+DivDeci(r-g,cd);
	(*h)/=6;
	while(*h<0) (*h)+=ID(1);
	while(*h>ID(1)) (*h)-=ID(1);
}

/*--------------------------------------------------------*/
/*                   HLS サークルの表示                   */
/*--------------------------------------------------------*/

#if 0
static void drawHLScircle(int x1,int y1,int size,int col)
{
	int i;
	grboxfill(x1,y1,size,size,0,DrawNORMAL);
	void drawcircle(deci l)
	{
		int h,s,r,g,b;
		int x,y,xa,ya,rx,ry;
		for (y=0; y<size; y++)
		{
			unsigned short int gbuf[512]; //,gbuf2[512];
			int gbufx, gbuflen = 0;
			ry = ID(y) + FD(0.5) - ID(size)/2;
			ya = _abs(ry);
			for (x=0; x<size; x++)
			{
				rx = ID(x) + FD(0.5) - ID(size)/2;
				xa = _abs(rx);
				// s = 
				// DivDeci(isqrt(AdjMulDeci(rx*rx+ry*ry)), ID(size)/2);
				// if ( DI(xa)*xa+DI(xa)*xa <= (size/2)*(ID(size)/2) )
				s = DivDeci(isqrt(DI(xa)*xa+DI(ya)*ya),ID(size)/2);
				if (s <= DUNIT)
				// s = ID(1);
				// if ( DI(xa)*xa+DI(xa)*xa <= (size/2)*(ID(size)/2) )
				{
	/*
					象限と傾き（１より大きいか否か）により、８通りに場合分け
						第一象限、|y| <= |x|: theta = acos512(dest / x)
						第一象限、|y| > |x|	: theta = 128-acos512(dest / y)
						第二象限、|y| > |x|	: theta = 128+acos512(dest / y)
						第二象限、|y| <= |x|: theta = 256-acos512(dest / (-x))
						第三象限、|y| <= |x|: theta = 256+acos512(dest / (-x))
						第三象限、|y| > |x|	: theta = 384-acos512(dest / (-y))
						第四象限、|y| > |x|	: theta = 384+acos512(dest / (-y))
						第四象限、|y| <= |x|: theta = 512-acos512(dest / x)
	*/
					int sg = (ya <= xa ? 0 : 1);
					int theta;
					#define r1  DivDeci(ya,xa)
					#define r2  DivDeci(xa,ya)
					#define I(n) IntToDeci((n)*128)
					if (rx == 0 && ry == 0)
						;
					else if (ry > 0)
						if (rx > 0)
							theta = (sg==0? atan512(r1) : I(1)-atan512(r2));
						else
							theta = (sg==1? I(1)+atan512(r2):I(2)-atan512(r1));
					else
						if (rx < 0)
							theta = (sg==0? I(2)+atan512(r1):I(3)-atan512(r2));
						else
							theta = (sg==1? I(3)+atan512(r2):I(4)-atan512(r1));
					h = theta / 512;
					hls_rgb(h,l,s,&r,&g,&b);
					if (gbuflen == 0)
						gbufx = x1+x;
					gbuf[gbuflen] = 1024*g+32*r+b;
					// gbuf2[gbuflen] = 1024*b+32*r+g;
					gbuflen++;
				}
			}
			if (gbuflen > 0)
			{
				grp_putblk(gbufx,y1+y,gbuflen,1, (char*)gbuf, DrawNORMAL);
				// grp_putblk(gbufx,Y0-y,gbuflen,1, (char*)gbuf2, DrawNORMAL);
			}
		}
	}
	deci h,l,s;
	rgb_hls(getR(col),getG(col),getB(col),&h,&l,&s);
	drawcircle(l);
}
#endif

/*--------------------------------------------------------*/
/*          HLS三角形＆色相グラデーションの表示           */
/*--------------------------------------------------------*/

void drawHLStriangle(int x1,int y1,int xlen,int ylen,deci h)
{
#if TRIMETHOD==0
	grboxfill(x1,y1,xlen,ylen,32767,DrawNORMAL);
	deci h,l,s;
	rgb_hls(getR(col),getG(col),getB(col),&h,&l,&s);
	int iy;
	for (iy=0; iy<ylen;iy++)
	{
		if (ylen-1 > 0)
			l = (ID(ylen-1-iy)+FD(0.5)) / (ylen-1);
		else
			l = ID(1);
		int rightx;
		rightx = DI(xlen *
		            DivDeci(ID(ylen)/2-_abs(ID(iy)+FD(0.5)-ID(ylen)/2),
		                    ID(ylen)/2))
		         - 1;
		if (rightx<0) rightx=0;
		int gbuflen = 0, gbufx;
		short int gbuf[512];
		int ix;
		for (ix=0; ix<=rightx; ix++)
		{
			if (rightx>0)
				s = ID(ix) / rightx;
			int r,g,b;
			hls_rgb(h,l,s,&r,&g,&b);
			if (gbuflen == 0)
				gbufx = x1+ix;
			gbuf[gbuflen] = 1024*g+32*r+b;
			gbuflen++;
		}
		if (gbuflen > 0)
			grp_putblk(gbufx,y1+iy,gbuflen,1,(char*)gbuf, DrawNORMAL);
	}
#else
	// xmemcpy(0x104,0x40000+1024*y+x1*2,getds(),(int)colmap,(x2-x1+1)*2);
	int vramseg,vramadrs,vramstep;
	vramseg = (DMgetifonepage() ? 0x10c : 0x104);
	vramadrs = 1024*y1+2*x1+(DMgetifonepage() ? 0 : 0x40000);
	vramstep = 1024;
	short int gbuf[512];
	if (ylen<=1)
		return;
	deci or,og,ob; // S=1,L=0.5 の色
	hls_rgb(h,FD(0.5),FD(1.0), &or,&og,&ob);
	or=ID(or);
	og=ID(og);
	ob=ID(ob);
	deci ylen_h = ID(ylen)/2;
	deci xwidth, xwidth_r;
	xwidth = xlen * DivDeci(FD(0.5), ylen_h),
	xwidth_r = DivDeci(ID(xlen), ylen_h);
	deci gray,gray_r;		// S=0 の無彩色の各R,G,Bの強さと、その変化量
	gray = FD(31.5);
	gray_r = -ID(31)/(ylen-1);
	deci s1r,s1g,s1b,s1r_r,s1g_r,s1b_r;	// S=1 の色と、その変化量
	s1r = s1g = s1b = FD(31.5);
	s1r_r = -DivDeci(ID(31)-or,ylen_h-FD(0.5));
	s1g_r = -DivDeci(ID(31)-og,ylen_h-FD(0.5));
	s1b_r = -DivDeci(ID(31)-ob,ylen_h-FD(0.5));
	int py=y1;
	int iy;
	for (iy=(ylen+1)/2;iy;iy--,
		 xwidth+=xwidth_r,s1r+=s1r_r,s1g+=s1g_r,s1b+=s1b_r,py++,gray+=gray_r)
	{
		int l=_max(1,DI(xwidth));
		deci sr,sg,sb,sr_r,sg_r,sb_r;
		sr=gray,sg=gray,sb=gray;
		sr_r=DivDeci(s1r-sr,xwidth);
		sg_r=DivDeci(s1g-sg,xwidth);
		sb_r=DivDeci(s1b-sb,xwidth);
		//int i;
		//for (i=0; i<l; i++, sr+=sr_r,sg+=sg_r,sb+=sb_r)
		//	gbuf[i] = GRB(sg>>DECIMAL,sr>>DECIMAL,sb>>DECIMAL);
		makeHLSgradline((char *)gbuf,l,sr,sg,sb,sr_r,sg_r,sb_r);
		gbuf[l]=gbuf[l-1];
		gbuf[l+1]=gbuf[l-1];
		// grp_putblk(x1,py,l,1,(char*)gbuf, DrawNORMAL);
		if (DMgetifonepage())
			xmemcpy(vramseg,vramadrs,getds(),(int)gbuf,l*2);
		else
			xmemcpy(vramseg,vramadrs,getds(),(int)gbuf,_min(xlen,l+2)*2);
		vramadrs += vramstep;
		// ghline(x1,x1+l-1,py,GRB(s1g>>DECIMAL,s1r>>DECIMAL,s1b>>DECIMAL),DrawNORMAL);
	}
	if (ylen%2==0)
	{
		xwidth -= xwidth_r, iy=ylen/2;
		s1r-=s1r_r/2,s1g-=s1g_r/2,s1b-=s1b_r/2;
	}
	else
	{
		xwidth -= xwidth_r*2, iy=(ylen-1)/2;
		s1r-=s1r_r,s1g-=s1g_r,s1b-=s1b_r;
	}
	s1r_r = -DivDeci(or,ylen_h-FD(0.5));
	s1g_r = -DivDeci(og,ylen_h-FD(0.5));
	s1b_r = -DivDeci(ob,ylen_h-FD(0.5));
	if (ylen%2==0)
		s1r+=s1r_r/2,s1g+=s1g_r/2,s1b+=s1b_r/2;
	else
		s1r+=s1r_r,s1g+=s1g_r,s1b+=s1b_r;
	xwidth_r = -xwidth_r;
	for (;iy;iy--,
		 xwidth+=xwidth_r,s1r+=s1r_r,s1g+=s1g_r,s1b+=s1b_r,py++,gray+=gray_r)
	{
		int l=_max(1,DI(xwidth));
		deci sr,sg,sb,sr_r,sg_r,sb_r;
		sr=gray,sg=gray,sb=gray;
		sr_r=DivDeci(s1r-sr,xwidth);
		sg_r=DivDeci(s1g-sg,xwidth);
		sb_r=DivDeci(s1b-sb,xwidth);
		makeHLSgradline((char *)gbuf,l,sr,sg,sb,sr_r,sg_r,sb_r);
		gbuf[l]=gbuf[l-1];
		gbuf[l+1]=gbuf[l-1];
		// int i;
		// for (i=0; i<l; i++, sr+=sr_r,sg+=sg_r,sb+=sb_r)
		//	gbuf[i] = GRB(sg>>DECIMAL,sr>>DECIMAL,sb>>DECIMAL);
		if (DMgetifonepage())
			xmemcpy(vramseg,vramadrs,getds(),(int)gbuf,l*2);
		else
			xmemcpy(vramseg,vramadrs,getds(),(int)gbuf,_min(xlen,l+2)*2);
		vramadrs += vramstep;
		// grp_putblk(x1,py,l,1,(char*)gbuf, DrawNORMAL);
		// ghline(x1,x1+l-1,py,GRB(s1g>>DECIMAL,s1r>>DECIMAL,s1b>>DECIMAL),DrawNORMAL);
	}
#endif
}

void drawHgradation(int x1,int y1,int xlen,int ylen)
{
	if (ylen>xlen)
	{
		int iy;
		for (iy=0; iy<ylen; iy++)
		{
			deci h;
			h = (ID(ylen-1-iy)+FD(0.5)) / (ylen-1);
			int r,g,b;
			hls_rgb(h,FD(0.5),FD(1.0),&r,&g,&b);
			ghline(x1,x1+xlen-1,y1+iy,r*32+g*1024+b,DrawNORMAL);
		}
	}
}

/*--------------------------------------------------------*/
/*                色空間表示メニューの定義                */
/*--------------------------------------------------------*/

/*
enum {
	itemColList=0,
	itemColSpace, itemColSpace2, itemColSpace3,
	itemH,itemS,itemV
};
*/

#define	ITM(n)		colspcmenu_buttons[n]
#define	BAR(id)		menu_scrollbar(&colspcmenu,id)
#define	BARVARP(p)	menu_scrollbar_getvar(p)
#define	BARVAR(n)	menu_scrollbar_getvar(menu_scrollbar(&colspcmenu,n))
static void barmove_H(),barmove_LS();
static void disp_colspcmenu(), erase_colspcmenu();

#include "colspace.md"

static bool menu2OK = NO; // disp_colspcmenu() は呼び出し済みか
static bool colspc2;	// 色空間２（たとえばＨバー）を表示しているかどうか

static void draw_cross(int x, int y)
{
	page_menu();
	int c;
	if (DMgetifonepage())
		c = menu_plt(White);
	else
		c = menu_plt(Black);
	ghline(x-5,x+5,y,c,DrawXOR);
	ghline(x-2,x+2,y,c,DrawXOR);
	gvline(x,y-5,y+5,c,DrawXOR);
	gvline(x,y-2,y+2,c,DrawXOR);
	if (DMgetifonepage())
		c = menu_plt(DarkGray);
	else
		c = menu_plt(White);
	ghline(x-2,x+2,y,c,DrawXOR);
	gvline(x,y-2,y+2,c,DrawXOR);
}

/* Ｈグラデーションバーのカーソルの表示／消去 */

static bool Hcsr_disp = NO;
static int Hcsr_x, Hcsr_y;

static void erase_Hcsr(void)
{
	if (!Hcsr_disp)
		return;
	draw_cross(Hcsr_x,Hcsr_y);
	Hcsr_disp = NO;
}

static void disp_Hcsr(deci h)
{
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(&colspcmenu, itemColSpace2, &ix, &iy, &ixlen, &iylen);
	int tx,ty;
	tx = ix + ixlen/2;
	ty = iy + (iylen-1) - DI((iylen-1) * h);
	if (Hcsr_disp && Hcsr_x==tx && Hcsr_y==ty)
		return;
	if (Hcsr_disp)
		erase_Hcsr();
	draw_cross(tx,ty);
	Hcsr_x = tx;
	Hcsr_y = ty;
	Hcsr_disp = YES;
}

/* Ｌ，Ｓカーソルの表示／消去 */

static bool LScsr_disp = NO;
static int LScsr_x,LScsr_y;

static void erase_LScsr(void)
{
	if (!LScsr_disp)
		return;
	draw_cross(LScsr_x,LScsr_y);
	LScsr_disp = NO;
}

static void disp_LScsr(deci l,deci s)
{
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(&colspcmenu, itemColSpace, &ix, &iy, &ixlen, &iylen);
	int tx,ty;
	ty = iy + ((iylen-1) * (DUNIT-l) + DUNIT/2) / DUNIT;
	tx = ix + DI(DI((ixlen-1) * (ID(1)/2-_abs(l-ID(1)/2))*2) * s);
	if (LScsr_disp && LScsr_x==tx && LScsr_y==ty)
		return;
	if (LScsr_disp)
		erase_LScsr();
	draw_cross(tx,ty);
	LScsr_x = tx;
	LScsr_y = ty;
	LScsr_disp = YES;
}

/* 色空間メニューの表示・消去 */

static void disp_HLStriangle_hole(int x1,int y1,int xlen,int ylen)
{
	if (ylen<=1)
		return;
	deci ylen_h = ID(ylen)/2;
	deci xwidth, xwidth_r;
	xwidth = xlen * DivDeci(FD(0.5), ylen_h),
	xwidth_r = DivDeci(ID(xlen), ylen_h);
	int py=y1;
	int iy;
	for (iy=(ylen+1)/2;iy;iy--,xwidth+=xwidth_r,py++)
	  { int l=_max(1,DI(xwidth)); ghline(x1,x1+l-1,py,0,DrawNORMAL); }
	if (ylen%2==0)
		xwidth -= xwidth_r, iy=ylen/2;
	else
		xwidth -= xwidth_r*2, iy=(ylen-1)/2;
	xwidth_r = -xwidth_r;
	for (;iy;iy--,xwidth+=xwidth_r,py++)
	  { int l=_max(1,DI(xwidth)); ghline(x1,x1+l-1,py,0,DrawNORMAL); }
}

static void disp_HLStriangle(void)
{
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(&colspcmenu, itemColSpace, &ix, &iy, &ixlen, &iylen);
	int zr = DMimage_getzoomrate();
	page_edit();
	drawHLStriangle(DMgetpage1x(ix),DMgetpage1y(iy),ixlen/zr,iylen/zr,
					(ID(BARVAR(barI0))+FD(0.5)) / 99);
}

static void disp_colspcmenu()
{
	PRINT("disp_colspcmenu begin\n");
	int ix,iy,ixlen,iylen,ix2,iy2,ixlen2,iylen2;
	menu_getbuttonxy(&colspcmenu, itemColList, &ix, &iy, NULL, NULL);
	drawPltList(ix,iy);
	drawPltCsr(pltnum);
	PRINT("パレットリスト表示終了\n");
	menu_getbuttonxy(&colspcmenu, itemColSpace, &ix, &iy, &ixlen, &iylen);
	menu_getbuttonxy(&colspcmenu, itemColSpace2, &ix2, &iy2, &ixlen2, &iylen2);
	colspc2 = (ixlen2 == 0 ? NO : YES);
	int zr = DMimage_getzoomrate();
	if (!DMgetifonepage())
	{
		if (DMmenu2_addbox(ix,iy,ixlen,iylen) != 0)
			goto NOCIRCLE;
		if (colspc2)
			if (DMmenu2_addbox(ix2,iy2,ixlen2,iylen2) != 0)
				goto NOCIRCLE;
	}
	PRINT("menu2 処理終了\n");
	page_menu();
	// grboxfill(ix,iy,ixlen,iylen,0,DrawNORMAL);
	if (colspc2)
	{
		grboxfill(ix2,iy2,ixlen2,iylen2,0,DrawNORMAL);
		grboxline(ix2-1,iy2-1,ixlen2+2,iylen2+2,menu_plt(Black),DrawNORMAL);
	}
	page_edit();
	if (METHOD == 0)
		;
#if 0
		drawHLScircle(DMgetpage1x(ix),DMgetpage1y(iy),
			ixlen/zr,plt_getcode(pltnum));
#endif
	else if (METHOD == 1)
	{
		page_menu();
		disp_HLStriangle_hole(ix,iy,ixlen,iylen);
		PRINT("ホール表示終了\n");
		page_edit();
		disp_HLStriangle();
		drawHgradation(DMgetpage1x(ix2),DMgetpage1y(iy2),ixlen2/zr,iylen2/zr);
		PRINT("グラデーション表示終了\n");
	}
NOCIRCLE:
	page_menu();
	deci h,l,s;
	h = (ID(BARVAR(barI0)) + FD(0.5)) / 99;
	l = (ID(BARVAR(barI1)) + FD(0.5)) / 99;
	s = (ID(BARVAR(barI2)) + FD(0.5)) / 99;
	disp_Hcsr(h);
	disp_LScsr(l,s);
	menu2OK = YES;
	PRINT("disp_colspcmenu end");
}

static void erase_colspcmenu()
{
	PRINT("erase_colspcmenu begin");
	menu2OK = NO;
	erase_LScsr();
	erase_Hcsr();
	if (!DMgetifonepage())
	{
		DMmenu2_deletebox();
		if (colspc2)
			DMmenu2_deletebox();
	}
	erasePltList();
	PRINT("erase_colspcmenu end");
}

/* スクロールバーの更新処理 */

static void barmove_H(void)
{
	if (!menu2OK)
		return;
	deci h,l,s;
	h = (ID(BARVAR(barI0))+FD(0.5)) / 99;
	l = (ID(BARVAR(barI1))+FD(0.5)) / 99;
	s = (ID(BARVAR(barI2))+FD(0.5)) / 99;
	// int r,g,b;
	// hls_rgb(h,l,s,&r,&g,&b);
	plt_setHLS(pltnum, h,l,s);
	makeupPltList();
	erase_Hcsr();
	erase_LScsr();
	disp_HLStriangle();
	disp_Hcsr(h);
	disp_LScsr(l,s);
}

static void barmove_LS(void)
{
	if (!menu2OK)
		return;
	deci h,l,s;
	h = (ID(BARVAR(barI0))+FD(0.5)) / 99;
	l = (ID(BARVAR(barI1))+FD(0.5)) / 99;
	s = (ID(BARVAR(barI2))+FD(0.5)) / 99;
	// int r,g,b;
	// hls_rgb(h,l,s,&r,&g,&b);
	plt_setHLS(pltnum, h,l,s);
	makeupPltList();
	disp_Hcsr(h);
	disp_LScsr(l,s);
}

/*--------------------------------------------------------*/
/*         画面状態に応じて、メニューの定義を調整         */
/*--------------------------------------------------------*/

static void setmenu(void)
{
	BUTTON *bp0 = menu_button(&colspcmenu, itemColSpace);
	BUTTON *bp1 = menu_button(&colspcmenu, itemColSpace2);
	BUTTON *bp2 = menu_button(&colspcmenu, itemColSpace3);
	if (METHOD == 0)
	{
		*bp0 = notHLSsubbutton[0];
		menu_button_setid(bp0,itemColSpace);
		*bp1 = notHLSsubbutton[1];
		menu_button_setid(bp1,itemColSpace2);
		*bp2 = notHLSsubbutton[2];
		menu_button_setid(bp2,itemColSpace3);
	}
	else
	{
		*bp0 = HLSsubbutton[0];
		menu_button_setid(bp0,itemColSpace);
		*bp1 = HLSsubbutton[1];
		menu_button_setid(bp1,itemColSpace2);
		*bp2 = HLSsubbutton[2];
		menu_button_setid(bp2,itemColSpace3);
	}
}

/*--------------------------------------------------------*/
/*          色空間内を直接クリックしたときの処理          */
/*--------------------------------------------------------*/

static void touchLStriangle(int ax, int ay)
{
	deci h,l,s;
	h = (ID(BARVAR(barI0))+FD(0.5)) / 99;
	int ixlen,iylen;
	menu_getbuttonxy(&colspcmenu,itemColSpace,NULL,NULL,&ixlen,&iylen);
	l = (ID(iylen-1-ay)+FD(0.5)) / (iylen-1);
	deci width = ixlen * (FD(0.5)-_abs(l-FD(0.5))) * 2;
	if (width == 0)
		s = 0;
	else if (ID(ax) <= width)
		s = DivDeci(ID(ax),width);
	else
		s = FD(1.0);
	// int r,g,b;
	// hls_rgb(h,l,s,&r,&g,&b);
	plt_setHLS(pltnum, h,l,s);
	makeupPltList();
	disp_LScsr(l,s);
	menu_scrollbar_setvar(BAR(barI0),_lim(DI(99 * h),0,99));
	menu_scrollbar_setvar(BAR(barI1),_lim(DI(99 * l),0,99));
	menu_scrollbar_setvar(BAR(barI2),_lim(DI(99 * s),0,99));
}

static void touchHgrad(int ax,int ay)
{
	deci h,l,s;
	int r,g,b;
	l = (ID(BARVAR(barI1))+FD(0.5)) / 99;
	s = (ID(BARVAR(barI2))+FD(0.5)) / 99;
	int iylen;
	menu_getbuttonxy(&colspcmenu,itemColSpace2,NULL,NULL,NULL,&iylen);
	h = (ID(iylen-1-ay)+FD(0.5)) / (iylen-1);
	plt_setH(pltnum, h);
	// plt_setcode(pltnum, GRB(g,r,b));
	menu_scrollbar_setvar(BAR(barI0),_lim(DI(99 * h),0,99));
	menu_scrollbar_setvar(BAR(barI1),_lim(DI(99 * l),0,99));
	menu_scrollbar_setvar(BAR(barI2),_lim(DI(99 * s),0,99));
	makeupPltList();
	erase_Hcsr();
	erase_LScsr();
	disp_HLStriangle();
	disp_Hcsr(h);
	disp_LScsr(l,s);
}

void commandColspace()
{
	PRINT("COLSPACE begin\n");
	setmenu();	// 画面状態に応じて、メニューの定義を調整する
	PRINT("setmenu end\n");
	deci h,l,s;
	plt_getHLS(pltnum, &h,&l,&s);
	menu_scrollbar_setvar(BAR(barI0),_lim(DI(99 * h),0,99));
	menu_scrollbar_setvar(BAR(barI1),_lim(DI(99 * l),0,99));
	menu_scrollbar_setvar(BAR(barI2),_lim(DI(99 * s),0,99));
	PRINT("scrollbar_setvar end\n");
	menu_disp(&colspcmenu);
	PRINT("menu_disp end\n");
	int btn1_area = -1;
	int _preax=-1,_preay=-1;
	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; int ax,ay; SCROLLBAR *sbarp;
			btn1_area = a = menu_where(ms.x,ms.y,&colspcmenu, &ax,&ay,&sbarp);
			switch (a)
			{
			case itemMoveMenu:
				menu_move();
				break;
			case itemSelector:
				menu_touchselector(&colspcmenu);
				break;
			case itemScrollBar:
				menu_touchscrollbar(sbarp, ax,ay);
				break;
			case itemColList:
				drawPltCsr(pltnum);	// erase
				pltnum = ax/16 + (ay/16)*4;
				drawPltCsr(pltnum);	// draw
				curcol = plt_getcode(pltnum);
				{
					deci h,l,s;
					plt_getHLS(pltnum,&h,&l,&s);
					menu_scrollbar_setvar(BAR(barI0),_lim(DI(99 * h),0,99));
					menu_scrollbar_setvar(BAR(barI1),_lim(DI(99 * l),0,99));
					menu_scrollbar_setvar(BAR(barI2),_lim(DI(99 * s),0,99));
					erase_Hcsr();
					erase_LScsr();
					disp_HLStriangle();
					disp_Hcsr(h);
					disp_LScsr(l,s);
				}
				break;
			case itemColSpace:
				touchLStriangle(ax,ay);
				break;
			case itemColSpace2:
				touchHgrad(ax,ay);
				break;
			}
			_preax=ax,_preay=ay;
		}
		else if (ms.btn1 == ON)
		{
			int ix,iy,ixlen,iylen;
			int ax,ay;
			if (btn1_area == itemColSpace)
			{
				menu_getbuttonxy(&colspcmenu,itemColSpace,&ix,&iy,&ixlen,&iylen);
				ax = _lim(ms.x-ix,0,ixlen-1);
				ay = _lim(ms.y-iy,0,iylen-1);
				touchLStriangle(ax,ay);
			}
			else if (btn1_area == itemColSpace2)
			{
			   menu_getbuttonxy(&colspcmenu,itemColSpace2,&ix,&iy,&ixlen,&iylen);
				ax = _lim(ms.x-ix,0,ixlen-1);
				ay = _lim(ms.y-iy,0,iylen-1);
				if (ax!=_preax || ay!=_preay)
					touchHgrad(ax,ay);
			}
			_preax=ax,_preay=ay;
		}
		else
			btn1_area = -1;
		if (ms.btn2 == OFFON)
		{
			int a;
			a = menu_where(ms.x,ms.y,&colspcmenu, NULL,NULL,NULL);
			if (a == OutOfMenu)
			{
				int px,py;
				px = DMimage_getx(ms.x),  py = DMimage_gety(ms.y);
				drawPltCsr(pltnum);	// erase
				plt_setcode(pltnum, EIMpoint(px,py));
				makeupPltList();
				drawPltCsr(pltnum);	// draw
				{
					deci h,l,s;
					plt_getHLS(pltnum,&h,&l,&s);
					menu_scrollbar_setvar(BAR(barI0),_lim(DI(99 * h),0,99));
					menu_scrollbar_setvar(BAR(barI1),_lim(DI(99 * l),0,99));
					menu_scrollbar_setvar(BAR(barI2),_lim(DI(99 * s),0,99));
					erase_Hcsr();
					erase_LScsr();
					disp_HLStriangle();
					disp_Hcsr(h);
					disp_LScsr(l,s);
				}
			}
			else
				break;
		}
	}
exitloop:
	menu_erase();
end:
	PRINT("COLSPACE end\n");
	return;
}



void colspc_debugmsg(char *buf)
{
	#ifdef DEBUG
		sprintf(buf,"(colspc: [%08x])\n",HLScomments[3].DEBUG_M(dspfunc));
	#else
		buf[0]=0;
	#endif
}


