/****************************************************************************/
/* TIME INPUT SYSTEM for X68000 V1.20 Copyright (C) 1991,94 by AIG-SOFT	    */
/****************************************************************************/
/* V1.2 : '94/08/16 : 僉乕擖椡娭悢奜晹壔 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "defines.h"
#include "aigtext.h"
#include "ascreen.h"
#include "akey.h"
#include "skey.h"

/****************************************************************************/
/* 僉乕愝掕昞
	俠俿俼俴亅俙			慜偺崁栚傊
	俠俿俼俴亅俛
	俠俿俼俴亅俠乛俛俼俤俙俲	擖椡拞抐
	俠俿俼俴亅俢			崱擔偺帪崗擖椡
	俠俿俼俴亅俤
	俠俿俼俴亅俥			屻偺崁栚傊
	俠俿俼俴亅俧乛俢俤俴		侾暥帤嶍彍
	俠俿俼俴亅俫乛俛俽		億僀儞僩慜侾暥帤嶍彍
	俠俿俼俴亅俬乛俿俙俛		屻傠偺崁栚傊乮亖俠俿俼俴亅俥乯
	俠俿俼俴亅俰
	俠俿俼俴亅俲			億僀儞僩屻慡嶍彍
	俠俿俼俴亅俴
	俠俿俼俴亅俵乛腴		擖椡
	俠俿俼俴亅俶
	俠俿俼俴亅俷
	俠俿俼俴亅俹			昩乮暘乯擖椡傊
	俠俿俼俴亅俻乛俫俷俵俤		帪擖椡傊
	俠俿俼俴亅俼
	俠俿俼俴亅俽
	俠俿俼俴亅俿
	俠俿俼俴亅倀
	俠俿俼俴亅倁
	俠俿俼俴亅倂
	俠俿俼俴亅倃
	俠俿俼俴亅倄乛俠俴俼		擖椡傗傝捈偟
	俠俿俼俴亅倅
	仺				侾暥帤嵍堏摦
	仼				侾暥帤塃堏摦
	仾
	伀
	俤俽俠
	俽俹俙俠俤			億僀儞僩崁栚嶍彍亄仺
*/
/****************************************************************************/
/* 撪晹曄悢 */

static	int	nx=0;		/* 億僀儞僞 */
static	unchar	nc[6]={0,0,0,0,0,0};	/* 擖椡僶僢僼傽乕 */
static	int	cx[6];		/* 僇乕僜儖埵抲 */
static	int	cn='_';		/* 嬻敀僉儍儔僋僞乕 */
static	int	fsec;		/* 昩桳傝僼儔僌 */
static	int	mc=-1;		/* AM/PM昞帵嵗昗 寭 俀係帪惂僼儔僌(-1=24) */
static	int	fam=1;		/* 1=AM , 0=PM */
#define WILD	'?'		/* 曄偊傞帪偼ctrl_operate()撪偺僉乕僐乕僪傕曄峏 */
/*	   HH / MM / SS  AM
	nx 01   23   45  mc
	nc
    x+	cx
*/
/****************************************************************************/

static int calc_sub(int xn)
{
int c1,c2;
	c1=nc[xn];
	if (c1==WILD) return(-1); /* wildcard */
	if (c1>0) c1=(c1-'0')*10;
	c2=nc[xn+1];
	if (c2>0) c2-='0';
	return(c1+c2);
}

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

