/****************************************************************************/
/* TEXT MENU-BAR SYSTEM for X68000 V1.90 Copyright (C) 1991-94 by AIG-SOFT  */
/****************************************************************************/
/* '94/02/21 V1.80 操作キー設定機能削除 */
/* '94/09/28 V1.90 周り枠描画 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defines.h"
#include "menubar.h"
#include "aigtext.h"
#include "ascreen.h"
#include "akey.h"
#include "skey.h"
#include "amacro.h"

static unsint cols[9];	/* 色コードバッファー */

/****************************************************************************/

static int key_play(int ky,int n,int *sp,_BAR_DATA *bdata)
{
	switch (ky) {
	    case SKleft:
	    case SKt4: /* cursor left */
		if (bdata->ex_left && *sp==1) return(2); /* left out */
		(*sp)--;
		if (*sp==0) *sp=(bdata->floop? n:1);
		return(1);
	
	    case SKright:
	    case SKt6: /* cursor right */
		if (bdata->ex_right && *sp==n) return(3); /* right out */
		(*sp)++;
		if (*sp>n) *sp=(bdata->floop? 1:n);
		return(1);
	
	    case SKhome: /* top point */
		*sp=1;
		return(1);
	
	    case SKdel: /* end point */
		*sp=n;
		return(1);
	}
	return(0);
}

/****************************************************************************/

static int jump_key(ky,n,msatr,fdirect)
int ky,n,msatr[],fdirect;
{
unint i;
	ky=toupper(ky);
    	if (fdirect) { /* direct key jump mode */
    		for (i=1;i<=n;i++) {
    			if ((msatr[i]&0xff)==ky) return(i);
    		}
    	} else {
        	if (ky>='1' && ky<='9') {
        		ky-='0';
        		if (ky<=n) return(ky);
        	}
        	else
        	if (ky>='A' && ky<='Z') {
        		ky-=('A'-10);
        		if (ky<=n) return(ky);
        	}
        }
	return(0);
}

/****************************************************************************/

static void set1(x,y,ms,msatr,mlen,sel,bdata,colors)
int x,y,msatr,mlen,sel;
unchar *ms;
_BAR_DATA *bdata;
MCOLORS *colors;
/* mlen>0:等配分モードでの１項目最大長さ , <=0:不等配分モードでの項目左スペース量 */
{
int c,l,l2,x1,x2;
unchar a[DISPX+1],b[DISPX*2+1];
	/* sel */
	/* 入力：0=normal , 1=select , 2=決定 */
	
	/* 内部変換 */
	/* 3=特殊色１ , 4=特殊色２ , 5=特殊色２select , 6=特殊色２決定 */
	/* 7=non select normal , 8=non select select */
	
	if ((bdata->md_non)&&(msatr&BIT8)) { /* non select */
		sel+=7;
	} else {
		if (bdata->md_spcol) { /* 特殊色有効モード */
			if (msatr&BIT10) sel+=4;
			if ((msatr&BIT9) && sel==0) sel=3;
		}
	}
	
	B_LOCATE(x,y); /* 座標設定 */
	x1=x;
	c=cols[sel]; /* 項目色選択 */
	EX_COLOR(c);
	
	if (mlen) { /* 等配分／固定幅配分モード時 */
		jnstrcpy(b,ms,mlen);
		ms=b;
		
		x2=klen2(ms);	/* 見た目の長さ */
		l=mlen-x2;	/* 見た目の長さの差 */
		if (bdata->md_mes) { /* center/right */
			if (bdata->md_mes==1) {l2=l; l/=2; l2-=l;} /* center */
			/* メッセージ長がmlenに満たないときの処理 */
			if (l>0) { /* 前にスペースを表示する */
				string(a,' ',l);
				if (bdata->md_revlen==0) {
					EX_COLOR(colors->back);
					x1+=l;
				} else x2+=l;
				EX_PRINT2(8,a);
				EX_COLOR(c);
			}
			l=(bdata->md_mes==1? l2:0);
		} /* leftの時は何もしない */
		
		EX_PRINT2(8,ms);
		x2+=x1;
		
		/* メッセージ長がmlenに満たないときの処理 */
		if (l>0) { /* 後ろにスペースを表示する */
			string(a,' ',l);
			if (bdata->md_revlen==0) EX_COLOR(colors->back);
			else x2+=l;
			EX_PRINT2(8,a);
		}
		
	} else { /* 項目幅配分モード時 */
		EX_PRINT2(8,ms);
		x2=x1+klen2(ms);
	}
	if (bdata->cwaku && (sel==1||sel==5||sel==8)) { /* メッセージ枠囲み */
		waku3(x1*8,y*16,x2*8-1,y*16+15,colors->waku,bdata->wptrn);
	}
}

