/* --COPYRIGHT--,BSD
 * Copyright (c) 2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  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.
 *
 * *  Neither the name of Texas Instruments Incorporated 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 OWNER 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.
 * --/COPYRIGHT--*/
/*
 * demo.c
 *
 *  Created on: Dec 11, 2016
 *      Author: a0272918
 */

/* Include files. */
#include <msp430.h>
#include <driverlib.h>
#include <KeypadDemo.h>
#include "captivate.h"
#include "CAPT_BSP.h"
#include "CAPT_PingPongBuffer.h"
#include "Serial_Drivers/I2CSlave.h"

#ifndef NULL
#define NULL			0
#endif

tCaptivateApplication *local_pApp;
tPingPongBuffer local_PingPongBuffer;

//*****************************************************************************
//
//! static g_ui8TransmitBuffer_ping is the transmit "ping" buffer, used in
//! conjunction with g_ui8TransmitBuffer_pong by g_PingPongBuffer.
//
//*****************************************************************************
static uint8_t local_ui8TransmitBuffer_ping[CAPT_TRANSMIT_BUFFER_SIZE];

//*****************************************************************************
//
//! \static g_ui8TransmitBuffer_pong is the transmit "pong" buffer, used in
//! conjunction with g_ui8TransmitBuffer_ping by g_PingPongBuffer.
//
//*****************************************************************************
static uint8_t local_ui8TransmitBuffer_pong[CAPT_TRANSMIT_BUFFER_SIZE];


/*
 * INDEX INTO BUTTON MAP
 * USE DOMINANT BUTTON AS INDEX INTO THIS ARRAY
 * RESULT IS BUTTON VALUE THAT CAN BE RETURNED
 * EXAMPLE: WHEN BUTTON #1 IS PRESSED, eButton1 is the assigned value
 */
ButtonMap_t buttonMap[] = {eButton0,eButton1,eButton2};

#define DEMO_SLIDER   (sliderSensor_Params)

/* keypad flags */
bool bKeypadActive = false;
bool bSliderActive = false;

/* Guard Channel Flags. */
/* Used to detect new prox events and exit prox events */
bool bProximity = false;
/* Will be used to mute out other callbacks if GC is active */
bool bProxTouch = false;

void CAPT_initInterface(tCaptivateApplication *pApp)
{
	local_pApp = pApp;

	(void)MAP_CAPT_initPingPongBuffer(
				&local_PingPongBuffer,
				local_ui8TransmitBuffer_ping,
				local_ui8TransmitBuffer_pong
			);
}


/* CapTIvate Message                                                                                      			    */
/*  [0]       [1]       [2]       [3]           [4]           [5]        [6]      [7]     [8]      [9]       [10]  		*/
/* Keypad    Keypad #  Keypress  GuardChannel  GuardChannel  Proximity  Buttton  Button   Slider   Slider    Slider     */
/* activity            Pressed   activity      active        activity   activity Pressed  Pressed  Position  Position   */
/* flag                          flag                        flag       flag                       (Upper)   (Lower)    */
uint8_t txBuffer[11];
uint8_t rxBuffer[11];

/*******************************************************************************
 * @fn      touchDetect
 *
 * @brief   callback function to process keypad flags, pack txBuffer and trigger
 *          IRQ.
 * @param   None.
 *
 * @return  None.
 ******************************************************************************/
void touchDetect(tSensor* pSensor)
{
/*    if(bProxTouch){ //if GC is active
        return; //immediately exit
    }*/
	uint16_t dominantButton;

	dominantButton = ((tButtonSensorParams*)(pSensor->pSensorParams))->ui16DominantElement;

	if((NEW_TOUCH) && (bKeypadActive == false))
	{


		// populate our txbuffer for testing
		txBuffer[0] = 0x01; // Keypad
		txBuffer[1] = buttonMap[dominantButton];
		txBuffer[2] = 0x01; // On

		bKeypadActive = true;

		// Set the IRQ line (active low)
		I2CSlave_setRequestFlag();
	}
	else if(TOUCH)
	{
		/* Do nothing */

	}
	else if(EXIT_TOUCH)
	{

		bKeypadActive = false;

		txBuffer[0] = 0x00;
		txBuffer[1] = 0x00;
		txBuffer[2] = 0x00;
		// Set the IRQ line (active low)
		I2CSlave_setRequestFlag();
	}
}

/*******************************************************************************
 * @fn      proximityDetect
 *
 * @brief   callback function to process guard channel flags, pack txBuffer and
 *          trigger IRQ.
 * @param   None.
 *
 * @return  None.
 ******************************************************************************/
