// gcc test.c `pkg-config --cflags --libs sdl2`
// grab 7k_icon.bmp or another image for the mouse cursor and place in same dir
// tap any key to go fullscreen
#include <SDL.h>
#include <stdio.h>

#define VGA_WIDTH             800
#define VGA_HEIGHT            600
#define VGA_BPP                 8
#define MAX(a,b)        (((a) > (b)) ? (a) : (b))
#define MIN(a,b)        (((a) < (b)) ? (a) : (b))

SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
SDL_Surface *front;
SDL_Surface *target;
SDL_Surface *icon;
Uint32 video_mode_flags;
int window_pitch;
int signal_exit_flag;
int cur_x;
int cur_y;
int cur_x1;
int cur_y1;
int cur_x2;
int cur_y2;

int main()
{
	if (SDL_Init(SDL_INIT_VIDEO))
		return 0;

	SDL_DisplayMode mode;
	int window_width = 1024;
	int window_height = 768;

	if (SDL_GetDesktopDisplayMode(0, &mode) == 0) {
		if (mode.h < 1024) {
			window_width = 800;
			window_height = 600;
		}
	} else {
		SDL_Quit();
		return 0;
	}

	if (SDL_CreateWindowAndRenderer(window_width,
					window_height,
					video_mode_flags,
					&window, &renderer) < 0) {
		SDL_Quit();
		return 0;
	}

	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
	SDL_RenderSetLogicalSize(renderer, VGA_WIDTH, VGA_HEIGHT);

	Uint32 window_pixel_format = SDL_GetWindowPixelFormat(window);
	if (window_pixel_format == SDL_PIXELFORMAT_UNKNOWN) {
		SDL_Quit();
		return 0;
	}

	window_pitch = VGA_WIDTH * SDL_BYTESPERPIXEL(window_pixel_format);

	// Cannot use SDL_PIXELFORMAT_INDEX8:
	//   Palettized textures are not supported
	texture = SDL_CreateTexture(renderer,
				    window_pixel_format,
				    SDL_TEXTUREACCESS_STREAMING,
				    VGA_WIDTH, VGA_HEIGHT);

	if (!texture) {
		SDL_Quit();
		return 0;
	}

	front = SDL_CreateRGBSurface(0,
				     VGA_WIDTH,
				     VGA_HEIGHT, VGA_BPP, 0, 0, 0, 0);
	if (!front) {
		SDL_Quit();
		return 0;
	}

	int desktop_bpp = 0;
	if (SDL_PIXELTYPE(window_pixel_format) == SDL_PIXELTYPE_PACKED32) {
		desktop_bpp = 32;
	} else if (SDL_PIXELTYPE(window_pixel_format) ==
		   SDL_PIXELTYPE_PACKED16) {
		desktop_bpp = 16;
	} else if (SDL_PIXELTYPE(window_pixel_format) ==
		   SDL_PIXELTYPE_PACKED8) {
		desktop_bpp = 8;
	} else {
		SDL_Quit();
		return 0;
	}

	target = SDL_CreateRGBSurface(0,
				      VGA_WIDTH,
				      VGA_HEIGHT, desktop_bpp, 0, 0, 0, 0);
	if (!target) {
		SDL_Quit();
		return 0;
	}

	icon = SDL_LoadBMP("7k_icon.bmp");
	if (!icon) {
		SDL_Quit();
		return 0;
	}
	Uint32 colorkey;
	colorkey = SDL_MapRGB(icon->format, 0, 0, 0);
	SDL_SetColorKey(icon, SDL_TRUE, colorkey);

	SDL_SetRelativeMouseMode(SDL_FALSE);

	while (!signal_exit_flag) {
		SDL_Event event;

		SDL_PumpEvents();

		while (SDL_PeepEvents(&event,
				      1,
				      SDL_GETEVENT,
				      SDL_QUIT, SDL_JOYBUTTONUP)) {

			switch (event.type) {
			case SDL_WINDOWEVENT:
				switch (event.window.event) {
				//case SDL_WINDOWEVENT_ENTER: // Do not respond to mouse focus
				case SDL_WINDOWEVENT_FOCUS_GAINED:
				case SDL_WINDOWEVENT_RESTORED:

					SDL_ShowCursor(SDL_DISABLE);
					break;

					//case SDL_WINDOWEVENT_LEAVE: // Do not respond to mouse focus
				case SDL_WINDOWEVENT_FOCUS_LOST:
				case SDL_WINDOWEVENT_MINIMIZED:
					// turn the system cursor back on to get around a fullscreen
					// mouse grabbed problem on windows
					SDL_ShowCursor(SDL_ENABLE);
					break;

				case SDL_WINDOWEVENT_EXPOSED:
					break;
				}
				break;

			case SDL_QUIT:
				signal_exit_flag = 1;
				break;
			case SDL_MOUSEMOTION:
				// SDL already accelerates relative mouse motions.
				// Disable to let the user control speed outside of game.
				if (video_mode_flags &
				    SDL_WINDOW_FULLSCREEN_DESKTOP) {
					cur_x += event.motion.xrel;
					cur_y += event.motion.yrel;
					if (cur_x < 0) {
						cur_x = 0;
					} else if (cur_x >
						   VGA_WIDTH - 5 - 1) {
						cur_x = VGA_WIDTH - 5 - 1;
					}
					if (cur_y < 0) {
						cur_y = 0;
					} else if (cur_y >
						   VGA_HEIGHT - 5 - 1) {
						cur_y = VGA_HEIGHT - 5 - 1;
					}
				} else {
					cur_x = event.motion.x;
					cur_y = event.motion.y;
				}
				printf("actual=(%d %d) game=(%d %d) %d\n",
				       event.motion.x, event.motion.y,
				       cur_x, cur_y,
				       SDL_GetRelativeMouseMode());
				//moveFlag = 1;
				break;
			case SDL_KEYUP:
				video_mode_flags ^=
				    SDL_WINDOW_FULLSCREEN_DESKTOP;
				SDL_SetWindowFullscreen(window,
							video_mode_flags);
				SDL_SetRelativeMouseMode(video_mode_flags &
							 SDL_WINDOW_FULLSCREEN_DESKTOP
							 ? SDL_TRUE :
							 SDL_FALSE);
				break;
			case SDL_MOUSEBUTTONUP:
				SDL_SetWindowGrab(window, SDL_TRUE);
				break;


			default:
				break;
			}
		}


		static Uint32 ticks = 0;
		Uint32 cur_ticks = SDL_GetTicks();
		if (cur_ticks > ticks + 17 || cur_ticks < ticks) {
			cur_x1 = cur_x - 5;	// handle the offset of the hotsite
			cur_y1 = cur_y - 5;
			cur_x2 = cur_x1 + icon->w - 1;
			cur_y2 = cur_y1 + icon->h - 1;

			int save_x1, save_x2, save_y1, save_y2;

			save_x1 = MAX(cur_x1, 0);
			save_y1 = MAX(cur_y1, 0);
			save_x2 = MIN(cur_x2, VGA_WIDTH - 1);
			save_y2 = MIN(cur_y2, VGA_HEIGHT - 1);

			SDL_Rect dstrect;
			SDL_Rect srcrect;
			dstrect.x = save_x1;
			dstrect.y = save_y1;
			srcrect.x = save_x1 - cur_x1;
			srcrect.y = save_y1 - cur_y1;
			srcrect.w = save_x2 - cur_x1;
			srcrect.h = save_y2 - cur_y1;
			ticks = cur_ticks;
			SDL_BlitSurface(front, NULL, target, NULL);
			SDL_BlitSurface(icon, &srcrect, target, &dstrect);
			SDL_UpdateTexture(texture, NULL, target->pixels,
					  window_pitch);
			SDL_RenderClear(renderer);
			SDL_RenderCopy(renderer, texture, NULL, NULL);
			SDL_RenderPresent(renderer);
		}

	}

	return 0;

}