/****************************************************************************/
/*	x,y	: メニューバー左端座標（テキスト）
	eex	: メニューバー右端座標（テキスト）
	sp 	: 初期セレクトポイント：（１〜ｎ）
	   	  sp<0のときは-sp=ポイント、rcode[0]=第一入力キー
	n	: 項目数
 	ms[]	: メニューバー項目
		  ms[0]="" : タイトルはbdata.title
		  ms[0]<>"": ms[0]がタイトル
	msatr[]	: 項目属性
		  bit0-7 : ダイレクトセレクトキー
		  bit8   : non select
		  bit9   : 特殊色１を使う
		  bit10  : 特殊色２を使う
	bdata	: メニューバーデータ
	colors	: 色情報
		  bdataとcolorsは本体をｽﾀｯｸに積まないようにするためｱﾄﾞﾚｽ渡しにする
		  ｽﾀｯｸに本体を積むとｽﾀｯｸを多く消費し,ｽﾋﾟｰﾄﾞも低下するのでこれを防ぐためである
	wget	: メニューバー下のﾃｷｽﾄ画面を待避するﾜｰｸｴﾘｱ変数のｱﾄﾞﾚｽ
	rcode[BRCODE] : リターン時のメニューバー状態情報
		  [0]=return key , [1]=rsx[sp] , [2]=sp , [3]=mouse-x
		  またsp<0のときは[0]は第一入力キーコードになる
*/
/****************************************************************************/

boxsub(int sx,int sy,int ex,_BAR_DATA *bdata,MCOLORS *colors)
/* メニューバー外枠表示サブルーチン */
{
	if (bdata->cwaku) {
		ColorTextGraph(txbox,colors->tale,sx*8,sy*16,(ex-sx+1)*8,16,0xffff);
	}
}

/****************************************************************************/