void proximityDetect(tSensor* pSensor){
    if((txBuffer[2]) && (txBuffer[8])){    /* if a key is pressed before prox sensor is tripped */
        txBuffer[5] = 0x00; /* mute the prox flag. */
        return;
    }

    if(PROX && (bProximity == false)){


        txBuffer[3] = 0x01;
        txBuffer[5] = 0x01; //there's been a prox detect
        bProximity = true; //raise the prox flag

        // Set the IRQ line (active low)
        I2CSlave_setRequestFlag();
    }
    else if(NO_PROX && (bProximity == true))
    {

        txBuffer[3] = 0x00;
        txBuffer[5] = 0x00;
        bProximity = false;
        // Set the IRQ line (active low)
        I2CSlave_setRequestFlag();
    }
}

/*******************************************************************************
 * @fn      buttonDetect
 *
 * @brief   callback function to process button flags, pack txBuffer and trigger
 *          IRQ.
 * @param   None.
 *
 * @return  None.
 ******************************************************************************/
void buttonDetect(tSensor* pSensor){
/*    if(bProxTouch){ //if GC is active
        return; //immediately return
    }*/
    if(NEW_TOUCH){

        TOUCH_LED_ON;

        // populate the txbuffer
        txBuffer[6] = 0x01; // wheel button press
        txBuffer[7] = 0x01; // Button's been pressed

        // Set the IRQ line (active low)
        I2CSlave_setRequestFlag();
    }
    else if(TOUCH)
    {
        /* Do nothing. */
    }
    else if(EXIT_TOUCH){

        TOUCH_LED_OFF;
		txBuffer[6] = 0x00;
		txBuffer[7] = 0x00;

    }

}

void sliderPosition(tSensor* pSensor){

static	uint8_t SliderPosition;
static	uint8_t ActualPosition = 0;
static	uint8_t temp = 0;

	SliderPosition = ((tSliderSensorParams*)(pSensor->pSensorParams))->SliderPosition.ui16Natural;
	ActualPosition = SliderPosition / 10;

		if((NEW_TOUCH) && (bSliderActive == false))
		{
			temp = ActualPosition;
			// populate our txbuffer for testing
			txBuffer[8] = 0x01; // slider
			txBuffer[9] = 0;
			txBuffer[10] = ActualPosition; // Position

			bSliderActive = true;

			// Set the IRQ line (active low)
			I2CSlave_setRequestFlag();
		}

		else if((TOUCH) && (temp != ActualPosition))
		{
			temp = ActualPosition;
			txBuffer[8] = 0x01; // slider
			txBuffer[9] = 0;
			txBuffer[10] = ActualPosition; // Position
			// Set the IRQ line (active low)
			I2CSlave_setRequestFlag();

		}
		else if (TOUCH)
		{

		}
		else if(EXIT_TOUCH)
		{

			bSliderActive = false;

			txBuffer[8] = 0x00;
			txBuffer[9] = 0x00;
			txBuffer[10] = 0x00;
			// Set the IRQ line (active low)
			I2CSlave_setRequestFlag();
		}

}
/*******************************************************************************
 * @fn      receiveHandler
 *
 * @brief   I2C rx handler for I2C slave port structure
 *
 * @param   uint16_t ui16Length
 *
 * @return  None.
 ******************************************************************************/
bool receiveHandler(uint16_t ui16Length)
{
	return false;
}

/* I2C slave port struct.  */
static const tI2CSlavePort customI2c =
{
	.pbReceiveCallback = &receiveHandler,
	.pvErrorCallback = 0,
	.pReceiveBuffer = rxBuffer,
	.ui16ReceiveBufferSize = 8,
	.bSendReadLengthFirst = false
};

/*******************************************************************************
 * @fn      InitDemo
 *
 * @brief   initializes MSP430 demo app, registers callback functions,
 *          initializes I2C and initializes the captivate app.
 * @param   None.
 *
 * @return  None.
 ******************************************************************************/
void InitDemo(void)
{

	MAP_CAPT_registerCallback(&numericKeypadSensor, &touchDetect);
	MAP_CAPT_registerCallback(&proxAndGuardSensor, &proximityDetect);
	MAP_CAPT_registerCallback(&SLD00, &sliderPosition);

	/*
	 * Setup and initialize the I2C Slave
	 * Make sure IRQ pin is setup in CAPT_BSP.c and
	 * captivate\comm\serial_drivers\i2cslave_definitions.h
	 * Default is P1.1. Current is 2.2.
	 */

	// Open port and pass to it our structure
	I2CSlave_openPort(&customI2c);

	// Need to only do this once - points I2C driver to our txBuffer
	I2CSlave_setTransmitBuffer(&txBuffer[0], 11);

	CAPT_initInterface(&g_uiApp);
}

