#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <linux/input.h>
#include <pthread.h>

#define USE_ROTATION_ENCODER 1
#define USE_TOGGLE_ENCODER 1

#define SLEEP_DELAY_MS 1
#define HOLD_DELAY_MS 80
#define REPORT_DELAY_MS 120

#define PROJECT_NAME re818

#define __parse_str(tag) #tag
#define parse_str(tag) __parse_str(tag)

#if USE_ROTATION_ENCODER
#define ROTATION_MODE 1
#endif

#if USE_TOGGLE_ENCODER
#define TOGGLE_MODE 2
#endif

#ifndef ROTATION_MODE
#define ROTATION_MODE 0
#endif
#ifndef TOGGLE_MODE
#define TOGGLE_MODE 0
#endif

#if PROJECT_NAME == re818
#define KCROT 0
#define KCENT 103
#define KCUP 104
#define KCDN 105
#define KCLT 106
#define KCRT 107

#define KVLROT 1
#define KVRROT -1
#define KVPRS 0
#define KVRLS 1
#define KVNOP 2

#else
#define KCROT 0
#define KCENT 103
#define KCUP 104
#define KCDN 105
#define KCLT 106
#define KCRT 107

#define KVLROT 1
#define KVRROT -1
#define KVPRS 0
#define KVRLS 1
#define KVNOP 2

#endif

typedef enum
{
	KRY_PSB_NOP = 0,  //静默事件索引值 left rotation
	KRY_PSB_LROT = 1, //左旋事件索引值 left rotation
	KRY_PSB_RROT = 2, //右旋事件索引值 right rotation
	KRY_PSB_ENTP = 3, //按钮按下事件索引值 enter press
	KRY_PSB_ENTR = 4, //按钮释放事件索引值 enter release
	KRY_PSB_UPP = 5,  //上拨动触发事件索引值 upper press
	KRY_PSB_UPR = 6,  //上拨动释放事件索引值 upper release
	KRY_PSB_DNP = 7,  //下拨动触发事件索引值 down press
	KRY_PSB_DNR = 8,  //下拨动释放事件索引值 down release
	KRY_PSB_LTP = 9,  //左拨动触发事件索引值 left press
	KRY_PSB_LTR = 10, //左拨动释放事件索引值 left release
	KRY_PSB_RTP = 11, //右拨动触发事件索引值 right press
	KRY_PSB_RTR = 12, //右拨动释放事件索引值 right release
	KRY_PSB_END
} KEY_PSB;

typedef enum
{
	KEY_CODE_ROT = KCROT, //旋钮code值
	KEY_CODE_ENT = KCENT, //按钮code值
	KEY_CODE_UP = KCUP,	  //上拨code值
	KEY_CODE_DN = KCDN,	  //下拨code值
	KEY_CODE_LT = KCLT,	  //左拨code值
	KEY_CODE_RT = KCRT,	  //右拨code值
	KEY_CODE_END
} KEY_CODE;

typedef enum
{
	KEY_VALUE_LROT = KVLROT, //左旋value值
	KEY_VALUE_RROT = KVRROT, //右旋value值
	KEY_VALUE_NP = KVPRS,	 //按下value值
	KEY_VALUE_NR = KVRLS,	 //释放value值
	KEY_VALUE_NOP = KVNOP,	 //空置value值
	KEY_VALUE_END
} KEY_VALUE;

