//Practice tracing circles

//Giotto, a famous artist, drew a freehand circle to get a job.

RegDefault("ZenithOS/CircleTrace", "F64 best_score=999;\n");
RegExe("ZenithOS/CircleTrace");

I64 cx, cy;
F64 avg_error = 0, elapsed_time = 0, total_error = 0, score = 999;

U0 SongTask(I64)
{
	Fs->task_end_cb = &SoundTaskEndCB;
	MusicSettingsReset;
	while (TRUE)
		Play("5hEDC4A5RCDECR");
}

U0 DrawIt(CTask *task, CDC *dc)
{
	GrPrint(dc, 0, 0, "Error:%6.3f  Time:%6.3f  Score:%6.3f  Best:%8.3f", avg_error, elapsed_time, score, best_score);
}

#define CIRCLE_RADIUS 	100
#define CIRCUMFERENCE 	(2 * ã * CIRCLE_RADIUS)

Bool CTPlot(CDC *dc, I64 x, I64 y, I64)
{
	F64 rad = Sqrt(Sqr(x - cx) + Sqr(y - cy));

	GrPlot(dc, x, y);
	total_error += Abs(rad - CIRCLE_RADIUS);

	return TRUE;
}

U0 CircleTrace()
{
	I64  message_code, arg1, arg2, x1, y1;
	F64  rad, t0, total_distance;
	CDC *dc = DCAlias;

	SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
	Fs->song_task = Spawn(&SongTask, NULL, "Song",, Fs);
	AutoComplete;
	WinBorder;
	WinMax;
	DocCursor;
	DocClear;

	cx = Fs->pix_width  / 2;
	cy = Fs->pix_height / 2;

	Fs->win_inhibit = WIG_TASK_DEFAULT - WIF_SELF_FOCUS - WIF_SELF_BORDER;
	Fs->draw_it		= &DrawIt;

	DCFill;
	dc->color = ROP_XOR + BLACK ^ TRANSPARENT;
	GrCircle(dc, cx, cy, CIRCLE_RADIUS);
	do
	{
		message_code = MessageGet(&arg1, &arg2, 1 << MESSAGE_KEY_DOWN + 1 << MESSAGE_MS_L_DOWN);
		switch (message_code)
		{
			case MESSAGE_KEY_UP:
				break;

			case MESSAGE_MS_L_DOWN:
				DCFill;
				dc->color = ROP_XOR + BLACK ^ TRANSPARENT;
				GrCircle(dc, cx, cy, CIRCLE_RADIUS);
				dc->color = ROP_XOR + RED ^ TRANSPARENT;
				t0 = tS;
				total_distance = 0.001;
				total_error = 0;
				x1 = arg1;
				y1 = arg2;
				do
				{
					message_code = MessageScan(&arg1, &arg2, 1 << MESSAGE_MS_L_UP + 1 << MESSAGE_MS_MOVE);
					switch (message_code)
					{
						case MESSAGE_MS_L_UP:
							break;

						case MESSAGE_MS_MOVE:
							if (x1 != arg1 || y1 != arg2)
							{
								total_distance += Sqrt(Sqr(x1 - arg1) + Sqr(y1 - arg2));
								Line(dc, x1, y1, 0, arg1, arg2, 0, &CTPlot);
								x1 = arg1;
								y1 = arg2;
								//undo overlapping pixs on segments
								GrPlot(dc, x1, y1);
								rad = Sqrt(Sqr(x1 - cx) + Sqr(y1 - cy));
								total_error -= Abs(rad - CIRCLE_RADIUS);
							}
							break;
					}
					elapsed_time = tS - t0;
					avg_error = total_error / total_distance;
					score = elapsed_time * avg_error;

					//$LK,"Sleep",A="MN:Sleep"$()s until the next time the
					//window mgr task runs.  The
					//window mgr calls the UpdateWin() routine
					//and places messages in the que, so there's
					//no need to do anything until the window mgr runs.
					Refresh;

				}
				while (message_code != MESSAGE_MS_L_UP);

				music.mute = TRUE;
				Sleep(200);
				if (total_distance > 0.95 * CIRCUMFERENCE)
				{
					if (score < best_score)
					{
						Sound(86);
						Sleep(50);
						Sound;
						Sleep(50);
						Sound(86);
						Sleep(50);
						Sound;
						Sleep(50);
						Sound(86);
						Sleep(50);
						best_score = score;
					}
					else
					{
						Sound(62);
						Sleep(50);
					}
				}
				else
				{
					Sound(34);
					Sleep(1000);
				}
				Sound;
				Sleep(200);
				music.mute = FALSE;
				break;
		}
	}
	while (message_code != MESSAGE_KEY_DOWN || arg1 != CH_SHIFT_ESC && arg1 != CH_ESC);

	MessageGet(,, 1 << MESSAGE_KEY_UP);
	SettingsPop;
	DCFill;
	DCDel(dc);
	RegWrite("ZenithOS/CircleTrace", "F64 best_score=%5.4f;\n", best_score);
}

CircleTrace;	//Execute when #included