static int format_read(unchar *fmt,unchar *format)
/* 擖椡僼僅乕儅僢僩夝愅 */
/*	"___帪 __暘 __昩 AM"
	"???:??:??"
	侾暥帤栚丗嬻偒埵抲暥帤
	俀暥帤栚埲崀昞帵暥帤楍
	偨偩偟丄嬻偒埵抲暥帤偲摨偠強偼帪崗擖椡埵抲偵側傞
	嵟掅係売強丄昩傕擖椡偡傞帪偼俇売強偁傞偙偲丅乮帪暘昩偦傟偧傟俀寘偢偮丅乯
	嬻偒埵抲暥帤'?'偼摿偵昞帵偺嵺偵僗儁乕僗偵抲偒姺偊傜傟傞丅
	僗儁乕僗偦偺傕偺偼巊傢側偄曽偑傛偄丅
	娍帤敾掕偼偟偰偄側偄偺偱丄娍帤俀僶僀僩栚偵偔傞壜擻惈偺偁傞暥帤偼
	巊傢側偄曽偑傛偄丅乮偟偨偑偭偰婰崋傪巊偆丅乯
	僼僅乕儅僢僩拞偵"AM"偑偁傞帪偼侾俀帪惂偵側傞丅柍偄帪偼俀係帪惂偱偁傞丅乮彫暥帤晄壜乯
*/
{
int i=0,c,cn,cnn=0;
	cn=format[i];
	if (cn==0) return(-1); /* format error */
	
	do {
		c=format[++i];
		if (c==cn) {
			if (cnn>=6) return(-2); /* 嬻偒埵抲暥帤偑懡偡偓傞 */
			cx[cnn++]=i-1;
			if (cn=='?') c=' ';
		}
		fmt[i-1]=c;
		if (i>40) return(-3); /* too long */
	} while (c!=0);
	
	if (cnn<4||cnn==5) return(-4); /* 嬻偒埵抲暥帤偑懌傝側偄 */
	
	fsec=0; /* 昩側偟 */
	if (cnn==6) fsec=1; /* 昩桳傝 */
	
	/* 侾俀帪惂敾掕 */
	mc=-1; /* 俀係帪惂 */
	i=kstrchar(format,'A'); /* "AM"search */
	if (i==-1) i=kstrchar(format,'P'); /* 側偄偲偒偼"PM"search */
	if (i>=0) {
		if (format[i+1]=='M') mc=i-1; /* 侾俀帪惂乮亅侾偼愭摢偺嬻偒堦暥帤偺暘乯*/
	}
	
	return(cn=='?'? ' ':cn);
}

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

static void time_disp(int x,int y,int mode)
/* 昞帵仌僇乕僜儖堏摦 */
/* mode : 0=not use , 1=point move only , 2=帪暘昩彂偒姺偊桳傝 , 3=AM/PM曄峏桳傝 */
{
int i,c;
	if (mode==3) {
		B_LOCATE(x+mc,y);
		EX_PRINT2(8,fam? "AM":"PM");
	}
	if (mode==2) {
		for (i=0;i<=(fsec? 5:3);i++) {
			B_LOCATE(x+cx[i],y);
			c=nc[i];
			EX_PUTC2(8,c==0? cn:c); /* wildcard偼c */
		}
	}
	B_LOCATE(x+cx[nx],y);
}

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

static int check_all()
{
	/* 帪偼俀係帪惂偺帪偼侽侽偱傕椙偄 */
	return(!(mc>=0 && nc[0]==0 && nc[1]==0));
}

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

