/********************************** (C) COPYRIGHT ******************************
* File Name          :usb_driver.h
* Author             : DL
* Version            : V1.1
* Date               : 2020/06/02
* Description        : A demo for USB compound device created by CH552, support
					   touch panel , and HID-compliant device.
********************************************************************************/
#include "TouchInclude.h"

UINT16  wTwoPointsCoorYBak[2];	 //备份Y坐标，用来判断角落是否有两指滑动
BOOL bTwoFingersMoveDown = 0;	 //双指下滑
UINT8  byTwoTouch = 0;            //双指按下计算用

extern UINT8 TouchNum;

#ifdef GESTURE
UINT8 byTouchNumberChange = 0;  //双指点击时记录手指数变化
UINT8 byTouchTime1 = 0;	        //单指点击时计时
UINT8 byTouchTime2 = 0;	        //双指点击时计时
UINT16 wCoorXBak[5];	        //备份X坐标，用来判断是否有滑动
UINT16 wCoorYBak[5];	        //备份Y坐标，用来判断是否有滑动
UINT8 byFirstTouch = 0;	        //用于双指第一次按下去抖
BOOL bMoveFlag = 0;		        //双指滑动标志
BOOL bclickFlag = 0;	        //双指点击标志
UINT8 byWheelUpDown = 0;        //双指滑动后滚轮上下滚动标志

#define LEFT_RIGHT_MOVE_DIS 600
#define UP_DOWN_MOVE_DIS 600
#define FIVE_MOVE_DIS 400
UINT8 byFourTouch = 0;
UINT8 byFiveTouch = 0;
UINT8 FourfingersGesture(void);
UINT8 byLeftRightMoveFlag = 0;  //左右滑动的标志
UINT8 byUpDownMoveFlag = 0;  //上下滑动的标志
BOOL bUpDowntMoveCtrl = 0;	 //上下滑动，上报键值之后要上报ctrl键
UINT16 wDisCoorX[4];
UINT16 wDisCoorY[4];
UINT16 wDisCoorXbak[4];
UINT16 wDisCoorYbak[4];
BOOL bFiveFingersMoveInFlag = 0;
BOOL bFiveFingersMoveOutFlag = 0;
extern UINT8 TouchNumBak;
extern BOOL bTwoFingerCoorBak;
extern UINT8 TouchCount;		   //手指按下帧数记录，要延迟3帧才上报鼠标

