
#include "DS_Button.h"

void DS_ButtonInit(DS_Button* Button, GPIO_TypeDef *Port, uint16_t Pin)
{
    Button->Port = Port;
    Button->Pin = Pin;
    Button->Pressed = false;
    Button->Released = false;
    Button->PrevTick = 0;
    Button->Storage = 5;
    Button->PressedLong = false;
    Button->PressStartTick = 0;
}

void DS_ButtonUpdate(DS_Button *Button)
{
    //создаём переменную
    //устанавливаем для неё границы от 0  до 10
    //если кнопка нажата - увеличиваем значение переменной, пока не доберемся до максимального (10)
    //если отпущена - уменьшаем, стремясь к нулю
    //опрос состояния делаем не чаще чем 1 раз в 10 миллисекунд
    //первое изменение делаем большим - 5 (имитация гистерезиса)
    //по достижении нуля - устанавливаем флаг что кнопка отпущена
    //по достижении 10 - флаг кнопка нажата

    uint32_t CurrentTick = HAL_GetTick();
    if ((CurrentTick - Button->PrevTick)<10)
        return;
    

    GPIO_PinState PinState  = HAL_GPIO_ReadPin(Button->Port, Button->Pin);
    if (PinState == GPIO_PIN_SET)
    {
        if(Button->Storage == 0)
            Button->Storage +=5;
        else if(Button->Storage<=10)
            Button->Storage++;

        if(Button->PressStartTick == 0)
            Button->PressStartTick = CurrentTick;
        else if ((CurrentTick - Button->PressStartTick)>1000)
            Button->PressedLong = true;
    }
    else
    {
        if(Button->Storage == 10)
            Button->Storage -=5;
        else if(Button->Storage > 0)
            Button->Storage--;

        Button->PressStartTick = 0;
        Button->PressedLong = false;
    }

    switch (Button->Storage)
    {
    case 0:
        Button->Pressed = false;
        Button->Released = true;
        break;
    case 10:
        Button->Pressed = true;
        Button->Released = false;
        break;
    
    default:
        break;
    }
    
}

bool DS_ButtonPressed(DS_Button *Button)
{
    if (Button->Pressed)
    {
        return true;
    }
    return false;
}

bool DS_ButtonReleased(DS_Button *Button)
{
    if(Button->Released)
    {
        return true;
    }
    return false;
}

bool DS_Button_PressedLong(DS_Button *Button)
{
    if(Button->PressedLong)
    {
        Button->PressedLong = false;
        Button->PressStartTick = 0;
        return true;

    }
    return false;
}
