?define BACKGROUND TRUE
?define GMOUSE TRUE
?define GOODFONTS TRUE
?define progNote "PTEST - определение времени реакции на световой раздражитель."
?define progFootNote "Удомля 1998"
?define ExitBanner "\n (C) Copyrigth M.Sheker"
?includepath "c:\c--\lib\shell"	//путь к директории с библиотекой SHELL
?include "SHELL.h--"
?include "file.h--"
?include "_string.h--"
?include "hok.h--"
?include "box.h--"
word width,height;
?include "REAKC.H--"
char mesname=" Скажите как Вас звать";
char messtart=" Начало теста";
char bestrez=" Лучшие результаты";
char mesexit=" Закончить тест";
char b1name=" `You name  ";
char b2name="   `Start   ";
char b3name=" `Hit-Parad ";
char b4name="   `Exit    ";

?define NUM_HIT 10

char nameg[16]=0;
struct _HIT_
{
	char name[16];
	float rez;
	float minrez;
}hit[NUM_HIT]=0;

int tecpoz=NUM_HIT;

void InputName()
byte activ;
{
	activ=FALSE;
	hWindow(modeCenter,modeCenter,7,24,"Какое Ваше имя?",idDialog,TRUE);
	Box(0,1,4,20,0);
	cstr.str=#nameg;
	cstr.cpos=0;
	cstr.width=15;
	cstr.wrow=2;
	cstr.wcol=4;
	for(;;){
		StringShow(activ-1);
		hOK2(activ,0);
		hRead(0);
		IF(AL==evKeyboard){
			IF(Event.keyCode==k_esc)break;
			IF(activ==FALSE)Edit_String(Event.keyCode);
			IF(Event.what==evKeyboard){
				SWITCH(Event.keyCode&0xff00){
					CASE k_up:
					CASE k_down:
					CASE k_tab:
					CASE k_shifttab:
						IF(activ==FALSE)AL=TRUE;
						ELSE AL=FALSE;
						activ=AL;
						BREAK;
					CASE 0x1C00:
						IF(activ==FALSE)activ=TRUE;
						ELSE GOTO ENP;
				}
			}
		}
		ELSE IF(AL==evMouse)&&(Event.buttons==1)&&(Event.mwrow==cstr.wrow)&&
			(Event.mwcol>=cstr.wcol)&&(cstr.wcol+cstr.width>Event.mwcol){
			cstr.cpos=Event.mwcol-cstr.wcol;
			activ=FALSE;
		}
		ELSE IF(AL==evCloseWin)BREAK;
		IF(hOKPress()==TRUE)BREAK;
	}
ENP:
	hOK2(TRUE,TRUE);
	WAIT(9);
	STRTRIM(#nameg);
	rWindow();
}

void StartGame()
char m1[20];
int i,j;
{
	WHILE(nameg[0]==0)InputName();
	whide();
	width=51;
	height=9;
	hWindow(modeCenter,modeCenter,19,56,"Жми клавишу как увидишь квадрат",idNormal,TRUE);
	Box(0,0,10,54,0);
	Say(14,1,_scheme.schNormalText[Window.scheme],"Число попыток      0             Лучший результат:");
	Say(15,1,_scheme.schNormalText[Window.scheme],"Текущий результат  0");
	Say(16,1,_scheme.schNormalText[Window.scheme],"Лучшее время       0                  он равен ");
	Say(17,1,_scheme.schNormalText[Window.scheme],"Худшее время       0                       сек");
	Say(18,1,_scheme.schNormalText[Window.scheme],"Среднее время      0");
	cprints(15,35,16,_scheme.schAccentText[Window.scheme],#hit[0].name);
	ftoan(float hit[0].rez,#m1,3);
	Say(17,38,_scheme.schNormalText[Window.scheme],#m1);
	FootMessage="Нажмите клавишу ESC для досрочного завершения теста";
	hReakc();
	for(;;){
		IF(Finish!=FALSE)BREAK;
		hRead(0);
		IF(AL==evKeyboard)&&(Event.keyCode==k_esc)BREAK;
		ELSE IF(AL==evCloseWin)BREAK;
		hReakcHandler();
	}
	rReakc();
	hInfoWindow("Т Е С Т  З А К О Н Ч Е Н !",idDialog);
	WAIT(38);
	rInfoWindow();
	if(numt==NUMTEST){
		FOR(i=0;(hit[i].name[0]!=0)&&(i<NUM_HIT);i++); //число записей
		FOR(j=i;(j!=0)&&(hit[j-1].rez>sred);j--){      //если новый лучше то сдвиг
			IF(j!=NUM_HIT){
				hit[j]=hit[j-1];
			}
		}
		IF(i!=j)||(i<NUM_HIT){
			strcpy(#hit[j].name,#nameg);
			hit[j].rez=sred;
			hit[j].minrez=mint;
			tecpoz=j;
			Hit();
		}
		ELSE{
			hInfoWindow("Ваш результат не попал в десятку лучших.",idAccent);
			WAIT(54);
			rInfoWindow();
		}
		tecpoz=NUM_HIT;
	}
	rWindow();
	wunhide();
	KBCLEAR();
	MoClear();
}

void Hit()
char m1[10];
int i,atr;
byte show;
{
	show=TRUE;
	whide();
 	hWindow(modeCenter,modeCenter,NUM_HIT+7,41,"А теперь наша лучшая десятка.",idBlack,TRUE);
	wputs(" ┌─────┬───────────────┬───────┬───────┐\n");
	wputs(" │Место│   Наши герои  │Средний│Лучший │\n");
	wputs(" ├─────┼───────────────┼───────┼───────┤\n");
	FOR(i=0;i<NUM_HIT;i++)wputs(
	      " │     │               │       │       │\n");

	wputs(" └─────┴───────────────┴───────┴───────┘\n");
	for(i=0;(hit[i].name[0]!=0)&&(i<NUM_HIT);i++){
		INTTOSTR(i+1,#m1);
		IF(i==tecpoz)atr=_scheme.schAccentText[Window.scheme];
		ELSE atr=_scheme.schNormalText[Window.scheme];
		Say(i+3,4,atr,#m1);
		cprints(i+3,8,15,atr,#hit[i].name);
		ftoan(float hit[i].rez,#m1,3);
		Say(i+3,25,atr,#m1);
		ftoan(float hit[i].minrez,#m1,3);
		Say(i+3,33,atr,#m1);
	}
	for(;;){
		IF(show==TRUE){
			hOK2(1,0);
			show=FALSE;
		}
		hRead(0);
		IF(AL==evKeyboard)&&(Event.keyCode==k_esc)||(Event.keyCode==k_return)BREAK;
		ELSE IF(AL==evCloseWin)BREAK;
		IF(hOKPress()==TRUE)BREAK;
	}
	rWindow();
	wunhide();
}

struct _BUTONS_
{
	byte ypos;
	byte xpos;
	byte len;	//длина кнопки
	byte hkey;//горячая клавиша
	byte select;//активная ли сейчас кнопка
	int but;	//название кнопки
	int mes;	//сообщение внижней строке
	int proc;	//вызываемая процедура
}BUT[4]={9, 1, 13,21,TRUE, #b1name,#mesname, #InputName,
         9, 16,13,31,FALSE,#b2name,#messtart,#StartGame,
         9, 31,13,35,FALSE,#b3name,#bestrez, #Hit,
         11,16,13,18,FALSE,#b4name,#mesexit, #CloseShell};

main()
{
	InitShell();	//инициализация оболочки
	InitGame();
	CloseShell();	//закрытие оболочки
}

void UserProc()
{

}

void SaveFile()
{
	writefile("ptest.scr",DS,#hit,sizeof(hit));
}

void InitGame()
byte SHOW;
int i;
byte press;	//нажатие на кнопку
{
	readfile("ptest.scr",DS,#hit,sizeof(hit));
	ATEXIT(#SaveFile);
	SHOW=TRUE;
	press=FALSE;
	hWindow(modeCenter,modeCenter,13,46,"Реакция на световой сигнал",idHelp,TRUE);
	wputs("RCВ этом тесте");
	wputs("\nCВам необходимо при появлении цветного");
	wputs("\nCквадрата нажать на FлюбуюF клавишу");
	wputs("\nCили кнопку мыши.");
	Box(0,1,6,42,"Правила игры");
	for(;;){
		if(SHOW==TRUE){
			FOR(i=0;i<4;i++){
				Button(BUT[i].ypos,BUT[i].xpos,BUT[i].but,BUT[i].select,press);
				IF(BUT[i].select==TRUE){
					FootMessage=BUT[i].mes;
					IF(press==TRUE){
						WAIT(2);
						$call BUT[i].proc
						WAIT(2);
						press=FALSE;
						i=-1;
					}
				}
			}
			SHOW=FALSE;
		}
		hRead(0);
		if(AL==evKeyboard){
			switch(Event.keyCode&0xFF00){
				CASE k_up:
					IF(BUT[3].select==TRUE){
						BUT[3].select=FALSE;
						BUT[0].select=TRUE;
						SHOW=TRUE;
					}
					break;
				CASE k_down:
					IF(BUT[3].select==FALSE){
						BUT[3].select=TRUE;
						BUT[0].select=FALSE;
						BUT[1].select=FALSE;
						BUT[2].select=FALSE;
						SHOW=TRUE;
					}
					break;
				CASE k_left:
					IF(BUT[3].select==FALSE)&&(BUT[0].select==FALSE){
						BUT[0].select=BUT[1].select;
						BUT[1].select=BUT[2].select;
						BUT[2].select=FALSE;
						SHOW=TRUE;
					}
					break;
				CASE k_right:
					IF(BUT[3].select==FALSE)&&(BUT[2].select==FALSE){
						BUT[2].select=BUT[1].select;
						BUT[1].select=BUT[0].select;
						BUT[0].select=FALSE;
						SHOW=TRUE;
					}
					break;
				case k_tab:
					i=BUT[3].select;
					BUT[3].select=BUT[2].select;
					BUT[2].select=BUT[1].select;
					BUT[1].select=BUT[0].select;
					BUT[0].select=i;
					SHOW=TRUE;
					break;
				case k_shifttab:
					i=BUT[0].select;
					BUT[0].select=BUT[1].select;
					BUT[1].select=BUT[2].select;
					BUT[2].select=BUT[3].select;
					BUT[3].select=i;
					SHOW=TRUE;
					BREAK;
				default:
					BX=Event.keyCode;
					IF(BX==k_return){
						press=TRUE;
						SHOW=TRUE;
						BREAK;
					}
					FOR(i=0;i<4;i++){
						IF(BUT[i].hkey==BH){
							FOR(press=0;press<4;press++){
								IF(press==i)BUT[i].select=TRUE;
								ELSE BUT[press].select=FALSE;
							}
							press=TRUE;
							SHOW=TRUE;
							BREAK;
						}
					}
					BREAK;
			}
			IF(Event.keyCode==k_esc)break;
		}
		else if(AL==evMouse){
			if(Event.buttons==1){
				FOR(i=0;i<4;i++){
					IF(Event.mwrow==BUT[i].ypos){
						IF(Event.mwcol>=BUT[i].xpos)&&(BUT[i].xpos+BUT[i].len>Event.mwcol){
							FOR(press=0;press<4;press++){
								IF(press==i)BUT[i].select=TRUE;
								ELSE BUT[press].select=FALSE;
							}
							press=TRUE;
							SHOW=TRUE;
							BREAK;
						}
					}
				}
			}
		}
		ELSE IF(AL==evCloseWin)BREAK;
	}
	rWindow();
}