/*******************************************************************************
* Function Name  : WheelMove
* Description    : 检测双指滑动
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void WheelMove()
{
	byWheelUpDown = 0; 	//每次清0重新判断

	if (TouchNum == 0)
	{
		byFirstTouch = 0;
	}
	else if (TouchNum == 2)
	{

		if (byFirstTouch == 0)
		{
			byFirstTouch++;		  //要去抖一次，否则坐标不对
		}
		else if(byFirstTouch == 1)
		{

			byFirstTouch = 3;

			wCoorXBak[0] = TP[0].X_pos;			 //备份坐标，用来做距离判断滑动
			wCoorXBak[1] = TP[1].X_pos;

			wCoorYBak[0] = TP[0].Y_pos;
			wCoorYBak[1] = TP[1].Y_pos;
		}
		else if (byFirstTouch > 1)
		{
			//左右滑动也要判断，以免识别成点击
			if (TP[0].X_pos + 100 < wCoorXBak[0] && TP[1].X_pos + 100 < wCoorXBak[1])
			{
				bMoveFlag = 1;	 //置滑动标志，有滑动就不会识别成点击
			}
			else if (TP[0].X_pos > wCoorXBak[0] + 100 && TP[1].X_pos > wCoorXBak[1] + 100)
			{
				bMoveFlag = 1;
			}
			else if (TP[0].Y_pos + 20 < wCoorYBak[0] && TP[1].Y_pos + 20 < wCoorYBak[1])	//Up
			{
				bMoveFlag = 1;

				byWheelUpDown = 1;
			}
			else if (TP[0].Y_pos > wCoorYBak[0] + 20 && TP[1].Y_pos > wCoorYBak[1] + 20)   //Down
			{
				bMoveFlag = 1;

				byWheelUpDown = 2;
			}

			if (bMoveFlag)		//有滑动了，重新备份坐标来判断距离
			{
				wCoorXBak[0] = TP[0].X_pos;
				wCoorXBak[1] = TP[1].X_pos;

				wCoorYBak[0] = TP[0].Y_pos;
				wCoorYBak[1] = TP[1].Y_pos;
			}
		}
	}
}

 /*******************************************************************************
* Function Name  : TwoPointsClick
* Description    : 检测双指点击，有下面4种情况：
					1、双指同时点击，同时松开
					2、双指同时点击，松开时一指先离开，另一指再离开
					3、单指先触摸到，紧接着双指触摸，双指同时松开
					4、单指先触摸到，紧接着双指触摸，松开时一指先离开，另一指再离开
* Input          : None
* Output         : None
* Return         : 1：双指双击 other：无效
*******************************************************************************/
UINT8 TwoPointsClick()
{
	UINT8 flag = 0xff;

	if (bMoveFlag == 1)	   //双指有滑动，直接退出检测
	{
		byTouchNumberChange = 0;
		return(flag);
	}

	if (TouchNum == 0)	   //没有手指，已松键
	{
		//双指同时按下同时松开，并且触摸时间在400ms内
        if ((byTouchNumberChange == 2) && (byTouchTime2 < 10))
		{
		    //CH552UART0SendByte(0xbb);
			flag = 1;

		}
		//两指同时按下，松开过程先变一指再松开，触摸时间在400ms内
		else if ((byTouchNumberChange == 3) && (byTouchTime1 < 10))
		{
		    //CH552UART0SendByte(0xbb);
			flag = 1;

		}
		//按下时先单指接触再变两指接触，松开过程不管，触摸时间在400ms内
		else if ((byTouchNumberChange == 4) && (byTouchTime1 < 20) && (byTouchTime2 < 10))
		{
			//CH552UART0SendByte(0xbb);
			flag = 1;
		}

		byTouchNumberChange = 0;
		byTouchTime1 = 0;
		byTouchTime2 = 0;
	}
	else if ((TouchNum == 1) && (byTouchNumberChange != 0xFF))	  //检测到单指触摸
	{
        if (byTouchNumberChange == 0)	   //如果之前没有触摸，说明在按下的过程先是一指触摸
		{
			byTouchNumberChange = 1;
			byTouchTime1 = 0;
		}
		else if (byTouchNumberChange == 2)	//如果之前是两指触摸，说明在松开的过程先是一指离开
		{
		    byTouchNumberChange = 3;
		}

		flag = 2;

	}
	else if ((TouchNum == 2) && (byTouchNumberChange != 0xFF))	   //检测到两指触摸
	{
		if (byTouchNumberChange == 0)	   //如果之前没有触摸，说明在按下的过程是两指同时触摸
		{
			byTouchNumberChange = 2;
			byTouchTime1 = 0;
			byTouchTime2 = 0;
		}
		else if (byTouchNumberChange == 1)	 //如果之前先识别到一指触摸，说明在按下的过程是一指变两指
		{
			byTouchNumberChange = 4;
			byTouchTime2 = 0;
		}

		flag = 2;
	}
	else	//其他手指数则非法
	{
	    byTouchNumberChange = 0xFF;
		byTouchTime1 = 0;
		byTouchTime2 = 0;
		flag = 0;
	}
	return(flag);
}


void BackUpXPos()
{
	UINT8 i;
	for (i = 0; i < 5; i++)
	{
		wCoorXBak[i] = TP[i].X_pos;
	}
}

void BackUpYPos()
{
	UINT8 i;
	for (i = 0; i < 5; i++)
	{
		wCoorYBak[i] = TP[i].Y_pos;
	}
}

UINT16 GetAbs(UINT16 a, UINT16 b)
{
	return a > b ? a - b : b - a;
}



void ReportKey()
{
	#if (DEBUG!=Debug_USB)
		if (!IsBLEConnected() || BleReportPosEn == DISABLE)
	#else
		if (((!BleReportFirst) && EnumOK) || !IsBLEConnected() || BleReportPosEn == DISABLE)
	#endif
	{

		R8_UEP3_T_LEN = 9;
		R8_UEP3_CTRL = (R8_UEP3_CTRL & (~ MASK_UEP_T_RES)) | UEP_T_RES_ACK;
	}
	else
	{
		HidDev_Report(HID_RPT_ID_KEY_IN, HID_REPORT_TYPE_INPUT, 8, &pEP3_RAM_Addr[1]);
	}
}

