/*
 * drv_button.c
 *
 *  Created on: 11 мар. 2025 г.
 *      Author: basov.g
 */
#include "drv_button.h"
#include "MDR32VF0xI_port.h"
#include "MDR32VF0xI.h"
#include "MDR32VF0xI_rst_clk.h"
#include "../utils/utils.h"
#define BUTTON_FRIST_PIN	PORT_PIN_10
#define BUTTON_SECOND_PIN	PORT_PIN_11
#define BUTTON_PORT    		MDR_PORTA
#define BUTTON_CLK			RST_CLK_PCLK_PORTA

const uint32_t buttonsPin[BUTTONSCOUNT] = {BUTTON_FRIST_PIN,BUTTON_SECOND_PIN};
static ButtonState buttonState[BUTTONSCOUNT];
void (*buttonEvents[BUTTONSCOUNT][6]) (void) = {0};
void drv_Button_Init()
{
	RST_CLK_PCLKCmd(BUTTON_CLK, ENABLE);
	PORT_InitTypeDef PORT_InitStructure;
	PORT_InitStructure.PORT_Direction    = PORT_DIRECTION_INPUT;
	PORT_InitStructure.PORT_Function  = PORT_FUNCTION_PORT;
	PORT_InitStructure.PORT_Mode  = PORT_MODE_DIGITAL;
	PORT_InitStructure.PORT_Power = PORT_POWER_INCREASED_UPTO_4mA;
	PORT_InitStructure.PORT_PullDown  = PORT_PULL_DOWN_OFF;
	PORT_InitStructure.PORT_PullUp  = PORT_PULL_UP_OFF;
	PORT_InitStructure.PORT_Pin = (BUTTON_FRIST_PIN | BUTTON_SECOND_PIN);
	PORT_Init(BUTTON_PORT, &PORT_InitStructure);
}

void drv_Button_SetNewState(ButtonNum num,ButtonState state)
{
	if(num>=BUTTONSCOUNT) return;
	buttonState[num] = state;
	if(buttonEvents[num][state]!=0)
	{
		buttonEvents[num][state]();
	}
}

void drv_Button_Update(void)
{
	static uint64_t timeLastPress[BUTTONSCOUNT]={0};
	static uint8_t buttonLogicState[BUTTONSCOUNT] = {0};

	for(int i = 0; i < BUTTONSCOUNT; i++)
	{

		uint8_t currentButtonLogicState = (uint8_t)(!PORT_ReadInputDataBit(BUTTON_PORT,(uint16_t)buttonsPin[i]));
		if(currentButtonLogicState != buttonLogicState[i])
		{
			if(currentButtonLogicState) timeLastPress[i] = getMillis();
		}

	switch(buttonState[i])
	{
		case ButtonUp:
		{
			if(getMillis() - timeLastPress[i] > 10 && currentButtonLogicState) drv_Button_SetNewState(i,ButtonDown);
			break;
		}
		case ButtonDown:
		{
			if(getMillis() - timeLastPress[i] > 1000 && currentButtonLogicState) drv_Button_SetNewState(i,ButtonPress);
			if(!currentButtonLogicState) drv_Button_SetNewState(i,ButtonClick);
			break;
		}
		case ButtonPress:
		{
			if(getMillis() - timeLastPress[i] > 3000 && currentButtonLogicState) drv_Button_SetNewState(i,ButtonLongPress);
			if(!currentButtonLogicState) drv_Button_SetNewState(i,ButtonRelease);
			break;	//state when button press short time
		}
		case ButtonLongPress:
		{
			if(!currentButtonLogicState) drv_Button_SetNewState(i,ButtonRelease);
			break;	//state when button press short time
		}
		case ButtonClick:
		{
			if(!currentButtonLogicState) drv_Button_SetNewState(i,ButtonRelease);
			break;
		}
		case ButtonRelease:
		{
			drv_Button_SetNewState(i,ButtonUp);
			break;
		}
	}
	buttonLogicState[i] = currentButtonLogicState;
	}
}

ButtonState drv_Button_GetState(ButtonNum num)
{
	return buttonState[num];
}

void drv_Button_SetEvent(ButtonNum num, ButtonState event, void (*function) (void))
{
	buttonEvents[num][event] = function;
}

