#include "system.h"
#include "uart.h"
#include "i2c.h"
#include "tsc2013.h"
#include "timer.h"
#include "haptics.h"

#include "Touch_GestureEngine.h"

typedef union
{
  uint8 buffer[4];
  struct
  {  
    uint16 IX_threshold;
    uint16 IY_threshold;
  }values;
}tsc2013_calibration_threshold;

const unsigned char lra_tick_data[] = 
{    
   0x01, 
   0x01,
   0x00, 
   0x01
};

const Waveform lra_tick = {4, lra_tick_data};

volatile uint16_t g_touch_detected = 0;
extern uint16_t tsc2013_touch_status;
volatile uint16_t g_time_out = 0;

tsc2013_data_set data_set;

uint8  finger_number = 0;
  
uint16 delta_x = 0;
uint16 delta_y = 0;

uint16 finger_pos_x[MAX_FINGER_NUM];
uint16 finger_pos_y[MAX_FINGER_NUM];

uint16 g_calibration_count = 0;
uint32 g_sum_IX = 0;
uint32 g_sum_IY = 0;
uint8  g_calibration_done = 0;
tsc2013_calibration_threshold g_calibration_threshold_array;

static void calculate_finger_pos(void);

int main( void )
{ 
  BYTE bGestureID;
  uint8 i;
  uint16 count;
  
#if (ENABLE_DEBUG_UART & ENABLE_DEBUG_UART_GESTURE_ID)  
  const char *strGesture = 0;
#endif
  
#if ENABLE_DEBUG_UART_GUI  
  uint8 len;
#endif
    
  board_init();

#if (ENABLE_DEBUG_UART)  
  uart1_puts("uart1 ok\n\r");
  uart1_puts("build date : "__DATE__" "__TIME__"\n\r");
#endif
    
  tsc2013_init();

  if ((P6IN & PIN_CAL) == 1)
  {  
    //start calibration routine
    g_calibration_count = 0;
    g_sum_IX = 0;
    g_sum_IY = 0;
    g_calibration_done = 0;
    
    while(1)
    {
      if (g_touch_detected)
      {
        g_touch_detected = 0;
        
        tsc2013_read_touch_status();
        
        if  ((tsc2013_touch_status & 0xf000) == 0xf000)
        {
          tsc2013_read_touch_data(); 
          
          if (!g_calibration_done) 
          {
            //send msg to PC GUI
            g_calibration_count++;
                    
            if ((g_calibration_count >= CALIBRATION_START_COUNT) && 
                (g_calibration_count < (CALIBRATION_START_COUNT + CALIBRATION_LENGTH)))
            {
              count = g_calibration_count - CALIBRATION_START_COUNT;
                
              if (count % 15 == 0)
              { 
              }
             
              g_sum_IX += data_set.values.IX;
              g_sum_IY += data_set.values.IY;
            }
            else
            {
              if (g_calibration_count == (CALIBRATION_START_COUNT + CALIBRATION_LENGTH))
              {
                g_sum_IX >>= 8;
                g_sum_IY >>= 8;
                
                g_calibration_done = 1;
                
                //write IX & IY value to Flash
                g_calibration_threshold_array.values.IX_threshold = ((g_sum_IX & 0xffff) + 5);
                g_calibration_threshold_array.values.IY_threshold = ((g_sum_IY & 0xffff) + 5);

#if (ENABLE_DEBUG_UART)      
                uart1_puts("calibration done\n\r");
  
                uart1_printf("IX = %d\n\r", g_calibration_threshold_array.values.IX_threshold);
                uart1_printf("IY = %d\n\r", g_calibration_threshold_array.values.IY_threshold);
#endif
                flash_write_array(g_calibration_threshold_array.buffer, 4, 0);
                
                break;
              }
            }
          }
        }
      }
    }
  }
  
  timer_init();
  
  TouchpathGestureEngine_Initialize();

#if (ENABLE_DEBUG_UART)      
  uart1_puts("calibration threshold\n\r");
  for(i = 0; i < 4; i++)
  {
    g_calibration_threshold_array.buffer[i] = flash_read_byte(i);
    
    uart1_printf("[%d] = 0x%x\n\r",i, g_calibration_threshold_array.buffer[i]);
  }
  
  uart1_printf("IX = %d\n\r", g_calibration_threshold_array.values.IX_threshold);
  uart1_printf("IY = %d\n\r", g_calibration_threshold_array.values.IY_threshold);
#endif
      
  while(1)
  {
    if (g_time_out)
    {
      g_time_out = 0;

#if (ENABLE_DEBUG_UART)      
      uart1_puts("finger off\n\r"); 
#endif
      
      TouchpathGestureEngine_Initialize();
    }
    
    if (g_touch_detected)
    {
      g_touch_detected = 0;
      
      tsc2013_read_touch_status();
      
      if  ((tsc2013_touch_status & 0xf000) == 0xf000)
      {
        tsc2013_read_touch_data(); 
        
        calculate_finger_pos();
        
        finger_number = 1;       
           
        if ((data_set.values.IX > g_calibration_threshold_array.values.IX_threshold) || 
            (data_set.values.IY > g_calibration_threshold_array.values.IY_threshold))
        {
           finger_number = 2;
          
           if (data_set.values.Z1 > Z1_THRESHOLD)
           {
             delta_x = (data_set.values.IX);
             delta_y = (data_set.values.IY);
             
  #if (ENABLE_DEBUG_UART & ENABLE_DEBUG_UART_RAW_DATA)           
             uart1_printf("2(%3d,%3d)\n\r", delta_x, delta_y);
  #endif
             
             TouchpathGestureEngine_SetDeltaXY(delta_x,delta_y,data_set.values.X1,data_set.values.Y1,data_set.values.X2,data_set.values.Y2);
             bGestureID = TouchpathGestureEngine_GetGestureID(2);
                          
             if (bGestureID)
             {
  #if (ENABLE_HAPTICS & ENABLE_HAPTICS_DRV2603)                 
               haptics_send_waveform(&lra_tick);
  #endif
                 
  #if (ENABLE_DEBUG_UART & ENABLE_DEBUG_UART_GESTURE_ID) 
               strGesture = get_gesture_string(bGestureID);
               if (strGesture)
               {
                 uart1_printf("%s\n\r", strGesture);
               }
  #endif
             }
           }
           else
           {
#if (ENABLE_DEBUG_UART)                
              uart1_printf("(%3d,%3d) filter out\n\r", data_set.values.IX, data_set.values.IY);
#endif             
           }
        }
        
        if(finger_number == 1)
        {  
#if (ENABLE_DEBUG_UART & ENABLE_DEBUG_UART_RAW_DATA)           
          uart1_printf("1(%3d,%3d)\n\r", finger_pos_x[0], finger_pos_y[0]);
#endif
                    
           TouchpathGestureEngine_SetXY(finger_pos_x[0], finger_pos_y[0]);
           bGestureID = TouchpathGestureEngine_GetGestureID(1);
          
           if (bGestureID)
           {
               if ((bGestureID >= ST_FLICK_SLOW_UP) && (bGestureID <= ST_FLICK_FAST_LEFT))
               {
                 TouchpathGestureEngine_Initialize();

#if (ENABLE_HAPTICS & ENABLE_HAPTICS_DRV2603)                 
                 haptics_send_waveform(&lra_tick);
#endif
               }
               
               if (bGestureID == ST_FLICK_SLOW_UP)
               {
                 bGestureID = ST_FLICK_SLOW_DOWN;
               }
               else if (bGestureID == ST_FLICK_SLOW_DOWN)
               {
                 bGestureID = ST_FLICK_SLOW_UP;
               }
             
#if (ENABLE_DEBUG_UART & ENABLE_DEBUG_UART_GESTURE_ID) 
               strGesture = get_gesture_string(bGestureID);
               if (strGesture)
               {
                 uart1_printf("%s\n\r", strGesture);
               }
#endif
           }
        }
        
        timer_start();
      }
    }
  }
}

void calculate_finger_pos(void)
{
  if (data_set.values.X1 >= data_set.values.X2)
  {
    finger_pos_x[0] = data_set.values.X2 + ((data_set.values.X1 - data_set.values.X2) >> 1);
  }
  else
  {
    finger_pos_x[0] = data_set.values.X1 + ((data_set.values.X2 - data_set.values.X1) >> 1);         
  }
  
  if (data_set.values.Y1 >= data_set.values.Y2)
  {
    finger_pos_y[0] = data_set.values.Y2 + ((data_set.values.Y1 - data_set.values.Y2) >> 1);
  }
  else
  {
    finger_pos_y[0] = data_set.values.Y1 + ((data_set.values.Y2 - data_set.values.Y1) >> 1);         
  }
  
  finger_pos_x[0] = 4096 - finger_pos_x[0];
  finger_pos_y[0] = 4096 - finger_pos_y[0];  
}