UINT8 FourfingersGesture()
{
	UINT8 i;
	UINT8 xmoveincount = 0;
	UINT8 ymoveincount = 0;
	UINT8 xmoveoutcount = 0;
	UINT8 ymoveoutcount = 0;

	memset(pEP3_RAM_Addr, 0, 9);
	pEP3_RAM_Addr[0] = HID_RPT_ID_KEY_IN;



	//CH552UART0SendByte(TouchNum);
	//PRINT("Touch=%d\n", TouchNum);
	if (TouchNum == 0)
	{
		byLeftRightMoveFlag = 0;   //clean move flag
		byUpDownMoveFlag = 0;
		bFiveFingersMoveInFlag = 0;
		bFiveFingersMoveOutFlag = 0;

		if (byFourTouch || byFiveTouch)
		{
			if (byFourTouch == 3 || byFiveTouch == 3)	 //松键第一帧
			{
				pEP3_RAM_Addr[1] = 1;	 //上报Ctrl
			}
			else
			{
				pEP3_RAM_Addr[1] = 0;

				//防止鼠标判断有误，需要清除以下标志
				TouchNumBak = 0;
				TouchCount = 0;
				bTwoFingerCoorBak = 0;
			}

			ReportKey();

			if (byFourTouch)
				byFourTouch--;

			if (byFiveTouch)
				byFiveTouch--;

			return 1;
		}
	}
	else if (TouchNum == 4)
	{

		if (byFourTouch == 0 )
		{
			byFourTouch++;
		}
		else if (byFourTouch == 1)
		{
			byFiveTouch = 0;

			BackUpXPos();
			BackUpYPos();

			byFourTouch = 3;

			pEP3_RAM_Addr[1] = 1;		//Ctrl

			ReportKey();

		}
		else if (byFourTouch > 1)
		{
			//上报了键值，要紧接着上报一帧Ctrl键，否则系统会识别长按键，键值功能失效
			if (bUpDowntMoveCtrl)
			{
				bUpDowntMoveCtrl = 0;
				//byFourTouch = 2;  //这里上报了Ctrl，松键的时候就不上报Ctrl了

				pEP3_RAM_Addr[1] = 1;	 //上报Ctrl

				ReportKey();
			}

			if (TP[0].X_pos + LEFT_RIGHT_MOVE_DIS < wCoorXBak[0] && TP[1].X_pos + LEFT_RIGHT_MOVE_DIS < wCoorXBak[1]
				&& TP[2].X_pos + LEFT_RIGHT_MOVE_DIS < wCoorXBak[2] /*&& TP[3].X_pos + LEFT_RIGHT_MOVE_DIS < wCoorXBak[3]*/) //left
			{
			   	//CH552UART0SendByte(0xF5);

				if (byLeftRightMoveFlag == 0 || byLeftRightMoveFlag == 2)
				{
					byLeftRightMoveFlag = 1;

					pEP3_RAM_Addr[1] = 0x01;	//Ctrl
					pEP3_RAM_Addr[3] = 0x4f;//0x50;	//<-

					ReportKey();
				}
				BackUpXPos();
			}
			else if (TP[0].X_pos > wCoorXBak[0] + LEFT_RIGHT_MOVE_DIS && TP[1].X_pos > wCoorXBak[1] + LEFT_RIGHT_MOVE_DIS
					&& TP[2].X_pos > wCoorXBak[2] + LEFT_RIGHT_MOVE_DIS/* && TP[3].X_pos > wCoorXBak[3] + LEFT_RIGHT_MOVE_DIS*/)  //right
			{

				//CH552UART0SendByte(0xF6);

				if (byLeftRightMoveFlag == 0 || byLeftRightMoveFlag == 1)
				{
					byLeftRightMoveFlag = 2;

					pEP3_RAM_Addr[1] = 0x01;	//Ctrl
					pEP3_RAM_Addr[3] = 0x50;//0x4f;	//->

					ReportKey();
				}
				BackUpXPos();
			}
			else if (TP[0].Y_pos + UP_DOWN_MOVE_DIS < wCoorYBak[0] && TP[1].Y_pos + UP_DOWN_MOVE_DIS < wCoorYBak[1]
					&& TP[2].Y_pos + UP_DOWN_MOVE_DIS < wCoorYBak[2] /*&& TP[3].Y_pos + UP_DOWN_MOVE_DIS < wCoorYBak[3]*/)	//Up
			{

				if (byUpDownMoveFlag == 0 || byUpDownMoveFlag == 2)
				{
					byUpDownMoveFlag = 1;
					bUpDowntMoveCtrl = 1;

					pEP3_RAM_Addr[1] = 0x01;	//Ctrl
					pEP3_RAM_Addr[3] = 0x52;	//up

					ReportKey();
				}
				BackUpYPos();
			}
			else if (TP[0].Y_pos > wCoorYBak[0] + UP_DOWN_MOVE_DIS && TP[1].Y_pos > wCoorYBak[1] + UP_DOWN_MOVE_DIS
					&& TP[2].Y_pos > wCoorYBak[2] + UP_DOWN_MOVE_DIS /*&& TP[3].Y_pos > wCoorYBak[3] + UP_DOWN_MOVE_DIS*/)   //Down
			{

				if (byUpDownMoveFlag == 0 || byUpDownMoveFlag == 1)
				{
					byUpDownMoveFlag = 2;
					bUpDowntMoveCtrl = 1;

					pEP3_RAM_Addr[1] = 0x01;	//Ctrl
					pEP3_RAM_Addr[3] = 0x51;	//down

					ReportKey();
				}
				BackUpYPos();
			}
		}
		return 1;
	}
	else if (TouchNum == 5)			//五指手势识别
	{

		if (byFiveTouch == 0 )
		{
			byFiveTouch++;
		}
		else if (byFiveTouch == 1)
		{
			byFourTouch = 0;

			BackUpXPos();
			BackUpYPos();

			byFiveTouch = 3;

			pEP3_RAM_Addr[1] = 1;		//Ctrl

			ReportKey();

		}
		else if (byFiveTouch > 1)
		{
			for (i = 0; i < 3; i++)
			{
				wDisCoorX[i] = GetAbs(TP[i].X_pos, TP[i + 2].X_pos);
				wDisCoorY[i] = GetAbs(TP[i].Y_pos, TP[i + 2].Y_pos);

				wDisCoorXbak[i] = GetAbs(wCoorXBak[i], wCoorXBak[i + 2]);
				wDisCoorYbak[i] = GetAbs(wCoorYBak[i], wCoorYBak[i + 2]);
			}

			wDisCoorX[3] = GetAbs(TP[0].X_pos, TP[4].X_pos);
			wDisCoorY[3] = GetAbs(TP[0].Y_pos, TP[4].Y_pos);

			wDisCoorXbak[3] = GetAbs(wCoorXBak[0], wCoorXBak[4]);
			wDisCoorYbak[3] = GetAbs(wCoorYBak[0], wCoorYBak[4]);


			//=======================Close========================//
			for (i = 0; i < 4; i++)
			{
				if (wDisCoorX[i] + FIVE_MOVE_DIS < wDisCoorXbak[i])
				{
					xmoveincount++;
				}

				if (wDisCoorY[i] + FIVE_MOVE_DIS < wDisCoorYbak[i])
				{
					ymoveincount++;
				}
			}

			if ((xmoveincount + ymoveincount >= 3))
			{

				if (bFiveFingersMoveInFlag == 0)
				{
					bFiveFingersMoveInFlag = 1;

					pEP3_RAM_Addr[1] = 1;		//Ctrl
					pEP3_RAM_Addr[3] = 0x05;	//B

					ReportKey();
				}
				BackUpXPos();
				BackUpYPos();
			}

			//=======================Open========================//
			for (i = 0; i < 4; i++)
			{
				if (wDisCoorX[i] > wDisCoorXbak[i] + FIVE_MOVE_DIS)
				{
					xmoveoutcount++;
				}

				if (wDisCoorY[i] > wDisCoorYbak[i] + FIVE_MOVE_DIS)
				{
					ymoveoutcount++;
				}
			}

			if (xmoveoutcount + ymoveoutcount >= 3)
			{
				//CH552UART0SendByte(0xF3);

				if (bFiveFingersMoveOutFlag == 0)
				{
					bFiveFingersMoveOutFlag = 1;

					pEP3_RAM_Addr[1] = 1;		//Ctrl
					pEP3_RAM_Addr[3] = 0x05;	//B

					ReportKey();
				}
				BackUpXPos();
				BackUpYPos();
			}
		}
		return 1;
	}
	else if (byFourTouch || byFiveTouch)
	{
		return 1;
	}
	return 0;
}
#endif