static int enter_time(int c,int mode)
/* 悢帤擖椡 */
{
	switch (nx) { /* 崱偄傞埵抲偵傛偭偰摦嶌偑堘偆 */
		case 0: /* 帪丗侾侽偺埵 */
			if (c>(mc==-1? '2':'1')) {
				/* 俀係帪惂偱俀丄侾俀帪惂偱侾埲忋偺帪偼侾偺埵偵擖傟傞 */
				nc[nx++]=0;
			} /* 偦傟埲奜偼偲傝偁偊偢侾侽偺埵偵擖傟傞 */
			nc[nx++]=c;
			break;
		case 1: /* 帪丗侾偺埵 */
			if (
			    (c>(mc==-1? '2':'1'))
				/* 俀係帪惂偱俀丄侾俀帪惂偱侾埲忋偺帪 */
			 || (mc>=0 && nc[0]=='1' && c>'2')
				/* 侾俀帪惂偱侾侽帪戜偺帪 */
			 || (nc[0]=='2' && c>='4')
				/* 俀係帪惂偱俀侽帪戜偺帪 */
			) {
				/* 侾侽偺埵傪徚偟偰偐傜擖傟傞 */
				nc[0]=0;
			}
			nc[nx++]=c;
			break;
		
		case 2: /* 暘丗侾侽偺埵 */
			if (c<='6') { /* 0-5偺偲偒 */
				nc[nx++]=c;
				break;
			}
			/* 6埲忋偺帪偼侾偺埵偵擖傟傞 */
		case 3: /* 暘丗侾偺埵 */
			nc[nx]=c;
			if (fsec) nx++;
			else {
				/* fsec==0偺偲偒偼堦斣塃偩偐傜偙傟埲忋摦偐側偄 */
				if ((mode&BIT3)&&check_all()) return(1); /* 帺摦妋掕儌乕僪 */
			}
			break;
		
		case 4: /* 昩丗侾侽偺埵 */
			if (c<='6') { /* 0-5偺偲偒 */
				nc[nx++]=c;
				break;
			}
			/* 6埲忋偺帪偼侾偺埵偵擖傟傞 */
		case 5: /* 昩丗侾偺埵 */
			nc[nx]=c;
			/* 堦斣塃偩偐傜偙傟埲忋摦偐側偄 */
			if ((mode&BIT3)&&check_all()) return(1); /* 帺摦妋掕儌乕僪 */
			break;
	}
	return(0);
}

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

static void time_init(int hour,int min,int sec,int mode)
/* 撪晹弶婜壔 */
{
int i;
time_t ltime;
char *cctime;
	/* 弶婜億僀儞僩偼帪偺埵抲 */
	nx=0;
	/* 擖椡柍偟偵偡傞 */
	for (i=0;i<6;i++) nc[i]=0;
	if (mode&BIT0) { /* 愭峴擖椡 */
		if (hour>=0 && hour<24) { /* 帪 */
			nc[0]=hour/10+'0';
			nc[1]=hour%10+'0';
		} else if (hour==-1) {
			nc[0]=nc[1]=WILD;
		}
		if (min>=0 && min<60) { /* 暘 */
			nc[2]=min/10+'0';
			nc[3]=min%10+'0';
		} else if (min==-1) {
			nc[2]=nc[3]=WILD;
		}
		if (sec>=0 && sec<60) { /* 昩 */
			nc[4]=sec/10+'0';
			nc[5]=sec%10+'0';
		} else if (sec==-1) {
			nc[6]=nc[7]=WILD;
		}
		if (mode&BIT1) nx=3; /* 偙偺偲偒偼暘偺埵抲傊 */
	}
}

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

static void now_init()
/* 崱偺帪崗擖椡 */
{
time_t ltime;
char *cctime;
	time(&ltime);
	cctime=ctime(&ltime);
	/* WED OCT 22 13:15:30 1986\n\0 */
	/* 012345678901234567890123     */
	/* 0         1         2        */
	/* 帪 */
	ltime=(cctime[11]-'0')*10+(cctime[12]-'0');
	if (mc>=0) { /* 侾俀帪惂 */
		fam=1;
		if (ltime==0) ltime=12; /* 侽帪偼侾俀帪 */
		if (ltime>12) {
			fam=0;
			ltime-=12;
		}
	}
	nc[0]=(ltime/10)+'0';
	nc[1]=(ltime%10)+'0';
	/* 暘 */
	nc[2]=cctime[14];
	nc[3]=cctime[15];
	/* 昩 */
	nc[5]=cctime[17];
	nc[6]=cctime[18];
}

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

