/* ========================================
 *
 * Copyright YOUR COMPANY, THE YEAR
 * All Rights Reserved
 * UNPUBLISHED, LICENSED SOFTWARE.
 *
 * CONFIDENTIAL AND PROPRIETARY INFORMATION
 * WHICH IS THE PROPERTY OF your company.
 *
 * ========================================
*/
/*****************************************************************************
* Included headers
*****************************************************************************/

#include <BLE_Process.h>
#include "stdbool.h"
#include <project.h>
#include "BLE_Process.h"
#include <main.h>
#include <animations.h>


/*****************************************************************************
* Macros and constants
*****************************************************************************/
#define             REFRESH_INTERVAL                    (1000u)

/* Connection handle used for transmitting information over BLE */
CYBLE_CONN_HANDLE_T  connectionHandle;	

/*****************************************************************************
* Static variables 
*****************************************************************************/

/* 'rgbHandle' stores RGB control data parameters */
CYBLE_GATT_HANDLE_VALUE_PAIR_T		rgbHandle;	
CYBLE_GATT_HANDLE_VALUE_PAIR_T		AnimationHandle;	


/*This flag is set when the Central device writes to CCC (Client Characteristic 
* Configuration) of the CapSense slider Characteristic to enable notifications */
// uint8 sendCapSenseSliderNotifications = FALSE;	

/* Array to store the present RGB LED control data. The 4 bytes 
* of the array represents {R, G, B, Intensity} */
uint8 RGBledData[4];
uint8 Animationdata;

/* This flag is used by application to know whether a Central 
* device has been connected. This is updated in BLE event callback 
* function*/
uint8 deviceConnected = FALSE;
uint8 showanimation = TRUE;
/*****************************************************************************
* Public variables 
*****************************************************************************/
bool enterHibernateFlag = false;


/*******************************************************************************
* Function Name: CustomEventHandler
********************************************************************************
* Summary:
* Call back event function to handle various events from BLE stack
*
* Parameters:
*  event:		event returned
*  eventParam:	link to value of the events returned
*
* Return:
*  void
*
*******************************************************************************/
void CustomEventHandler(uint32 event, void * eventParam)
{
    /* Local variable to strore the write request parameters */
	CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam;
    
  
    switch(event)
    {
        case CYBLE_EVT_STACK_ON:
        	/* Start Advertisement and enter Discoverable mode*/
			CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
			break;
			
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
            /* Enter hibernate mode upon disconnect */
			// enterHibernateFlag = true;
            CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
        break;
            
		case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
			/* Set the BLE state variable to control LED status */
            if(CYBLE_STATE_DISCONNECTED == CyBle_GetState())
            {
                /* Start Advertisement and enter Discoverable mode*/
                CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            }
			break;
			
        case CYBLE_EVT_GATT_CONNECT_IND:
			/* This flag is used in application to check connection status */
			deviceConnected = TRUE;
            // GREEN_Write(0xFF);
			break;
        
        case CYBLE_EVT_GATT_DISCONNECT_IND:
			/* Update deviceConnected flag*/
			deviceConnected = FALSE;
            showanimation = TRUE;
			// GREEN_Write(0x0);
			/* Reset CapSense notification flag to prevent further notifications
			 * being sent to Central device after next connection. */
            CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            
			break;
        
            
        case CYBLE_EVT_GATTS_WRITE_REQ: 							
            /* This event is received when Central device sends a Write command 
             * on an Attribute. 
             * We first get the attribute handle from the event parameter and 
             * then try to match that handle with an attribute in the database.
             */
            wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam;
            

            /* This condition checks whether the RGB LED characteristic was
             * written to by matching the attribute handle.
             * If the attribute handle matches, then the value written to the 
             * attribute is extracted and used to drive RGB LED.
             */
            
            /* Extract the attribute handle for the RGB LED characteristic 
             * from the custom service data structure.
             */
             
            /* if (attributeHandle == RGB LED Characteristic Handle) */
            if(wrReqParam->handleValPair.attrHandle == cyBle_customs[RGB_LED_SERVICE_INDEX].\
								                        customServiceInfo[RGB_LED_CHAR_INDEX].\
                                                        customServiceCharHandle)
            {
                showanimation = FALSE;
                /* Extract the value of the attribute from the handle-value 
                 * pair database. */
                RGBledData[RED_INDEX] = wrReqParam->handleValPair.value.val[RED_INDEX];
                RGBledData[GREEN_INDEX] = wrReqParam->handleValPair.value.val[GREEN_INDEX];
                RGBledData[BLUE_INDEX] = wrReqParam->handleValPair.value.val[BLUE_INDEX];
                RGBledData[INTENSITY_INDEX] = wrReqParam->handleValPair.value.val[INTENSITY_INDEX];
                
                /* Update the PrISM components and the attribute for RGB LED read 
                 * characteristics */
                UpdateRGBled();
            }

            if(wrReqParam->handleValPair.attrHandle == cyBle_customs[ANIMATION_SERVICE_INDEX].\
								                        customServiceInfo[ANIMATION_CHAR_INDEX].\
                                                        customServiceCharHandle)
            {
                Animationdata = wrReqParam->handleValPair.value.val[ANIMATION_SELECTOR_INDEX];
               
                Set_AnimationSelector(Animationdata);
                /* Update RGB control handle with new values */
                // rgbHandle.attrHandle = RGB_LED_CHAR_HANDLE;
	            AnimationHandle.attrHandle = ANIMATION_CHAR_HANDLE;
	            AnimationHandle.value.val = wrReqParam->handleValPair.value.val;
	            AnimationHandle.value.len = sizeof(Animationdata);
	            AnimationHandle.value.actualLen = sizeof(Animationdata);
	            
                
            	/* Send updated Animation-Control handle as attribute for read by central device */
            	CyBle_GattsWriteAttributeValue(&AnimationHandle, FALSE, &cyBle_connHandle, FALSE);  
                            
            }
            
     	
			/* Send the response to the write request received. */
			CyBle_GattsWriteRsp(cyBle_connHandle);
			
			break;

        default:

       	 	break;
    }
}

/*******************************************************************************
* Function Name: UpdateRGBled
********************************************************************************
* Summary:
* Receive the new RGB data and modify PrISM parameters. Also, update the
* read characteristic handle so that the next read from the BLE central device
* gives present RGB color and intensity data.
*
* Parameters:
*  void
*
* Return:
*  void
*
*******************************************************************************/
void UpdateRGBled(void)
{
	/* Local variables to calculate the color components from RGB received data*/
	uint8 debug_red;
	uint8 debug_green;
	uint8 debug_blue;
	uint8 intensity_divide_value = RGBledData[INTENSITY_INDEX];
	
	debug_red = (uint8)(((uint16)RGBledData[RED_INDEX] * intensity_divide_value) / 255);
	debug_green = (uint8)(((uint16)RGBledData[GREEN_INDEX] * intensity_divide_value) / 255);
	debug_blue = (uint8)(((uint16)RGBledData[BLUE_INDEX] * intensity_divide_value) / 255);
	
	Display_new_Color(debug_red,debug_green,debug_blue);
    
    
	/* Update RGB control handle with new values */
	rgbHandle.attrHandle = RGB_LED_CHAR_HANDLE;
	rgbHandle.value.val = RGBledData;
	rgbHandle.value.len = sizeof(RGBledData);
	rgbHandle.value.actualLen = sizeof(RGBledData);
	
	/* Send updated RGB control handle as attribute for read by central device */
	CyBle_GattsWriteAttributeValue(&rgbHandle, FALSE, &cyBle_connHandle, FALSE);  
}

/* [] END OF FILE */