typedef struct KeyList
{
	int mode;
	int code;
	int value;
	int ret;
} EVEN_KEY_LIST;
int retKey(int code, int value, int mode)
{
	EVEN_KEY_LIST keyList[] = {
		{ROTATION_MODE, KEY_CODE_ROT, KEY_VALUE_LROT, KRY_PSB_LROT},
		{ROTATION_MODE, KEY_CODE_ROT, KEY_VALUE_RROT, KRY_PSB_RROT},
		{TOGGLE_MODE, KEY_CODE_ENT, KEY_VALUE_NP, KRY_PSB_ENTP},
		{TOGGLE_MODE, KEY_CODE_ENT, KEY_VALUE_NR, KRY_PSB_ENTR},
		{TOGGLE_MODE, KEY_CODE_UP, KEY_VALUE_NP, KRY_PSB_UPP},
		{TOGGLE_MODE, KEY_CODE_UP, KEY_VALUE_NR, KRY_PSB_UPR},
		{TOGGLE_MODE, KEY_CODE_DN, KEY_VALUE_NP, KRY_PSB_DNP},
		{TOGGLE_MODE, KEY_CODE_DN, KEY_VALUE_NR, KRY_PSB_DNR},
		{TOGGLE_MODE, KEY_CODE_LT, KEY_VALUE_NP, KRY_PSB_LTP},
		{TOGGLE_MODE, KEY_CODE_LT, KEY_VALUE_NR, KRY_PSB_LTR},
		{TOGGLE_MODE, KEY_CODE_RT, KEY_VALUE_NP, KRY_PSB_RTP},
		{TOGGLE_MODE, KEY_CODE_RT, KEY_VALUE_NR, KRY_PSB_RTR},
		{TOGGLE_MODE, KEY_CODE_ENT, KEY_VALUE_NOP, KRY_PSB_NOP}};

	int cnt = 0;

	for (cnt = 0; cnt < 13; cnt++)
	{
		if ((keyList[cnt].code == code) && (keyList[cnt].value == value) && (keyList[cnt].mode == mode))
		{
			return keyList[cnt].ret;
		}
	}
	// printf("not found.\n");
	return 0;
}