#ifdef DOUBLECLIK_FILETER
extern UINT16 Press_Flag;
extern UINT16 Press_Flag_Bak1;
extern UINT16 Press_Flag_Bak2;
extern UINT16 StylusPress;
UINT8 DoubleClickTimer = 0;

void DoubleClickFilter(BOOL flag, UINT8 id)
{
	 static UINT16 PrePointX = 0xFFFF, PrePointY = 0xFFFF;
	 //static UINT16 PreStylusPressure = 0;
	 UINT16 Range = 240;
	 //static UINT8 ID;

#if USBCONFIG
	 if(config.mouse_double_click_en ==0)
	   return;
#endif

	 if(flag)
	 {
		 Range = 150;
	 }


	 if(DoubleClickTimer < 5)// || DoubleClickFlag)  //400ms以内连续单指Touch
	 {
		 if(TP[id].X_pos < PrePointX + Range && TP[id].X_pos + Range > PrePointX
			 && TP[id].Y_pos < PrePointY + Range && TP[id].Y_pos + Range > PrePointY)
		 {
			 //ID = id;

			 TP[id].X_pos = PrePointX;

			 TP[id].Y_pos = PrePointY;

		 }
		 else
		 {
			 DoubleClickTimer = 100;
		 }

	 }
	 else
	 {
		 PrePointX = TP[id].X_pos;
		 PrePointY = TP[id].Y_pos;
	 }

	 if((Press_Flag&Press_Flag_Bak1&Press_Flag_Bak2)==0 && !flag)
	 {
		 DoubleClickTimer = 0;
	 }
}
#endif

