/*
 * Copyright 2015-2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2018 NXP
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 * 
 * 3. Neither the name of copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"

#include "usb_device_class.h"
#include "usb_device_hid.h"

#include "usb_device_ch9.h"
#include "usb_device_descriptor.h"

#include "usb_device_composite.h"
#include "datawork.h"
#include "key_codes.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

typedef struct _usb_device_hid_keyboard_struct
{
    uint8_t *buffer;
    uint8_t idleRate;
} usb_device_hid_keyboard_struct_t;

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

static usb_status_t USB_DeviceHidKeyboardAction(void);

/*******************************************************************************
 * Variables
 ******************************************************************************/

extern char g_holdk;
extern char sendFlag;
USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_KeyboardBuffer[USB_INTERFACE_0_HID_KEYBOARD_INPUT_REPORT_LENGTH];
static usb_device_composite_struct_t *s_UsbDeviceComposite;
static usb_device_hid_keyboard_struct_t s_UsbDeviceHidKeyboard;

/*******************************************************************************
 * Code
 ******************************************************************************/
static usb_status_t USB_DeviceHidKeyboardAction(void)
{
    static int x = 0U;
//    enum
//    {
//        DOWN,
//        UP
//    };
    s_UsbDeviceHidKeyboard.buffer[2] = 0x00U;
    if(g_StrBuf[x]=='\0')
    {
    	for(int i = 0;i<20;i++)
    	{
    		 g_StrBuf[i] = '\0';
    	}
    	 //strcpy(g_StrBuf,"");
    	x = 0U;
    	sendFlag = 0;
    }
    else if(!g_holdk)
    {
    	s_UsbDeviceHidKeyboard.buffer[2] = cNumericToKey(g_StrBuf[x]);
    	x++;
    }

    return USB_DeviceHidSend(s_UsbDeviceComposite->interface0HidKeyboardHandle, USB_INTERFACE_0_HID_KEYBOARD_EP_1_INTERRUPT_IN,
                             s_UsbDeviceHidKeyboard.buffer, USB_INTERFACE_0_HID_KEYBOARD_INPUT_REPORT_LENGTH);
}

void callKeyboardAction(void)
{
	USB_DeviceHidKeyboardAction();
}

/* Interface callback */
usb_status_t USB_DeviceInterface0HidKeyboardCallback(class_handle_t handle, uint32_t event, void *param)
{
    usb_status_t error = kStatus_USB_Error;

    switch (event)
    {
        case kUSB_DeviceHidEventSendResponse:
            if (s_UsbDeviceComposite->attach)
            {
                //return USB_DeviceHidKeyboardAction();

            	if(sendFlag!=0)
            	{
            		error = USB_DeviceHidKeyboardAction();
            	}
            	else
            	{
            		error = kStatus_USB_Success;
            	}
            }
            break;
        case kUSB_DeviceHidEventGetReport:
        case kUSB_DeviceHidEventSetReport:
        case kUSB_DeviceHidEventRequestReportBuffer:
            error = kStatus_USB_InvalidRequest;
            break;
        case kUSB_DeviceHidEventGetIdle:
        case kUSB_DeviceHidEventGetProtocol:
        case kUSB_DeviceHidEventSetIdle:
        case kUSB_DeviceHidEventSetProtocol:
            break;
        default:
            break;
    }

    return error;
}

/* set Configuration */
usb_status_t USB_DeviceInterface0HidKeyboardSetConfiguration(class_handle_t handle, uint8_t configuration_idx)
{
   if (USB_COMPOSITE_CONFIGURATION_INDEX == configuration_idx)
   {
       return USB_DeviceHidKeyboardAction();
   }
   return kStatus_USB_Error;
}

usb_status_t USB_DeviceInterface0HidKeyboardSetInterface(class_handle_t handle, uint8_t alternateSetting)
{
   USB_DeviceHidKeyboardAction();
   return kStatus_USB_Error;
}

usb_status_t USB_DeviceInterface0HidKeyboardInit(usb_device_composite_struct_t *deviceComposite)
{
    s_UsbDeviceComposite = deviceComposite;
    s_UsbDeviceHidKeyboard.buffer = s_KeyboardBuffer;
    return kStatus_USB_Success;
}