int menubar(x,y,eex,sp,n,ms,msatr,bdata,colors,wget,rcode)
int *x,*y,*eex,sp,n,msatr[],rcode[BRCODE];
unchar *ms[],*(*wget);
_BAR_DATA *bdata;
MCOLORS *colors;
{
int lx,ly,lc,cur,fkey=0,fcur=1,ky,ret,mlen,i,msc,mcx,mcy;
int ssp,sx,sy,ex,tx,rsx[DISPX+1],btn=0,fmouse,fms;

	if (n>TWIDTH(&ly)) return(-10010); /* 項目数が多すぎる */
	
	lc=EX_COLOR(-1);
	cursor(&lx,&ly); /* cursor save */
	cur=curmode(bdata->cursor);
	fms=fmouse=bdata->mouse;
	fmouse&=(~BIT7); /* BIT7を消す */
	fms&=BIT7; /* BIT7だけを取り出す */
	
	/* パラメーター計算 */
	mlen=bar_width(x,y,eex,n,ms,bdata,&tx,rsx);
	if (mlen<0) { /* parameter error */
		ret=mlen-10000; /* -10001/-10002 */
		goto BEND2;
	}
	
	/* 省メモリーのため */
	sx=*x;
	sy=*y;
	ex=*eex;
	cols[0]=colors->menues;
	cols[1]=colors->sel_menues;	cols[2]=colors->cr_menues;
	cols[3]=colors->menues1;	cols[4]=colors->menues2;
	cols[5]=colors->sel_menues2;	cols[6]=colors->cr_menues2;
	cols[7]=colors->non_menues;	cols[8]=colors->nsl_menues;
	
	/* 第一入力キー判定 */
	if (sp<0) {sp=-sp; fkey=rcode[0];}
	
	if (bdata->remake==0) { /* make menubar */
		/* 画面待避 */
		*wget=gettext2(sx,sy,ex,sy);
		if (*wget==NULL) { /* memory can't get error */
			ret=-10003;
			goto BEND;
		}
		
		/* とりあえず下地のバーを描く */
		fill_area(sx*8,sy*16,(ex-sx+1)*8,16,colors->back);
		
		/* タイトル表示 */
		if (tx>=0) {
			EX_COLOR(colors->title);
			B_LOCATE(tx,sy);
			EX_PRINT2(8,ms[0]);
		}
		if (fmouse) rcode[3]=-1; /* 前回マウスＸ座標初期化 */
	}
	if (bdata->remake!=1) { /* 最初または項目再表示モードの時のみ */
		for (i=1;i<=n;i++) set1(rsx[i],sy,ms[i],msatr[i],mlen,0,bdata,colors);
		boxsub(sx,sy,ex,bdata,colors);
		kflush(); /* キーボードバッファークリア */
	}
	
	if (fmouse) { /* マウス初期化 */
		if (fmouse==3) { /* マウスカーソル初期設定なし */
		    mcx=MS_CURGT();
		    mcy=mcx&0xffff;
		    mcx>>=16;
		    msc=MS_STAT();
		} else {
		  int cx,cy;
		    cy=sy*16+8;
		    if (bdata->remake==0) {
			cx=sx*8+4;
		    } else {
			cx=(rcode[3]>>16)*8+4;
		    }
		    msc=ms_set(&mcx,&mcy,cx,cy,1);
		}
	}
	
	/* メイン */
	while (1) {
		/* 選択中項目反転表示 */
		if (fcur) {
			set1(rsx[sp],sy,ms[sp],msatr[sp],mlen,1,bdata,colors);
			boxsub(sx,sy,ex,bdata,colors);
			ssp=sp;
		}
		if (fcur==2) fkey=SKcr; /* セレクト＆リターン */
		fcur=0;
		
		if (fkey) {ky=fkey; fkey=0;} /* 第１入力キー */
		else {
			do {
				if (fmouse) btn=mson();
				ky=inkey2(1,btn);
				if (ky==0 && fmouse) { /* マウス */
					ky=bar_mouse(btn,&ssp,sy,n,mlen,tx,rsx,ms,&rcode[3],fms);
					switch (ky) { /* 特殊操作 */
						case -1: /* move */
							goto BAR_MOVE;
						case 1: /* point move */
							goto OPERATION;
					}
					/* ESC/CRも帰って来る */
				}
			} while (ky==0);
		}
		
		/* キーごとの処理 */
		/* 緊急脱出キー */
		for (i=0;i<bdata->exits;i++) {
			if (keycmp(ky,bdata->exit[i])) {
				ret=-sp;
				goto BRETURN;
			}
		}
		
		/* エスケープ */
		if ((ky&0xff)==ESC || ky==SKbrk) {
			ret=0;
			break;
		}
		
		/* リターン */
		if (bdata->downret) {
			if (ky==SKdown||ky==SKt2) ky=CR;
		}
		if ((ky&0xff)==CR) {
			if (bdata->md_non && (msatr[sp]&BIT8)) { /* non select */
				beep();
				continue;
			}
			set1(rsx[sp],sy,ms[sp],msatr[sp],mlen,2,bdata,colors);
			ret=sp;
			break;
		}
		
		if (ky==SKtou && CheckMESXY()) { /* 登録：メニューバー移動 */
		    BAR_MOVE:;
			ky=move_area(&sx,&sy,&ex,&sy
				,wget,fmouse
				,bdata->startx,bdata->starty,bdata->endx,bdata->endy);
			if (ky==-1) beep(); /* can't move */
			continue;
		}
		
		ret=key_play(ky,n,&ssp,bdata);
		if (ret==2 || ret==3) { /* left/right exit */
			/* 元の色に戻す */
			set1(rsx[sp],sy,ms[sp],msatr[sp],mlen,0,bdata,colors);
			ret=-1000-ret;
			break;
		}
		if (ret==0) {
			/* direct key jump */
			ret=jump_key(ky,n,msatr,bdata->direct);
			if (ret) {
				ssp=ret;
				if (bdata->direct==2) fcur=2; /* direct select & return */
			}
		}
		
		/* sp move */
		if (sp!=ssp) { /* selector */
		    OPERATION:;
			/* 元の色に戻す */
			set1(rsx[sp],sy,ms[sp],msatr[sp],mlen,0,bdata,colors);
			sp=ssp;
			fcur=1;
		}
	}
	boxsub(sx,sy,ex,bdata,colors);
    BRETURN:;
	if (fmouse==1) ms_reset(msc,mcx,mcy); /* マウス後処理 */
    BEND:;
	/* 座標渡し */
	*x=sx;
	*y=sy;
	*eex=ex;
	
	/* status */
	rcode[0]=ky;
	rcode[1]=rsx[sp];
	rcode[2]=sp;
    BEND2:;
	curmode(cur);
	B_LOCATE(lx,ly);
	EX_COLOR(lc);
	return(ret);
}

/****************************************************************************/
