/****************************************************************************/
/* DATE 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=4;		/* 億僀儞僞 */
static	unchar	nc[8]={0,0,0,0,0,0,0,0};/* 擖椡僶僢僼傽乕 */
static	int	cx[8];		/* 僇乕僜儖埵抲 */
static	int	cn='_';		/* 嬻敀僉儍儔僋僞乕 */
#define WILD	'?'		/* 曄偊傞帪偼ctrl_operate()撪偺僉乕僐乕僪傕曄峏 */
/*	   YYYY / MM / DD
	nx 0123   45   67
	nc
    x+	cx
*/
/****************************************************************************/

static int format_read(unchar *fmt,unchar *format)
/* 擖椡僼僅乕儅僢僩夝愅 */
/*	"_____擭 __寧 __擔"
	"?????/??/??"
	侾暥帤栚丗嬻偒埵抲暥帤
	俀暥帤栚埲崀昞帵暥帤楍
	偨偩偟丄嬻偒埵抲暥帤偲摨偠強偼擭寧擔擖椡埵抲偵側傞
	昁偢俉売強偁傞偙偲丅乮擭係寘丄寧擔偦傟偧傟俀寘偢偮丅乯
	嬻偒埵抲暥帤'?'偼摿偵昞帵偺嵺偵僗儁乕僗偵抲偒姺偊傜傟傞丅
	僗儁乕僗偦偺傕偺偼巊傢側偄曽偑傛偄丅
	娍帤敾掕偼偟偰偄側偄偺偱丄娍帤俀僶僀僩栚偵偔傞壜擻惈偺偁傞暥帤偼
	巊傢側偄曽偑傛偄丅乮偟偨偑偭偰婰崋傪巊偆丅乯
*/
{
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>=8) 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<8) return(-4); /* 嬻偒埵抲暥帤偑懌傝側偄 */
	return(cn=='?'? ' ':cn);
}

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

