/*
keyboard.c
Contains simplified functions for keyboard that use allegro 5 as a base.
author: 
*/



#include <stdbool.h>
#include <stdio.h>

#include <allegro5\allegro.h>

#include "keyboard.h"


bool keyboard_key[ALLEGRO_KEY_MAX];		// Array of key states (true/false - down/up)



/* Initialises keyboard:
	-installs allegro keyboard
	-sets all keys to false
	-attaches keyboard events to event_queue
*/
void keyboard_init(void) {
	print_log("Initializing keyboard stuff:\n");


	/* Installs allegro keyboard. */
	print_log("\tInitializing keyboard...\n");
	if (!al_install_keyboard()) {
		error_log("\tERROR - Exiting");
	}
	print_log("\tDONE\n");

	/* Sets all keys to false. */
	print_log("\tSetting all keys to false...\n");
	for (int i = 0; i < ALLEGRO_KEY_MAX; i++) {
		keyboard_key[i] = false;
	}
	print_log("\tDONE\n");
	

	/* Create keyboard event queue. */
	print_log("\tCreating keyboard event queue...\n");
	keyboard_event_queue = al_create_event_queue();
	if (keyboard_event_queue == NULL) {
		error_log("\tERROR - Exiting");
	}
	print_log("\tDONE\n");

	
	/* Attach keyboard to event queue. */
	print_log("\tRegistering keyboard event source...\n");
	al_register_event_source(keyboard_event_queue, al_get_keyboard_event_source());
	print_log("\tDONE\n");

	print_log("DONE\n");
}



/* Gets keyboard changes from event_queue. If more "real-time" readings are needed call this function just before checking key state. */
void keyboard_receive(void) {
	/* Checks if there is anything in keyboard_event_queue */
	if (!al_is_event_queue_empty(keyboard_event_queue)) {

		/* Get whats on queue and continue. For continuous run (not dependent on next keyboard input) use get_next. */
		al_get_next_event(keyboard_event_queue, &keyboard_event);
		//al_drop_next_event(keyboard_event_queue);
		//al_wait_for_event(event_queue, &keyboard_event);
		//al_peek_next_event(event_queue, &keyboard_event);

		/* Reads event from queue and acts accordingly */
		switch (keyboard_event.type) {
		case ALLEGRO_EVENT_KEY_DOWN:
			keyboard_key[keyboard_event.keyboard.keycode] = true;
			//print_log("keyboard_event.keyboard.keycode = %i  %i  DOWN\n", ev.keyboard.keycode, keyboard_key[ev.keyboard.keycode]);
			break;
		case ALLEGRO_EVENT_KEY_UP:
			keyboard_key[keyboard_event.keyboard.keycode] = false;
			//print_log("keyboard_event.keyboard.keycode = %i  %i  UP\n", ev.keyboard.keycode, keyboard_key[ev.keyboard.keycode]);
			break;
		default: break;
		}

		/* Checks if there is anything left in queue - if there is receive it */
		if (!al_is_event_queue_empty(keyboard_event_queue)) {
			//printf("\nkey_queue not empty");
			al_peek_next_event(keyboard_event_queue, &keyboard_event);
			//printf("\n key = %i", keyboard_event.keyboard.keycode);
			keyboard_receive();
		}
	}
}



/* Returns state of the key. If more "real-time" readings are needed call keyboard_receive() just before checking key state. */
bool keyboard_check_key(int key) {
	if (keyboard_key[key] == true)
		return true;
	return false;
}



/* Toggles (inverts) key state. */
void keyboard_toggle_key(int key) {
	switch (keyboard_key[key]) {
	case false:
		keyboard_key[key] = true;
		break;
	case true:
		keyboard_key[key] = false;
		break;
	}
}