#include "console.h"
#include <stdlib.h>

/* Human readable strings for the gestures */
static const char *gestures[] = {
    "-                       ",
    "Levo > Desno            ",
    "Desno > Levo            ",
    "Dol > Gor               ",
    "Gor > Dol               ",
    "Krog desno              ",
    "Krog levo               "
};

int airwheel_global = 0; // 0 - min -> 100 max
int airwheel_last = 0; // last value
int airwheel_last_sent = 0;
int demo_mode = 0;

void init_device(data_t *data)
{
    /* Bitmask later used for starting a stream with
     * SD-, position- and gesture-data
     */
    const int stream_flags = gestic_data_mask_dsp_status |
            gestic_data_mask_gesture | gestic_data_mask_touch |
            gestic_data_mask_airwheel | gestic_data_mask_position |
            gestic_data_mask_sd;

    /* Allocate a new gestic_t-instance */
    data->gestic = gestic_create();

    /* Initialize the gestic_t-instance */
    gestic_initialize(data->gestic);

    /* Open a connection to the device */
    if(gestic_open(data->gestic) < 0) {
        fprintf(stderr, "Ne morem vzpostaviti povezave s 3D tablico.\n");
        exit(-1);
    }

    /* Get pointers to the result-buffers */
    data->gestic_pos = gestic_get_position(data->gestic, 0);
    data->gestic_sd = gestic_get_sd(data->gestic, 0);
    data->gestic_calib = gestic_get_calibration(data->gestic, 0);
    data->gestic_gesture = gestic_get_gesture(data->gestic, 0);
    data->gestic_touch = gestic_get_touch(data->gestic, 0);
    data->gestic_air_wheel = gestic_get_air_wheel(data->gestic, 0);

    /* Reset the device to the default state:
     * - Automatic calibration enabled
     * - All frequencies allowed
     * - Approach detection enabled for power saving
     * - Enable all gestures ( bit 1 to 6 set to 1 = 126 )
     */
    if(gestic_set_auto_calibration(data->gestic, data->auto_calib, 100) < 0 ||
       gestic_select_frequencies(data->gestic, gestic_all_freq, 100) < 0 ||
       gestic_set_approach_detection(data->gestic, 1, 100) < 0 ||
       gestic_set_enabled_gestures(data->gestic, 126, 100) < 0)
    {
        fprintf(stderr, "Ne morem ponastaviti 3D tablice na prevzete vrednosti.\n");
        exit(-1);
    }

    /* Set output-mask to the bitmask defined aboveand stream only changes */
    if(gestic_set_output_enable_mask(data->gestic, stream_flags, 0,
                                     gestic_data_mask_all, 100) < 0)
    {
        fprintf(stderr, "Ne dobivam podatkov s 3D tablice.\n");
        exit(-1);
    }
}

void free_device(data_t *data)
{
    /* Close the connection to the device */
    gestic_close(data->gestic);

    /* Release resources that were associated with the gestic_t-instance */
    gestic_cleanup(data->gestic);

    /* Release the gestic_t-instance itself */
    gestic_free(data->gestic);
}