static int ctrl_operate(int ky,int hour,int min,int sec,int mode)
/* 僐儞僩儘乕儖僐乕僪張棟 亖 撪晹僐乕僪張棟 */
/* 儕僞乕儞抣
	0=not use key or nothing happen
	1=use key : point move only
	2=use key : 彂偒姺偊桳傝
	3=use key : AM/PM曄峏桳傝
*/
{
int i;
	switch (ky) {
		case SKd|0x04: /* ^D : 崱偺帪崗擖椡 */
			now_init();
			return(2);
		
		case SKtab|0x09: /* TAB */
		case SKf|0x06: /* ^F : 崁栚屻傠堏摦 */
			if (nx<=1) {nx=2; return(1);} /* 帪仺暘 */
			if (fsec && nx<=3) {nx=4; return(1);} /* 暘仺昩 */
			return(0);
		
		case SKa|0x01: /* ^A : 崁栚慜堏摦 */
			if (fsec && nx>=4) {nx=2; return(1);} /* 暘仼昩 */
			if (nx>=2) {nx=0; return(1);} /* 帪仼暘 */
			return(0);
		
		case SKhome: /* HOME */
		case SKq|0x11: /* ^Q : 儂乕儉 */
			if (nx==0) return(0);
			nx=0;
			return(1);
		
		case SKp|0x10: /* ^P : 僄儞僪 */
			if (fsec) {
				if (nx==5) return(0);
				nx=5;
			} else {
				if (nx==3) return(0);
				nx=3;
			}
			return(1);
		
		case SKright: /* -> : 億僀儞僩屻傠堏摦 */
			if (fsec) {
				if (nx>=5) return(0);
			} else {
				if (nx>=3) return(0);
			}
			nx++;
			return(1);
		
		case SKleft: /* <- : 億僀儞僩慜堏摦 */
			if (nx==0) return(0);
			nx--;
			return(1);
		
		case SKdel: /* DEL */
		case SKg|0x07: /* ^G : 億僀儞僩埵抲嶍彍 */
			if (nc[nx]==0) return(0);
			nc[nx]=0;
			return(2);
		
		case SKh|0x08: /* ^H */
		case SKbs: /* BS : 億僀儞僩埵抲嶍彍亄慜堏摦 */
			i=nc[nx];
			nc[nx]=0;
			if (nx==0) return(i==0? 0:2);
			nx--;
			return(1+(i!=0));
		
		case SKspc: /* SPC : 億僀儞僩埵抲嶍彍亄屻傠堏摦 */
			i=nc[nx];
			nc[nx]=0;
			if (nx==(fsec? 5:3)) return(i==0? 0:2);
			nx++;
			return(1+(i!=0));
		
		case SKmdiv|'?': /* ? : 儚僀儖僪僇乕僪亄屻傠堏摦 */
			i=nc[nx];
			if (nx==0 || nx==1) {
				nc[0]=nc[1]=WILD;
				nx=2;
			} else
			if (nx==2 || nx==3) {
				nc[2]=nc[3]=WILD;
				if (!fsec) {
					nx=3;
					return(i==WILD? 0:2);
				}
				nx=4;
			} else
			if (fsec && (nx==4 || nx==5)) {
				nc[4]=nc[5]=WILD;
				nx=5;
				return(i==WILD? 0:2);
			}
			return(1+(i!=WILD));
		
		case SKk|0x0b: /* ^K : 億僀儞僩埲崀僋儕傾 */
			for (i=nx;i<(fsec? 5:3);i++) nc[i]=0;
			return(2);
		
		case SKclr: /* CLR */
		case SKy|0x19: /* ^Y : 慡僋儕傾 */
			time_init(hour,min,sec,mode);
			return(2);
		
		case SKa|'A': /* A : AM */
			if (mc==-1) break; /* 俀係帪惂偺帪 */
			fam=1;
			return(3);
		
		case SKp|'P': /* P : PM */
			if (mc==-1) break; /* 俀係帪惂偺帪 */
			fam=0;
			return(3);
	}
	/* 巊梡偝傟偰偄側偄僉乕偺帪 */
	beep();
	return(0);
}

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