static void date_disp(int x,int y,int mode)
/* 昞帵仌僇乕僜儖堏摦 */
/* mode : 0=not use , 1=point move only , 2=彂偒姺偊桳傝 */
{
int i,c;
	if (mode==2) {
		for (i=0;i<8;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 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 check_all()
{
	/* 擭偼侽侽偱傕椙偄 */
	/* 寧擔偼偳偪傜偐擖偭偰偄傟偽偄偄 */
	return (!(	  (nc[4]+nc[5]==0)
			||(nc[6]+nc[7]==0)
	));
}

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

static int enter_date(int c,int mode)
/* 悢帤擖椡 */
{
	switch (nx) { /* 崱偄傞埵抲偵傛偭偰摦嶌偑堘偆 */
		case 0: /* 擭 */
		case 1:
		case 2:
		case 3:
			/* 0乣9傑偱慡偰擖椡壜擻 */
			nc[nx++]=c;
			break;
		
		case 4: /* 寧丗侾侽偺埵 */
			if (c>='2') { /* 2埲忋偺帪偼侾偺埵偵擖傟傞 */
				nc[nx++]=0;
				nc[nx++]=c;
				break;
			}
			if (c=='0') { /* 0偺帪偼侾偺埵傊旘傇 */
				nc[nx++]=0;
				break;
			}
			/* 1偺偲偒 */
			nc[nx++]=c; /* 偲傝偁偊偢侾侽偺埵偵擖傟傞 */
			if (nc[5]>='3') {
				/* 侾偺埵偵俁埲忋偑擖偭偰偄傞帪偼侾偺埵傪徚偡 */
				nc[5]=0;
			}
			break;
		case 5: /* 寧丗侾偺埵 */
			if (c>='3') { /* 3埲忋偺帪偼侾侽偺埵傪徚偟偰偐傜擖傟傞 */
				nc[4]=0;
				nc[nx++]=c;
				break;
			}
			/* 0,1偺偲偒 */
			/* 10偺埵偑侽偱丄侾偺埵傕侽偺帪偼僋儕傾偟偰偟傑偆 */
			if (c=='0' && nc[4]==0) c=0;
			nc[nx++]=c;
			break;
		
		case 6: /* 擔丗侾侽偺埵 */
			if (c>='4') { /* 4埲忋偺帪偼侾偺埵偵擖傟傞 */
				nc[nx++]=0;
				nc[nx]=c; /* 堦斣塃偩偐傜偙傟埲忋摦偐側偄 */
				if ((mode&BIT3)&&check_all()) return(1); /* 帺摦妋掕儌乕僪 */
				break;
			}
			if (c=='0') { /* 0偺帪偼侾偺埵傊旘傇 */
				nc[nx++]=0;
				break;
			}
			/* 1,2,3偺偲偒 */
			if (c=='3' && nc[7]>='2') { /* 3偺偲偒 */
				/* 侾偺埵偵俀埲忋偑擖偭偰偄傞帪偼侾偺埵傪徚偡 */
				nc[7]=0;
			}
			nc[nx++]=c;
			break;
		case 7: /* 擔丗侾偺埵 */
			if (c=='0') { /* 0偺偲偒 */
				if (nc[6]==0) c=0; /* 侾侽偺埵傕侽側傜徚偟偰偟傑偆 */
			}
			if (nc[6]=='3') { /* 侾侽偺埵偑俁偺帪 */
				if (c>='2') nc[6]=0; /* 2埲忋偺帪偼侾侽偺埵傪徚偟偰偐傜擖傟傞 */
			}
			nc[nx]=c; /* 堦斣塃偩偐傜偙傟埲忋摦偐側偄 */
			if ((mode&BIT3)&&check_all()) return(1); /* 帺摦妋掕儌乕僪 */
	}
	return(0);
}

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

static void date_init(int year,int month,int day,int mode)
/* 撪晹弶婜壔 */
{
int i;
time_t ltime;
char *cctime;
	/* 弶婜億僀儞僩偼寧偺埵抲 */
	nx=4;
	/* 擖椡柍偟偵偡傞 */
	for (i=0;i<8;i++) nc[i]=0;
	if (mode&BIT0) { /* 愭峴擖椡 */
		if (year>=0) {
			if (year<100) {
				nc[0]='1';
				nc[1]='9';
				nc[0]=year/10+'0';
				nc[1]=year%10+'0';
			} else {
				nc[0]=year/1000+'0';
				year%=1000;
				nc[1]=year/100+'0';
				year%=100;
				nc[2]=year/10+'0';
				nc[3]=year%10+'0';
			}
		} else if (year==-1) {
			nc[0]=nc[1]=nc[2]=nc[3]=WILD;
		}
		if (month>=1 && month<=12) { /* 寧 */
			if (month>=10) {nc[4]='1'; month-=10;}
			nc[5]=month+'0';
		} else if (month==-1) {
			nc[4]=nc[5]=WILD;
		}
		if (day>=1 && day<=31) { /* 擔 */
			if (day>=10) {nc[6]=day/10+'0'; day%=10;}
			nc[7]=day+'0';
		} else if (day==-1) {
			nc[6]=nc[7]=WILD;
		}
		if (mode&BIT1) nx=7; /* 偙偺偲偒偼擔偺埵抲傊 */
	} else {
		/* 擭偼堦墳崱擭傪擖傟偰偍偔 */
		time(&ltime);
		cctime=ctime(&ltime);
		nc[0]=cctime[20];
		nc[1]=cctime[21];
		nc[2]=cctime[22];
		nc[3]=cctime[23];
	}
}

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

static void today_init()
/* 崱擔偺擔晅擖椡 */
{
int i;
time_t ltime;
char *cctime;
	time(&ltime);
	cctime=ctime(&ltime);
	/* WED OCT 22 13:15:30 1986\n\0 */
	/* 012345678901234567890123     */
	
	/* 擭 */
	nc[0]=cctime[20];
	nc[1]=cctime[21];
	nc[2]=cctime[22];
	nc[3]=cctime[23];
	/* 擔 */
	nc[6]=cctime[8];
	nc[7]=cctime[9];
	
	/* 寧 */
	nc[4]=0;
	i=week_asc(&cctime[4]);
	if (i>=10) {nc[4]='1'; i-=10;}
	nc[5]=i+'0';
}

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

static int ctrl_operate(int ky,int year,int month,int day,int mode)
/* 僐儞僩儘乕儖僐乕僪張棟 亖 撪晹僐乕僪張棟 */
/* return */
/*  0=not use key or nothing happen */
/*  1=use key : point move only */
/*  2=use key : 彂偒姺偊桳傝 */
{
int i;
	switch (ky) {
		case SKd|0x04: /* ^D : 崱擔偺擔晅擖椡 */
			today_init();
			return(2);
		
		case SKtab: /* TAB */
		case SKf|0x06: /* ^F : 崁栚屻傠堏摦 */
			if (nx<=3) {nx=4; return(1);} /* 擭仺寧 */
			if (nx<=5) {nx=6; return(1);} /* 寧仺擔 */
			return(0);
		
		case SKa|0x01: /* ^A : 崁栚慜堏摦 */
			if (nx>=6) {nx=4; return(1);} /* 寧仼擔 */
			if (nx>=4) {nx=0; return(1);} /* 擭仼寧 */
			return(0);
		
		case SKhome: /* HOME */
		case SKq|0x11: /* ^Q : 儂乕儉 */
			if (nx==2) return(0);
			nx=2;
			return(1);
		
		case SKp|0x10: /* ^P : 僄儞僪 */
			if (nx==7) return(0);
			nx=7;
			return(1);
		
		case SKright: /* -> : 億僀儞僩屻傠堏摦 */
			if (nx>=7) 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==7) return(i==0? 0:2);
			nx++;
			return(1+(i!=0));
		
		case SKmdiv|'?': /* ? : 儚僀儖僪僇乕僪亄屻傠堏摦 */
			i=nc[nx];
			if (nx==0 || nx==1) {
				nc[0]=nc[1]=nc[2]=nc[3]=WILD;
				nx=4;
			} else
			if (nx==2 || nx==3) {
				nc[2]=nc[3]=WILD;
				nx=4;
			} else
			if (nx==4 || nx==5) {
				nc[4]=nc[5]=WILD;
				nx=6;
			} else
			if (nx==6 || nx==7) {
				nc[6]=nc[7]=WILD;
				nx=7;
				return(i==WILD? 0:2);
			}
			return(1+(i!=WILD));
		
		case SKk|0x0b: /* ^K : 億僀儞僩埲崀僋儕傾 */
			for (i=nx;i<8;i++) nc[i]=0;
			return(2);
		
		case SKclr: /* CLR */
		case SKy|0x19: /* ^Y : 慡僋儕傾 */
			date_init(year,month,day,mode);
			return(2);
	}
	/* 巊梡偝傟偰偄側偄僉乕偺帪 */
	beep();
	return(0);
}

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

int date_input(format,year,month,day,mode,kexit,rkey,getchs)
unchar *format;
int *year,*month,*day,mode,kexit,*rkey;
int (*getchs)();
/* mode	bit 0 : 愭峴擖椡儌乕僪
	bit 1 : 愭峴擖椡偟偨屻 0=寧偺侾侽偺埵偺埵抲傊 , 1=擔偺侾偺埵偺埵抲傊
	bit 2 : 捈慜偺儕僞乕儞忬懺傪嵞尰偟偰嵞奐
	bit 3 : 帺摦妋掕儌乕僪
	bit 4 : 擭寧擔偑僄儔乕偱傕堦墳抣傪曉偡
*/
{
int x,y,c,cc,yr,m,d;
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 */
		date_init(*year,*month,*day,mode);
		
		finit=1;
		
		/* 弶婜昞帵 */
		EX_PRINT2(8,fmt);
	}
	date_disp(x,y,2);
	
	/* 擖椡 */
	while (1) {
		c=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=='?') {
			c=ctrl_operate(c,*year,*month,*day,mode);
			if (c!=0) date_disp(x,y,c);
			continue;
		}
		
		/* 捠忢擖椡 */
		if (cc>='0' && cc<='9') { /* 悢帤偺偲偒 */
			c=enter_date(cc,mode);
			date_disp(x,y,2);
			if (c) { /* 帺摦妋掕儌乕僪 */
				*rkey=0;
				break;
			}
		} else beep();
	}
	
	/* 彮偟廋惓 */
	/* 寧擔偑侾侽偺埵偩偗 -> 侾偺埵偵擖傟傞 */
	if (nc[5]==0 && nc[4]!=0) {nc[5]=nc[4]; nc[4]=0;}
	if (nc[7]==0 && nc[6]!=0) {nc[7]=nc[6]; nc[6]=0;}
	
	/* 擭寧擔敾掕 */
	yr=calc_sub(0);
	if (yr!=-1) {
		c=calc_sub(2);
		if (c==-1) yr=-1; else yr=yr*100+c;
	}
	m=calc_sub(4);
	d=calc_sub(6);
	c=check_date(yr,m,d);
	if (c==0 || (mode&BIT4)) { /* 僄儔乕偱側偄帪 */
		*year=yr;
		*month=m;
		*day=d;
	}
	
	/* 嵟屻偵擔晅傪嵞昞帵偡傞 */
	date_disp(x,y,2);
	
	/* 擔晅敾掕僼儔僌偲嫟偵婣傞 */
	return(c);
}

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