#ifdef CALL_OSD_MENU
//双指在右下角下滑，串口上报命令调用OSD菜单
#define X_RANGE	10916
#define Y_RANGE 6400

UINT8 CallOsdMenuCmd[10] = {0x55, 0x56, 0xd1, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x27};

void CallOSDMenu()
{
	UINT16 x_range = X_RANGE;
	if (TouchNum == 0)
	{
		byTwoTouch = 0;

		if (bTwoFingersMoveDown)
		{
			bTwoFingersMoveDown = 0;

			USART2_SendData(CallOsdMenuCmd, 10);
		}
	}
	else if (TouchNum == 2)
	{
		if(TpOption.uart_cmd == UART_COMMAND_A_90
		||TpOption.uart_cmd == UART_COMMAND_B_90
		||TpOption.uart_cmd == UART_COMMAND_A_270
		||TpOption.uart_cmd == UART_COMMAND_B_270
		)
		{
			x_range = RESOLUTION_X/2;
		}

		if (TP[0].X_pos_back > x_range && TP[0].Y_pos_back > Y_RANGE && TP[1].X_pos_back > x_range && TP[1].Y_pos_back > Y_RANGE)
		{
			if (byTwoTouch == 0)
			{
				byTwoTouch++;
			}
			else if (byTwoTouch == 1)
			{
				wTwoPointsCoorYBak[0] = TP[0].Y_pos_back;
				wTwoPointsCoorYBak[1] = TP[1].Y_pos_back;

				byTwoTouch++;
			}
			else if (byTwoTouch > 1)
			{
				if (TP[0].Y_pos_back > wTwoPointsCoorYBak[0] + 320
					&& TP[1].Y_pos_back > wTwoPointsCoorYBak[1] + 320)
				{
					 //CH552UART0SendByte(0x66);
					 bTwoFingersMoveDown = 1;
				}
			}
		}
	}
}
#endif