int time_input(format,hour,min,sec,mode,kexit,rkey,getchs)
unchar *format;
int *hour,*min,*sec,mode,kexit,*rkey;
int (*getchs)();
/* mode bit 0 : 愭峴擖椡儌乕僪
	bit 1 : 愭峴擖椡偟偨屻 0=帪偺侾侽偺埵偺埵抲傊 , 1=暘偺侾偺埵偺埵抲傊
	bit 2 : 捈慜偺儕僞乕儞忬懺傪嵞尰偟偰嵞奐
	bit 3 : 帺摦妋掕儌乕僪
	bit 4 : 帪崗偑僄儔乕偱傕堦墳抣傪曉偡
*/
{
int x,y,c,cc,h,m,s;
static int finit=0;
static unchar fmt[DISPX*2+1];
	cursor(&x,&y);
	if (finit==0 || (mode&BIT2)==0) {
		/* 弶婜壔 */
		cn=format_read(fmt,format);
		if (cn<0) return(cn); /* format error -1乣-4 */
		time_init(*hour,*min,*sec,mode);
		
		finit=1;
		
		/* 弶婜昞帵 */
		EX_PRINT2(8,fmt);
	}
	time_disp(x,y,2);
	
	/* 擖椡 */
	while (1) {
		c=bstol(getchs(0));
		cc=c&0xff;
		
		if (keycmp(c,kexit)) { /* 嬞媫扙弌偼偙偺僐乕僪偵曄姺 */
			*rkey=c; /* 儕僞乕儞僉乕僐乕僪 */
			return(100);
		}
		
		if (cc==0x03) { /* ^C/BREAK */
			*rkey=c; /* 儕僞乕儞僉乕僐乕僪 */
			return(101);
		}
		if (cc==CR) { /* 儕僞乕儞 */
			*rkey=c; /* 儕僞乕儞僉乕僐乕僪 */
			break;
		}
		
		/* 僐儞僩儘乕儖 */
		if (cc<=' ' || cc=='?' || (mc>=0 && (cc=='A'||cc=='P'))) {
			c=ctrl_operate(c,*hour,*min,*sec,mode);
			if (c!=0) time_disp(x,y,c);
			continue;
		}
		
		/* 捠忢擖椡 */
		if (cc>='0' && cc<='9') { /* 悢帤偺偲偒 */
			c=enter_time(cc,mode);
			time_disp(x,y,2);
			if (c) { /* 帺摦妋掕儌乕僪 */
				*rkey=0;
				break;
			}
		} else beep();
	}
	
	/* 彮偟廋惓 */
	/* 帪暘昩偑侾侽偺埵偩偗 -> 侾偺埵偵擖傟傞 */
	if (nc[1]==0 && nc[0]!=0) {nc[1]=nc[0]; nc[0]=0;}
	if (nc[3]==0 && nc[2]!=0) {nc[3]=nc[2]; nc[2]=0;}
	if (fsec) {
		if (nc[5]==0 && nc[4]!=0) {nc[5]=nc[4]; nc[5]=0;}
	}
	
	/* 帪崗敾掕 */
	h=calc_sub(0);
	if (mc>=0) { /* 侾俀帪惂 -> 俀係帪惂曄姺 */
		if (fam==0) {
			h+=12;
			if (h==24) h=0; /* 俀係帪偼侽帪 */
		}
	}
	m=calc_sub(2);
	s=0; if (fsec) s=calc_sub(4);
	c=check_time(h,m,s);
	if (c==0 || (mode&BIT4)) { /* 僄儔乕偱側偄帪 */
		*hour=h;
		*min=m;
		*sec=s;
	}
	
	/* 嵟屻偵帪崗傪嵞昞帵偡傞 */
	time_disp(x,y,2);
	
	/* 帪崗敾掕僼儔僌偲嫟偵婣傞 */
	return(c);
}

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