void update_device(data_t *data)
{
    int i;

    /* Abbreviations for the electrodes */
    const char source[] = { 'J', 'Z', 'S', 'V', 'C' };

    while(gestic_data_stream_update(data->gestic, NULL) == 0)
    {
        /* Print update of the position 
        gotoxy(0, 4);
        if(data->gestic_pos != NULL)
            printf("Polozaj:         X %5d   Y %5d   Z %5d   \n",
                   data->gestic_pos->x, data->gestic_pos->y,
                   data->gestic_pos->z);
        else
            printf("Polozaj:         Ni na voljo\n");
		*/
        /* Print update of gestures */
        gotoxy(0, 3);
        if(data->gestic_gesture != NULL) {
            /* Remember last gesture and reset it after 1s = 200 updates */
            if(data->gestic_gesture->gesture > 0 && data->gestic_gesture->gesture <= 6){
				if (data->last_gesture != data->gestic_gesture->gesture) {
					run_demo_keypress(data->gestic_gesture->gesture);
				}
                data->last_gesture = data->gestic_gesture->gesture;
			}
            else if(data->gestic_gesture->last_event > 200)
                data->last_gesture = 0;
			
			printf("      Gesta: %s \n", gestures[data->last_gesture]);
        } else {
            printf("      Gesta: Ni na voljo\n");
        }

        /* Print update of touch
        gotoxy(0, 6);
        printf("Dotik:            ");
        for(i = 0; i < 5; ++i) {
            if(data->gestic_touch->flags & (1<<i))
                printf("%c ", source[i]);
        }
        printf("           \n");
		*/

        /* Print update of AirWheel */
        gotoxy(0, 4);
        if(data->gestic_air_wheel != NULL) {
			if (data->gestic_air_wheel->counter > airwheel_last) {
				airwheel_last = data->gestic_air_wheel->counter;
				airwheel_global++;
				/*
				if (airwheel_global > 100) {
					airwheel_global = 100;
				}
				*/
				if ((airwheel_global - airwheel_last_sent) > 5) {
					run_demo_keypress(10);
					airwheel_last_sent = airwheel_global;
				}
			}
			else if (data->gestic_air_wheel->counter < airwheel_last) {
				airwheel_last = data->gestic_air_wheel->counter;
				airwheel_global--;
				/*
				if (airwheel_global < 0) {
					airwheel_global = 0;
				}
				*/
				if ((airwheel_global - airwheel_last_sent) < -5) {
					run_demo_keypress(11);
					airwheel_last_sent = airwheel_global;
				}
			}

            printf("Zracno kolo: %d   \n", airwheel_global);
        } else {
            printf("Zracno kolo: Ni na voljo\n");
        }

        /* Print update of Signal Deviation */
        gotoxy(0, 5);
        if(data->gestic_sd != NULL) {
            printf("     Signal:");
            for(i = 0; i < 5; ++i)
                printf(" %c %5.0f  ", source[i], data->gestic_sd->channel[i]);

            if(data->gestic_calib != NULL)
                printf("\nKalibracija: %d",
                       data->gestic_calib->last_event);
        } else {
            printf("Signal: Ni na voljo\n");
        }
    }
}

void switch_auto_calib(data_t *data)
{
    /* Try to swith autocalibration with a timeout of 100 ms */
    int new_mode = !data->auto_calib;
    if(gestic_set_auto_calibration(data->gestic, new_mode, 100) != 0)
        return;
    data->auto_calib = new_mode;
}

void calibrate_now(data_t *data)
{
    /* Try to force calibration with a timeout of 100 ms */
    gestic_force_calibration(data->gestic, 100);
}

void switch_touch_detect(int demo_status) {
	demo_mode = demo_status;
}

void switch_air_wheel(data_t *data) {
    int new_mode = !data->air_wheel;
    if(gestic_set_air_wheel_enabled(data->gestic, new_mode, 100) != 0)
        return;
    data->air_wheel = new_mode;
}

void simulate_key_press(int key) {
	INPUT ip;

	// Set up a generic keyboard event.
	ip.type = INPUT_KEYBOARD;
	ip.ki.wScan = 0; // hardware scan code for key
	ip.ki.time = 0;
	ip.ki.dwExtraInfo = 0;

	ip.ki.wVk = key; 
	ip.ki.dwFlags = 0; // 0 for key press
	SendInput(1, &ip, sizeof(INPUT));

	// Release key
	ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
	SendInput(1, &ip, sizeof(INPUT));
}

