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

#include <stdio.h>
#include <time.h>
#include <iocslib.h>
#include "defines.h"
#include "amacro.h"
#include "akey.h"
#include "skey.h"

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

static	void	(*PrintTime)();
static	void	(*SelTime)();
static	int	fdisp=0;

void SetClockDisp(void (*pt)(),void (*st)())
/* ClockSet()用表示関数設定 */
{
	PrintTime=pt;
	SelTime=st;
	fdisp=1;
}

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

int ClockSet(int x,int y,int *hh,int *mm,int (*getchs)(),int mode)
/* mode : BIT0=0:24hours , 1:12hours , BIT12 , BIT14&13 , BIT15 */
/* 0:00=12:00am 1:00=1:00am 〜 12:00=12:00pm 13:00=1:00pm 〜 23:00=11:00pm */
/* リターン値は２４時制のみ */
{
time_t t,tt;
int cur;
int h,m,s,ds;
int fdp,hms=2; /* hms : 2=sec , 1=min , 0=hour */
	if (!fdisp) return(-100);
	/* 初期セレクトモード設定 */
	switch (mode&(BIT14|BIT13)) {
		case BIT13:hms=1; break;
		case BIT14:hms=0; break;
	}
	mode&=(~(BIT14|BIT13));
	
	cur=curmode(0);
	if (mode&BIT12) { /* 外部h:m:s始動 */
		mode&=(~BIT12);
		/* sはmmの上位１ビットに入れておく */
		h=*hh;
		m=*mm;
		s=m>>8;
		m&=0xff;
	} else s=NowTime(&h,&m); /* 現在時刻設定 */
	PrintTime(x,y,h,m,s,mode);
	SelTime(x,y,hms,1);
	t=clock();
	do {
		/* 外部時刻表示ルーチン：出来るだけ速くすること */
		PrintTime(x,y,h,m,s,mode);
		
		fdp=0;
		while (clock()-t<CBASE) { /* wait sec */
		    ds=1;
		    while (B_KEYSNS()) { /* キーによる時刻修正 */
			switch (getchs(0)) {
			    default:
				continue;
			    case SKesc:
				s=-s-1; /* s<=-1 */
			    case SKcr:
			    case SKent:
			    case SKm|0x0d:
				goto END;
			
			    case SKhome: /* 現在時刻設定 */
				s=NowTime(&h,&m);
				break;
			
			    case SKleft: /* h <- m <- s */
				if (hms>0) {
					SelTime(x,y,hms,0); /* 元のクリア */
					hms--;
					SelTime(x,y,hms,1); /* 新しいところのセット */
				}
				continue;
			    case SKright:/* h -> m -> s */
				if (hms<2) {
					SelTime(x,y,hms,0);
					hms++;
					SelTime(x,y,hms,1);
				}
				continue;
			
			    case SKrdown:
				ds=10; /* -10 */
			    case SKup:
				switch (hms) {
				    case 2:/* sec */
					s-=ds;
					if (s<0) {
					    s+=60;
					    if ((--m)<0) {
						m=59;
						if ((--h)<0) h=23;
					    }
					}
					break;
				    case 1:/* min */
					m-=ds;
					if (m<0) {
					    m+=60;
					    if ((--h)<0) h=23;
					}
					break;
				    case 0:/* hour */
					if (mode) ds=1; /* 12時制の時 */
					h-=ds;
					if (h<0) {
						if (ds==1) h=23;
						else {
							h+=ds;
							h%=10;
							h+=10;
							if (h<=13) h+=10;
						}
					}
					break;
				}
				break;
			
			    case SKtab:/* 0 second */
				if (s<=29) {s=0; break;}
				else {s=0; goto MINUP;}
			
			    case SKrup:
				ds=10; /* +10 */
			    case SKdown:
				switch (hms) {
				    case 2:/* sec */
					s+=ds;
					if (s>=60) {
					    s-=60;
					    if ((++m)>=60) {
						m=0;
						if ((++h)>=24) h=0;
					    }
					}
					break;
				    case 1:/* min */
				    MINUP:;
					m+=ds;
					if (m>=60) {
					    m-=60;
					    if ((++h)>=24) h=0;
					}
					break;
				    case 0:/* hour */
					if (mode) ds=1; /* 12時制の時 */
					h+=ds;
					if (h>=24) {
						if (ds==1) h=0;	else h%=10;
					}
					break;
				}
				break;
			}
			PrintTime(x,y,h,m,s,mode);
			fdp=1;
			t=clock(); /* 時計を一時的に止めるため */
		    }
		}
		if (!fdp) {
			tt=clock(); /* 処理中に1sec以上経ってもいいように */
			ds=(tt-t)/CBASE;
			t=tt;
			
			/* 秒カウント（分・時繰り上がりあり）*/
			/* ただし、溜めを６０秒以上にはしないこと */
			s+=ds;
			if (s>=60) {
				s-=60;
				if ((++m)>=60) {
					m=0;
					if ((++h)>=24) h=0;
				}
			}
		}
	} while (1);
    END:;
	*hh=h;
	*mm=m;
	SelTime(x,y,hms,0);
	curmode(cur);
	return(s);
}

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