/**************************************************************************//**
 * @file         Touch.h
 * @brief        Touch driver class for VK-LCD panels
******************************************************************************/

#ifndef MBED_TOUCH_H
#define MBED_TOUCH_H

#include "mbed.h"
#include <string>
#include "stmpe811iic.h"

    /*! @enum Touch_type_t
    	@brief Type of the touch controller
    */
    typedef enum {
    	RESISTIVE = 0, /*!< Resistive */
    	CAPACITIVE     /*!< Capacitive */
    } Touch_type_t;

    /*! @enum Touch_interface_type_t
        @brief Communication interface
    */
    typedef enum {
    	I_2_C = 0, 		 /*!< I2C */
    	S_P_I     		 /*!< SPI */
    } Touch_communication_type_t;

    /*! @enum IRQ_trigger_t
    	@brief Type of the interrupt
    */
    typedef enum {
    	INT_ON_EDGE  = 0,   /*!< generate INT on front change */
    	INT_ON_LEVEL        /*!< generate INT on active level */
    } IRQ_trigger_t;

    /*! @enum IRQ_polarity_t
        @brief Edge of a signal
    */
    typedef enum {
    	RISING_OR_ACTIVE_HI  = 0, /*!< Rising edge/HI level     */
    	FALLING_OR_ACTIVE_LO      /*!< Falling edge/LOW level   */
    } IRQ_polarity_t;

    /*! @struct touch_config_t
    	@brief Touch Config structure
    */
    typedef struct {
    	string			name;				/*!< Name of the Touch driver */
        int				screen;				/*!< reserved				  */
        Touch_type_t	type;				/*!< Resistive or Capacitive  */
        struct {							/*!< I2C or SPI & the pins of selected periphery */
        	Touch_communication_type_t type;
        	PinName sda;
        	PinName scl;
        	PinName mosi;
        	PinName miso;
        	PinName sclk;
        	PinName ssel;
        	int 	freq;
        }interface;
        struct {							/*!< IRQ : front and pin of selected periphery */
        	IRQ_trigger_t	trigger;
            IRQ_polarity_t	polarity;
            PinName			pin;
        }activity_irq;
    }touch_config_t;

extern const touch_config_t STMPE811_cfg;

/*! @class Touch
 *  @brief Touch driver class for VK-LCD panels
 */

class Touch : public I2C, public InterruptIn
{
public:
    /*! @enum Init_err_t
        @brief Error codes
     */
    typedef enum {
        TOUCH_OK = 0,                   /*!< Initialization successful      */
        TOUCH_INIT_ERR = -1,           	/*!< Communication interface err while configuring driver */
		TOUCH_UNSUPP_ERR = -2,			/*!< Unsupported driver */
        TOUCH_ERR = -3,         		/*!< unknown error */
    } init_err_t;

    /** Constructor method of Touch object
    */
    Touch( const touch_config_t * tp_cfg = &STMPE811_cfg );

    /** Destructor method of Touch object
    */
    virtual ~Touch( void );

    /** Touch controller initialization
     *  @retval       Error code
     */
    init_err_t Init( void );

    /** New Data available
     */
    static void Irq_Alert( void );

    /** Set Calibration data (raw data interpretation)
     *  @retval       Error code
     */
    virtual init_err_t Clb_Setup(void);

    /** Set Touch Controller settings
    *  @retval       Error code
    */
    virtual init_err_t Drv_Setup(void);

    /** Get one sample of data
     *  @param[in]   raw: pointer to ring buffer to store the samples
     */
    virtual void Get_Data( unsigned long long * raw );

    /** Get all available samples of data
     *  @param[in]   raw: pointer to ring buffer to store the samples
     *  @retval           samples count
     */
    virtual int Get_Fifo( unsigned long long * raw );

    /** Transfer function (from raw coordinates to screen coordinates)
     *  @param[in]	 points : number of samples to transfer
     */
    virtual void Get_XYZ( int points );

    /** Pull the new samples if new data is available
     *  @param[in]   pts: pointer to a variable to put the count of the new samples
     *  @retval       	  Status of the pen => up:false;  down:true
     */
    bool Handle_touch( unsigned char *pts );

    /** Get index of the last sample in the ring buffer
     */
    int Get_Last_Idx( void );

    short x;
	short y;
	float z;
	const touch_screen_data_t *xyz_data;

	unsigned short adc_x;
	unsigned short adc_y;
	unsigned short adc_z;
	const touch_raw_data_t *adc_data;

protected:
    static bool			 new_data;
    int					 last_xyz_idx;
    touch_raw_data_t	 raw_data[FIFO_DEPTH];
    touch_screen_data_t  screen_data[FIFO_DEPTH];
    const touch_config_t *touch_cfg;
    touch_calib_data_t	 calib;
};

#endif /* MBED_TOUCH_H */