void simulate_ctrl_key_press(int key) {
	INPUT ip;

	// Set up a generic keyboard event.
	ip.type = INPUT_KEYBOARD;
	ip.ki.wScan = 0; // hardware scan code for key
	ip.ki.time = 0;
	ip.ki.dwExtraInfo = 0;

	// Press the "Ctrl" key
	ip.ki.wVk = VK_CONTROL;
	ip.ki.dwFlags = 0; // 0 for key press
	SendInput(1, &ip, sizeof(INPUT));

	ip.ki.wVk = key;
	ip.ki.dwFlags = 0; // 0 for key press
	SendInput(1, &ip, sizeof(INPUT));

	// Release key
	ip.ki.wVk = key;
	ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
	SendInput(1, &ip, sizeof(INPUT));

	// Release the "Ctrl" key
	ip.ki.wVk = VK_CONTROL;
	ip.ki.dwFlags = KEYEVENTF_KEYUP;
	SendInput(1, &ip, sizeof(INPUT));
}

void run_demo_keypress(int gesture) {
	if (demo_mode == 0) {
		// plain text on keyboard
		if (gesture == 1) {		// desno
			simulate_key_press(0x44);
			simulate_key_press(0x45);
			simulate_key_press(0x53);
			simulate_key_press(0x4E);
			simulate_key_press(0x4F);
			simulate_key_press(0x0D);
		}
		else if (gesture == 2) { // levo
			simulate_key_press(0x4C);
			simulate_key_press(0x45);
			simulate_key_press(0x56);
			simulate_key_press(0x4F);
			simulate_key_press(0x0D);
		}
		else if (gesture == 3) { // gor
			simulate_key_press(0x47);
			simulate_key_press(0x4F);
			simulate_key_press(0x52);
			simulate_key_press(0x0D);
		}
		else if (gesture == 4) { // dol
			simulate_key_press(0x44);
			simulate_key_press(0x4F);
			simulate_key_press(0x4C);
			simulate_key_press(0x0D);
		}
		else if (gesture == 10) { // vrtimo desno
			simulate_key_press(0x56);
			simulate_key_press(0x52);
			simulate_key_press(0x54);
			simulate_key_press(0x49);
			simulate_key_press(0x4D);
			simulate_key_press(0x4F);

			simulate_key_press(0x20);

			simulate_key_press(0x44);
			simulate_key_press(0x45);
			simulate_key_press(0x53);
			simulate_key_press(0x4E);
			simulate_key_press(0x4F);
			simulate_key_press(0x0D);
		}
		else if (gesture == 11) { // vrtimo levo
			simulate_key_press(0x56);
			simulate_key_press(0x52);
			simulate_key_press(0x54);
			simulate_key_press(0x49);
			simulate_key_press(0x4D);
			simulate_key_press(0x4F);

			simulate_key_press(0x20);

			simulate_key_press(0x4C);
			simulate_key_press(0x45);
			simulate_key_press(0x56);
			simulate_key_press(0x4F);
			simulate_key_press(0x0D);
		}
	}
	else if (demo_mode == 1) {
		// VLC media player
		if (gesture == 1) {		// desno
			simulate_key_press(0x4E); //n - next song
		}
		else if (gesture == 2) { // levo
			simulate_key_press(0x50); //p - previous
		}
		else if (gesture == 3) { // gor
			simulate_key_press(0x20); //space - play
		}
		else if (gesture == 4) { // dol
			simulate_key_press(0x53); //s - stop
		}
		else if (gesture == 10) { // vrtimo desno
			simulate_ctrl_key_press(0x26); // ctrl - up
		}
		else if (gesture == 11) { // vrtimo levo
			simulate_ctrl_key_press(0x28); // ctrl - down
		}
	}
	else if (demo_mode == 2) {
		// Acrobat Reader
		if (gesture == 1) {		// desno
			simulate_key_press(0x27); //next page
		}
		else if (gesture == 2) { // levo
			simulate_key_press(0x25); //previous page
		}
		else if (gesture == 3) { // gor
			simulate_ctrl_key_press(0x4C); //full screen ctrl + l
		}
		else if (gesture == 4) { // dol
			simulate_key_press(0x1B); //exit
		}
		else if (gesture == 10) { // vrtimo desno
			simulate_key_press(0x28); // ctrl - up
		}
		else if (gesture == 11) { // vrtimo levo
			simulate_key_press(0x26); // up
		}
	}
}