#include <SDL.h>
#include <xmp.h>
#include <stdbool.h>
#include <stdio.h>
#include <SDL_image.h>

// Fanta <fanta@56k.es> 2026
// Presentator 0.2

// Variables
int modPlaying;
char * modName = NULL;
int modVolume = 100;
int iv;
char *imgVol[] = {"res/vol100.png","res/vol090.png","res/vol080.png","res/vol070.png","res/vol060.png","res/vol050.png","res/vol040.png","res/vol030.png","res/vol020.png","res/vol010.png","res/vol000.png"};
char windowTitle[16] = "Presentator 0.2";
int windowWidth = 1024;
int windowHeight = 768;
char * slidesIndex = "slides/index.txt";
char * actualSlide = NULL;
int actualNSlide = 1;
bool quit = false;
SDL_Window * window;
SDL_Renderer * render;
SDL_Texture *textureVolume = NULL;
SDL_Texture *textureSlide = NULL;
SDL_Texture *textureProgressRect = NULL;
SDL_Event evento;
xmp_context ctx;
int transition_active = 0;


// Functions
int createWindow(void){
	SDL_Init(SDL_INIT_VIDEO);
	window = SDL_CreateWindow(windowTitle,SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,windowWidth,windowHeight,SDL_WINDOW_FULLSCREEN);
	render = SDL_CreateRenderer(window, -1, 0);
	return 0;
}

int refreshVolumeArea(int iv){
	SDL_Rect textureVolumeRect1 = { 0, 0, 398, 68 };
	SDL_Rect textureVolumeRect2 = { 910, 20, 100, 20 };
	IMG_Init(IMG_INIT_PNG);
    textureVolume = IMG_LoadTexture(render, imgVol[iv]);
	SDL_RenderCopy(render, textureVolume, &textureVolumeRect1, &textureVolumeRect2);
    return 0;
}

static void playBuffer(void *udata, Uint8 *stream, int len)
{
	if (xmp_play_buffer((xmp_context)udata, stream, len, 0) < 0){ modPlaying = 0; }
}

static int initAudio(xmp_context ctx) {
	SDL_AudioSpec a;
	a.freq = 44100;
	a.format = AUDIO_S16;
	a.channels = 2;
	a.samples = 2048;
	a.callback = playBuffer;
	a.userdata = ctx;
	if (SDL_OpenAudio(&a, NULL) < 0) { printf("error inicializando audio: %s\n", SDL_GetError());	return 1; }
	return 0;
}

void loadMod(char *modPath){
	modName = modPath;
	ctx = xmp_create_context();
	xmp_load_module(ctx, modName);
	xmp_start_player(ctx, 44100, 0);
	xmp_set_player(ctx, XMP_PLAYER_VOLUME, modVolume);
	initAudio(ctx);
	modPlaying = 1;
	SDL_PauseAudio(0);
}

int stopMod(void){
	xmp_end_player(ctx);
	xmp_free_context(ctx);
	SDL_CloseAudio();
	return 0;
}

int loadSlide(int nslide){
	FILE * fp;
    char * line = NULL;
    size_t len = 0;
    int nline = 1;
    ssize_t read;

    fp = fopen(slidesIndex, "r");
    while ((read = getline(&line, &len, fp)) != -1) {
		if (nslide == nline){
			actualSlide = line;
			actualSlide[ strlen(actualSlide) - 1 ] = '\0';
			SDL_Rect textureSlideRect = { 0, 0, windowWidth, windowHeight };
			IMG_Init(IMG_INIT_PNG);
			textureSlide = IMG_LoadTexture(render, actualSlide);
			SDL_RenderCopy(render, textureSlide, NULL, &textureSlideRect);
		}
		nline = nline +1;
    }
    fclose(fp);
    nline = nline - 1;
    if (line){ free(line); };
	return 0;
}

int transition_BackToBlack(void){
	SDL_SetRenderDrawBlendMode(render, SDL_BLENDMODE_BLEND);
	SDL_Rect barra = { 0, 0, windowWidth, windowHeight };
		
	int z;
	for (z = 250; z > 0; z = z -10) {
	loadSlide(actualNSlide);
	refreshVolumeArea(iv);
		SDL_SetRenderDrawColor(render, 0, 0, 0, z);
		SDL_RenderFillRect(render, &barra);
		SDL_RenderPresent(render);
	}
		
	return 0;
}


int renderAll(void){
	loadSlide(actualNSlide);
	refreshVolumeArea(iv);
	SDL_RenderPresent(render);
	return 0;
}



// Main
int main(int argc, char ** argv) {
	createWindow();
	loadMod("mods/001.mod");
	loadSlide(1);
	refreshVolumeArea(0);
	SDL_RenderPresent(render);





	while (!quit) {
		SDL_WaitEvent(&evento);

		switch (evento.type) {
			case SDL_KEYDOWN:
				switch (evento.key.keysym.sym) {
					case SDLK_q:
						stopMod();
						quit = true;
						break;
					case SDLK_DOWN:
						if(modVolume > 0) {
							modVolume = modVolume - 10;
							xmp_set_player(ctx, XMP_PLAYER_VOLUME, modVolume);
							iv = iv + 1;
							renderAll();
						}
						break;
					case SDLK_UP:
						if(modVolume < 100) {
							modVolume = modVolume + 10;
							xmp_set_player(ctx, XMP_PLAYER_VOLUME, modVolume);
							iv = iv - 1;
							renderAll();
						}
						break;
					case SDLK_1:
						stopMod();
						loadMod("mods/001.mod");
						break;
					case SDLK_2:
						stopMod();
						loadMod("mods/002.mod");
						break;
					case SDLK_3:
						stopMod();
						loadMod("mods/003.xm");
						break;
					case SDLK_4:
						stopMod();
						loadMod("mods/004.xm");
						break;
					case SDLK_5:
						stopMod();
						loadMod("mods/005.mod");
						break;
					case SDLK_6:
						stopMod();
						loadMod("mods/006.mod");
						break;
					case SDLK_7:
						stopMod();
						loadMod("mods/007.mod");
						break;
					case SDLK_8:
						stopMod();
						loadMod("mods/008.mod");
						break;
					case SDLK_9:
						stopMod();
						loadMod("mods/009.mod");
						break;
					case SDLK_RIGHT:
					    actualNSlide = actualNSlide + 1;
					    if (transition_active == 1 ){ transition_BackToBlack(); };
					    renderAll();
						break;
					case SDLK_LEFT:
					    actualNSlide = actualNSlide - 1;
					    if (transition_active == 1 ){ transition_BackToBlack(); };
						renderAll();
						break;
					case SDLK_F1:
						if (transition_active == 0){
							transition_active = 1;
						}else{
							transition_active = 0;
						}
						break;
				}
				break;
		}


	}

}
