/*
 * Copyright (c) 2018 Jan Van Winkel <jan.van_winkel@dxplore.eu>
 * Copyright (c) 2023 Nordic Semiconductor
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <SDL.h>
#include "nsi_tracing.h"

int sdl_display_init_bottom(uint16_t height, uint16_t width, uint16_t zoom_pct,
			    bool use_accelerator, void **window, void **renderer, void **mutex,
			    void **texture, void **read_texture)
{
	*window = SDL_CreateWindow("Zephyr Display", SDL_WINDOWPOS_UNDEFINED,
				   SDL_WINDOWPOS_UNDEFINED, width * zoom_pct / 100,
				   height * zoom_pct / 100, SDL_WINDOW_SHOWN);
	if (*window == NULL) {
		nsi_print_warning("Failed to create SDL window: %s", SDL_GetError());
		return -1;
	}

	if (use_accelerator) {
		*renderer = SDL_CreateRenderer(*window, -1, SDL_RENDERER_ACCELERATED);
	} else {
		*renderer = SDL_CreateRenderer(*window, -1, SDL_RENDERER_SOFTWARE);
	}

	if (*renderer == NULL) {
		nsi_print_warning("Failed to create SDL renderer: %s",
				SDL_GetError());
		return -1;
	}

	*mutex = SDL_CreateMutex();
	if (*mutex == NULL) {
		nsi_print_warning("Failed to create SDL mutex: %s", SDL_GetError());
		return -1;
	}

	SDL_RenderSetLogicalSize(*renderer, width, height);

	*texture = SDL_CreateTexture(*renderer, SDL_PIXELFORMAT_ARGB8888,
				     SDL_TEXTUREACCESS_STATIC, width, height);
	if (*texture == NULL) {
		nsi_print_warning("Failed to create SDL texture: %s", SDL_GetError());
		return -1;
	}

	*read_texture = SDL_CreateTexture(*renderer, SDL_PIXELFORMAT_ARGB8888,
					  SDL_TEXTUREACCESS_TARGET, width, height);
	if (*read_texture == NULL) {
		nsi_print_warning("Failed to create SDL texture for read: %s", SDL_GetError());
		return -1;
	}

	SDL_SetRenderDrawColor(*renderer, 0, 0, 0, 0xFF);
	SDL_RenderClear(*renderer);
	SDL_RenderPresent(*renderer);

	return 0;
}

void sdl_display_write_bottom(const uint16_t height, const uint16_t width,
			      const uint16_t x, const uint16_t y,
			      void *renderer, void *mutex, void *texture,
			      uint8_t *buf, bool display_on)
{
	SDL_Rect rect;
	int err;

	rect.x = x;
	rect.y = y;
	rect.w = width;
	rect.h = height;

	err = SDL_TryLockMutex(mutex);
	if (err) {
		nsi_print_warning("Failed to lock SDL mutex: %s", SDL_GetError());
		return;
	}

	SDL_UpdateTexture(texture, &rect, buf, 4 * rect.w);

	if (display_on) {
		SDL_RenderClear(renderer);
		SDL_RenderCopy(renderer, texture, NULL, NULL);
		SDL_RenderPresent(renderer);
	}

	SDL_UnlockMutex(mutex);
}

int sdl_display_read_bottom(const uint16_t height, const uint16_t width,
			    const uint16_t x, const uint16_t y,
			    void *renderer, void *buf, uint16_t pitch,
			    void *mutex, void *texture, void *read_texture)
{
	SDL_Rect rect;
	int err;

	rect.x = x;
	rect.y = y;
	rect.w = width;
	rect.h = height;

	err = SDL_TryLockMutex(mutex);
	if (err) {
		nsi_print_warning("Failed to lock SDL mutex: %s", SDL_GetError());
		return -1;
	}

	SDL_SetRenderTarget(renderer, read_texture);

	SDL_RenderClear(renderer);
	SDL_RenderCopy(renderer, texture, NULL, NULL);
	SDL_RenderReadPixels(renderer, &rect, SDL_PIXELFORMAT_ARGB8888, buf, width * 4);

	SDL_SetRenderTarget(renderer, NULL);

	SDL_UnlockMutex(mutex);

	return err;
}

void sdl_display_blanking_off_bottom(void *renderer, void *texture)
{
	SDL_RenderClear(renderer);
	SDL_RenderCopy(renderer, texture, NULL, NULL);
	SDL_RenderPresent(renderer);
}

void sdl_display_blanking_on_bottom(void *renderer)
{
	SDL_RenderClear(renderer);
	SDL_RenderPresent(renderer);
}

void sdl_display_cleanup_bottom(void **window, void **renderer, void **mutex, void **texture,
				void **read_texture)
{
	if (*read_texture != NULL) {
		SDL_DestroyTexture(*read_texture);
		*read_texture = NULL;
	}

	if (*texture != NULL) {
		SDL_DestroyTexture(*texture);
		*texture = NULL;
	}

	if (*mutex != NULL) {
		SDL_DestroyMutex(*mutex);
		*mutex = NULL;
	}

	if (*renderer != NULL) {
		SDL_DestroyRenderer(*renderer);
		*renderer = NULL;
	}

	if (*window != NULL) {
		SDL_DestroyWindow(*window);
		*window = NULL;
	}
}
