#include <Arduino.h>
#include "abc800_usb.h"
#include "abc800_hidboot.h"
#include "abc800_config.h"
#include "abc800_gpio.h"
#include "EspUsbHost.h"
extern TimerHandle_t repeat_delay_timer_out;
extern TimerHandle_t repeat_timer_out;
extern TaskHandle_t Keyboard_Task_Out;
extern TaskHandle_t Keyboard_ABC800_Task_In;
extern QueueHandle_t abc800_key_queue_out;
 KeyboardReportParser keyparse;
uint8_t old_key = 0x00;
key800queue key800queueold; 
static const char TAG[] = __FILE__;
void  onRepeatTimer_out(TimerHandle_t xTimer) {
  if (xQueueSend(abc800_key_queue_out, (void *)&key800queueold, 0) != pdTRUE) {
    ESP_LOGE(TAG,"Queue full");
  }
   xTimerStart(repeat_timer_out, portMAX_DELAY);
}

void onProductString(char *str)
{
  ESP_LOGI(TAG,"%s",str);
}

void onManufacturerString(char *str)
{
   ESP_LOGI(TAG,"%s",str);
}


static void hid_dataout_cb()
{
      ESP_LOGI(TAG,"DATA out return");
}



void abc800_port_init(){

    repeat_timer_out = xTimerCreate(
                      "Repeat Timer",        // Name of timer
                      ABC800_KEY_REPEAT_TIME / portTICK_PERIOD_MS,  // Period of timer (in ticks)
                      pdFALSE,                     // Auto-reload
                      (void *)0,                  // Timer ID
                      onRepeatTimer_out); 
    repeat_delay_timer_out = xTimerCreate(
                      "Repeat Delay Timer",           // Name of timer
                      ABC800_KEY_REPEAT_TIME_DELAY/ portTICK_PERIOD_MS,  // Period of timer (in ticks)
                      pdFALSE,                    // Auto-reload
                      (void *)1,                  // Timer ID
                      onRepeatTimer_out); 
                      
}
namespace abc800 {

    void UsbHost800::onKeyboardKey(uint8_t ascii, uint8_t keycode, uint8_t modifier) {
      /*if (' ' <= ascii && ascii <= '~') {
        Serial.printf("%c %i\n", ascii,keycode);
      } else if (ascii == '\r') {
        Serial.println();
      }*/
    };
    void UsbHost800::onKeyboard(hid_keyboard_report_t report, hid_keyboard_report_t last_report){
        ohid_datain_cb(report);
      
    };
    void UsbHost800::ohid_datain_cb(hid_keyboard_report_t report)
    {

          ESP_LOGD(TAG, "mod: %02x", report.modifier);
          ESP_LOGD(TAG, "Key: %02x", report.keycode[0]);
          if (!(int8_t)report.keycode[0]){ //CHECK UP DOWN PMPMPM
            xTimerStop(repeat_delay_timer_out, portMAX_DELAY);
            xTimerStop(repeat_timer_out, portMAX_DELAY);
          }
          uint8_t key = report.keycode[0];
          uint8_t mod = report.modifier;
          keyparse.Parse(report.keycode);

          if (key!=0){
            digitalWrite(K800_RST,1);
            key800queue key800queue ;
            key800queue.special = 0x00;
            key800queue.ascii = keyparse.OemToAscii(mod,key);
            key800queue.modifier = mod;
            if (key800queue.ascii== 0x00 && key!=0x00){
              key800queue.special = key;
            }
            if (key!=0x00 || key800queue.special!=0x00){
              
              if (old_key!=key)
              {
                // RESET
                if (key800queue.modifier==0x05 && key ==0x4c) 
                {
                  if (!xTaskNotifyFromISR(Keyboard_ABC800_Task_In, ABC800_KEY_RESET, eSetValueWithoutOverwrite,NULL))
                  {
                      ESP_LOGE(TAG,"Could not notify task");
                  }
                }
                else
                {
                  if (xQueueSend(abc800_key_queue_out, (void *)&key800queue, 0) != pdTRUE) {
                    ESP_LOGE(TAG,"Queue full");
                  }
                  key800queueold=key800queue;
                  xTimerStart(repeat_delay_timer_out, portMAX_DELAY);
                }
              }
              
            }
  
          }else{
            digitalWrite(KEY800_LED,LOW);
          }
          old_key=key;

  }

}

