#define DEBUG_PRINT_ENABLE 1
#include <xs1.h>
#include <platform.h>
#include "xua_conf.h"

#include "user_hid.h"
#include "xua_hid_report.h"

#include "xc_ptr.h"

#include "xud.h"
#include "hid.h"
#include "debug_print.h"

#if HID_CONTROLS > 0

#ifdef XSCOPE
#include "print.h"
#endif

#ifdef DFU_CONTROL_USB_HID
#include <xccompat.h>

#define HID_DFU_REPORT_ID 0x41
#endif

#define P_GPI_BUTA_SHIFT        0x00
#define P_GPI_BUTA_MASK         (1<<P_GPI_BUTA_SHIFT)
#define P_GPI_BUTB_SHIFT        0x01
#define P_GPI_BUTB_MASK         (1<<P_GPI_BUTB_SHIFT)
#define P_GPI_BUTC_SHIFT        0x02
#define P_GPI_BUTC_MASK         (1<<P_GPI_BUTC_SHIFT)
#define P_GPI_SW1_SHIFT         0x03
#define P_GPI_SW1_MASK          (1<<P_GPI_SW1_SHIFT)

/* Write HID Report Data into hidData array
 *
 * Bits are as follows:
 * 0: Play/Pause
 * 1: Scan Next Track
 * 2: Scan Prev Track
 * 3: Volume Up
 * 4: Volume Down
 * 5: Mute
 */

unsigned multicontrol_count = 0;
unsigned wait_counter =0;
unsigned long get_reference_time();

#define THRESH 1
#define MULTIPRESS_WAIT 25

#define HID_CONTROL_NEXT 		0x02
#define HID_CONTROL_PLAYPAUSE 	0x01
#define HID_CONTROL_PREV		0x04
#define HID_CONTROL VOLUP       0x08
#define HID_CONTROL_VOLDN		0x10
#define HID_CONTROL_MUTE		0x20

typedef enum
{
	STATE_IDLE = 0x00,
	STATE_PLAY = 0x01,
	STATE_NEXTPREV = 0x02,
}t_controlState;

t_controlState state;

unsigned lastA;

unsigned g_ButtonVal = 0;
unsigned char g_hid_pass_data0;
unsigned char g_hid_pass_data1;
unsigned char g_hid_pass_data2;
unsigned char g_hid_pass_data3;
unsigned char g_hid_pass_data4;
unsigned char g_hid_pass_data5;
unsigned char g_hid_pass_data6;
unsigned char g_hid_pass_data7;

void UserReadHIDButtons(unsigned char hidData[])
{
    unsigned tmp;
    GET_SHARED_GLOBAL(tmp, g_ButtonVal);
    hidData[0] = tmp;
}

void UserReadHIDPass(unsigned char hidPassData[])
{
    int i = 0;
    GET_SHARED_GLOBAL(hidPassData[i++], g_hid_pass_data0);
    GET_SHARED_GLOBAL(hidPassData[i++], g_hid_pass_data1);
    GET_SHARED_GLOBAL(hidPassData[i++], g_hid_pass_data2);
    GET_SHARED_GLOBAL(hidPassData[i++], g_hid_pass_data3);
    GET_SHARED_GLOBAL(hidPassData[i++], g_hid_pass_data4);
    GET_SHARED_GLOBAL(hidPassData[i++], g_hid_pass_data5);
    GET_SHARED_GLOBAL(hidPassData[i++], g_hid_pass_data6);
    GET_SHARED_GLOBAL(hidPassData[i++], g_hid_pass_data7);

    SET_SHARED_GLOBAL(g_hid_pass_data0, 0);
    SET_SHARED_GLOBAL(g_hid_pass_data1, 0);
    SET_SHARED_GLOBAL(g_hid_pass_data2, 0);
    SET_SHARED_GLOBAL(g_hid_pass_data3, 0);
    SET_SHARED_GLOBAL(g_hid_pass_data4, 0);
    SET_SHARED_GLOBAL(g_hid_pass_data5, 0);
    SET_SHARED_GLOBAL(g_hid_pass_data6, 0);
    SET_SHARED_GLOBAL(g_hid_pass_data7, 0);
}

#if DEBUG_MEMORY_LOG_ENABLED

extern unsigned int debug_memory_log_buffer_index;
#define DEBUG_MEMORY_LOG_BUFFER_SIZE 2048
extern unsigned char debug_memory_log_buffer[DEBUG_MEMORY_LOG_BUFFER_SIZE];
unsigned int log_index = 0;

void UserReadHIDLog(unsigned char hidLogData[])
{
    unsafe
    {
        unsigned char * unsafe logPtr =  debug_memory_log_buffer;
        unsigned size =  (debug_memory_log_buffer_index - log_index >= 64) ? 64 : (debug_memory_log_buffer_index - log_index);
        if (size > 0)
        {
            for (int i = 0; i < size; i++)
            {
                hidLogData[i] = logPtr[log_index + i];
            }

            log_index += size;

            if (log_index >= debug_memory_log_buffer_index)
            {
                log_index = 0;
                SET_SHARED_GLOBAL(debug_memory_log_buffer_index, 0);
            }
        }
        else
        {
            for (int i = 0; i < 64; i++)
            {
                hidLogData[i] = 0;
            }

        }

    }
}

#endif

#endif