int getCurrentTime() //直接调用这个函数就行了，返回值最好是int64_t，long long应该也可以
{
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

#if USE_ROTATION_ENCODER
static int encoder_rotation_fd = 0;
static int keyRotValue = 0; //业务逻辑的index
static int invRotValue = 0; //业务逻辑的index
static int timerRotMark = 0;
static int holdRotAction = 0; //持续触发
static int reportDelayMs = 0; //上报延时
void *psbRotHandler(void *p)
{
	struct input_event in;
	int tempVal = 0;
	int tempTimerMart = 0;
	while (1)
	{
		tempTimerMart = getCurrentTime();
		if (read(encoder_rotation_fd, &in, sizeof(struct input_event)) == sizeof(struct input_event))
		{
			// printf("[%8d]psbRotHandler		KEY_CODE=%d		KEY_NUM=%d\n", getCurrentTime(), in.code, in.value); // psb的数值
			tempVal = retKey(in.code, in.value, ROTATION_MODE);
			if (tempVal == 0)
			{
			}
			else
			{
				// printf("now Time:%d\n", tempTimerMart);
				if (tempTimerMart - timerRotMark > HOLD_DELAY_MS)
				{
					holdRotAction = 0;
				}
				else
				{
					holdRotAction = 1;
					// printf("now Time:%d mark time:%d\n", tempTimerMart, timerRotMark);
				}
				timerRotMark = tempTimerMart;
				reportDelayMs = tempTimerMart;
				keyRotValue = tempVal;
				// printf("keyRotValue=%d\n", keyRotValue);
			}
		}

		if (holdRotAction)
		{
			// printf("faster rotation!\n");
		}

		usleep(SLEEP_DELAY_MS * 1000);
	}
	return NULL;
}
int psbGetRotValue(void)
{
	return keyRotValue;
}
int psbGetRotActionValue(void)
{
	return holdRotAction;
}
void psbClearRotValue(void)
{
	keyRotValue = 0;
	return;
}
void psbClearRotActionValue(void)
{
	holdRotAction = 0;
	timerRotMark = 0;
	return;
}
#endif

#if USE_TOGGLE_ENCODER
static int encoder_toggle_fd = 0;
static int keyTogValue = 0; //业务逻辑的index
static int timerTogMark = 0;
static int holdTogAction = 0;	  //持续触发
static int realToggleTrigger = 0; //防止摇杆触发按下
static int enterPressLock = 0;
static int avoidShakeLock = 0; //避免按下时抖动
int isToggleAction(int *val)
{
	if (enterPressLock == 1)
	{
		return 0;
	}
	int tempVal = *val;
	if ((tempVal == KRY_PSB_UPP) ||
		(tempVal == KRY_PSB_DNP) ||
		(tempVal == KRY_PSB_LTP) ||
		(tempVal == KRY_PSB_RTP))
	{
		realToggleTrigger = 1;
		return 1;
	}
	else if ((tempVal == KRY_PSB_UPR) ||
			 (tempVal == KRY_PSB_DNR) ||
			 (tempVal == KRY_PSB_LTR) ||
			 (tempVal == KRY_PSB_RTR))
	{
		realToggleTrigger = 2;
		return 1;
	}
	else if ((realToggleTrigger != 0) && ((tempVal == KRY_PSB_ENTR) || (tempVal == KRY_PSB_ENTP)))
	{
		if (realToggleTrigger == 1 && tempVal == KRY_PSB_ENTP)
			*val = 0;
		if (realToggleTrigger == 2 && tempVal == KRY_PSB_ENTR)
		{
			*val = 0;
			realToggleTrigger = 0;
		}
		return 0;
	}
	else
	{
		return 0;
	}
}
int isEnterPressAction(int *val)
{
	int tempVal = *val;
	if ((tempVal == KRY_PSB_ENTP))
	{
		enterPressLock = 1;
		printf("        trigger press ENTER.\n");
	}
	else if ((tempVal == KRY_PSB_ENTR))
	{
		enterPressLock = 0;
		printf("    trigger release ENTER.\n");
	}
	else
	{
		if (enterPressLock)
		{
			*val = 0;
		}
	}
	return 0;
}
void *psbTogHandler(void *p)  //摇杆处理函数
{
	struct input_event in;
	int tempVal = 0;
	int tempTimerMart = 0;
	while (1)
	{
		tempTimerMart = getCurrentTime();
		if (read(encoder_toggle_fd, &in, sizeof(struct input_event)) == sizeof(struct input_event))
		{

			tempVal = retKey(in.code, in.value, TOGGLE_MODE);
			if (tempVal == 0)
			{
			}
			else
			{
				printf("[%8d]psbTogHandler	KEY_CODE=%d		KEY_NUM=%d	\n", tempTimerMart, in.code, in.value); // psb的数值
				//处理摇杆时同时触发摇杆与按钮问题
				isToggleAction(&tempVal);
				if (tempVal == 0)
				{
					continue;
				}
				//处理按下时不响应其他摇杆操作
				isEnterPressAction(&tempVal);
				if (tempVal == 0)
				{
					continue;
				}
				// printf("now Time:%d\n", tempTimerMart);
				if (tempTimerMart - timerTogMark > HOLD_DELAY_MS)
				{
					holdTogAction = 0;
				}
				else
				{
					holdTogAction = 1;
				}
				timerTogMark = tempTimerMart;
				keyTogValue = tempVal;
				// printf("keyTogValue=%d\n", keyTogValue);
			}
		}
		usleep(SLEEP_DELAY_MS * 1000);
	}
	return NULL;
}
int psbGetTogValue(void)
{
	return keyTogValue;
}
void psbClearTogValue(void)
{
	keyTogValue = 0;
	return;
}
#endif

void psbInit(void)
{
#if USE_ROTATION_ENCODER
	pthread_t thread_rotation;
	encoder_rotation_fd = open("/dev/input/event1", O_RDONLY); //打开event1
	if (encoder_rotation_fd <= 0)
	{
		printf("psbInit:encoder_rotation_fd <= 0.\n");
	}
	else
	{
		pthread_create(&thread_rotation, NULL, psbRotHandler, NULL); //用handler读和处理
	}
#endif
#if USE_TOGGLE_ENCODER
	pthread_t thread_toggle;
	encoder_toggle_fd = open("/dev/input/event2", O_RDONLY); //打开event1
	if (encoder_toggle_fd <= 0)
	{
		printf("psbInit:encoder_toggle_fd <= 0.\n");
	}
	else
	{
		pthread_create(&thread_toggle, NULL, psbTogHandler, NULL); //用handler读和处理
	}
#endif
	return;
}
