#include <stdio.h>
#include <stdlib.h>
#include <zx81.h>
#include <string.h>

void printCenter(int numLiner, char* textCenter)
{
	int lenCenter = strlen(textCenter);
	int whiteSpace = (32 - lenCenter) / 2;
	zx_setcursorpos(numLiner, whiteSpace);
	printf("%s", textCenter);
}

uchar GetChar(char cY, char cX)
{
	return wpeek(wpeek(16396) + 1 + cX + cY * 33);
}

void SetChar(char cX, char cY, char cValue) {
	bpoke(wpeek(16396) + 1 + cY + cX * 33, cValue);
}

void UpdateScore(score) {
	if (score < 10) {
		zx_setcursorpos(8, 31);
		printf("%c", 156 + score);
	}
	else if (score < 100) {
		zx_setcursorpos(8, 30);
		printf("%c%c", 156 + (score / 10), 156 + (score % 10));
	}
	else {
		zx_setcursorpos(8, 29);
		printf("%c%c%c", 156 + (score / 100), 156 + ((score / 10) % 10), 156 + (score % 10));
	}
}

void scrollLeft(void) {
	//from https://sinclairzxworld.com/viewtopic.php?p=32978#p32978
#asm
SCROLL_LEFT:
	; SCROLL PLAYING AREA ONE COLUMN LEFT
	LD A, 8
	LD HL, ($400C)
	INC HL
	INC HL
	LD DE, ($400C)
	INC DE

SCROLL_LOOP_LEFT:
	LD BC, 31
	LDIR
	DEC HL
	LD (HL), $00
	INC HL
	INC HL
	INC HL
	INC DE
	INC DE
	DEC A
	JR NZ, SCROLL_LOOP_LEFT

	RET ; SCROLL_LEFT

#endasm
}

int main(void)
{

	int hiScore = 0;
	int a;

INITGAME:

	zx_asciimode(0);
	for (a = 0; a < 3; a++)
	{
		zx_setcursorpos(a + 3, 5);
		printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128);
	}
	zx_asciimode(1);
	zx_setcursorpos(4, 6);
	printf("HIGHWAY");
	zx_setcursorpos(4, 14);
	printf("ROBBERY");
	zx_setcursorpos(4, 22);
	zx_asciimode(0);
	printf("%c%c%c%c", 158, 156, 158, 157);
	zx_asciimode(1);
	printCenter(10, "Q up A down");
	printCenter(14, "get   and not hit with ");
	zx_setcursorpos(14, 8);
	zx_asciimode(0);
	printf("%c", 141);
	zx_setcursorpos(14, 27);
	printf("%c", 136);
	zx_asciimode(1);
	printCenter(16, "press any key to start");

	if (hiScore > 0) {
		printCenter(19, "hiscore    ");
		zx_setcursorpos(19, 19);
		printf("%d", hiScore);
	}

	printCenter(23, "2021 salvacam");

	fgetc_cons();        // wait for keypress
	zx_cls();


	zx_asciimode(0);
	int score = 0;
	int y = 4;

	int exit = 0;
	int timePause = 10;
	int timeBonus = 0;

	for (a = 0; a < 9; a++) {
		zx_setcursorpos(a, 0);
		printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128);
	}

	zx_setcursorpos(8, 0);
	printf("%c%c", 141, 128);

	zx_asciimode(1);
	zx_setcursorpos(8, 3);
	printf("HIGHWAY");
	zx_setcursorpos(8, 11);
	printf("ROBBERY");
	zx_asciimode(0);
	zx_setcursorpos(8, 19);
	printf("%c", 141);
	zx_setcursorpos(8, 28);
	printf("%c%c%c%c", 141, 156, 156, 156);
	zx_setcursorpos(9, 0);
	printf("%c", 0);


	in_Wait(15);
	do
	{
		in_Wait(timePause);

		SetChar(y, 15, 128);
		scrollLeft();

		SetChar(0, 31, 128);
		SetChar(1, 31, 128);
		SetChar(2, 31, 128);
		SetChar(3, 31, 128);
		SetChar(4, 31, 128);
		SetChar(5, 31, 128);
		SetChar(6, 31, 128);
		SetChar(7, 31, 128);

		timeBonus++;
		if (timeBonus < 7) {
			SetChar(rand() % 8, 31, 141);
		}
		else
		{
			SetChar(rand() % 8, 31, 136);
			if (timeBonus == 15) {
				timeBonus = 0;
			}
		}

		if (GetChar(y, 15) == 136 ) {
			exit = 1;
			break;
		}
		if (GetChar(y, 15) == 141 ) {
			score++;
			UpdateScore(score);
		}

		SetChar(y, 15, 146);

		if (in_KeyPressed(in_LookupKey('Q')) && y > 0) {
			if (GetChar(y - 1, 15) == 136 ) {
				exit = 1;
				break;
			}
			if (GetChar(y - 1, 15) == 141 ) {
				score++;
				UpdateScore(score);
			}
			SetChar(y, 15, 128);
			y--;
			SetChar(y, 15, 146);
		}

		if (in_KeyPressed(in_LookupKey('A')) && y < 7) {
			if (GetChar(y + 1, 15) == 136 ) {
				exit = 1;
				break;
			}
			if (GetChar(y + 1, 15) == 141 ) {
				score++;
				UpdateScore(score);
			}
			SetChar(y, 15, 128);
			y++;
			SetChar(y, 15, 146);
		}

	} while (exit == 0);

	int key = getk();
	int explotion = 5;
	while (key == '\0') {

		SetChar(y, 15, 18);

		if (explotion == 5) {
			explotion = 133;
		}
		else {
			explotion = 5;
		}

		SetChar(y, 10, explotion);
		SetChar(y, 11, explotion);
		SetChar(y, 12, explotion);
		SetChar(y, 13, explotion);
		SetChar(y, 14, explotion);

		SetChar(y, 16, explotion);
		SetChar(y, 17, explotion);
		SetChar(y, 18, explotion);
		SetChar(y, 19, explotion);
		SetChar(y, 20, explotion);

		in_Pause(10);
		key = getk();
	}

	zx_cls();

	zx_asciimode(1);

	if (score > 999) score = 999;

	printCenter(10, "your score    ");
	zx_setcursorpos(10, 21);
	printf("%d", score);

	in_Wait(50);
	printCenter(12, "hiscore    ");
	zx_setcursorpos(12, 21);
	printf("%d", hiScore);

	if (score > hiScore ) {
		hiScore = score;
		in_Wait(20);
		printCenter(12, "NEW HISCORE    ");
		zx_setcursorpos(12, 21);
		printf("%d", hiScore);
	}

	in_Wait(50);
	printCenter(15, "press any key to restart");

	zx_asciimode(0);

	fgetc_cons();        // wait for keypress
	zx_cls();

	goto INITGAME;
	return 0;
}