#include <stdio.h>
#include <string.h>
#include <math.h>

extern "C" {
  #include "board.h"
  //   #include "radio.h"
  #include "uart.h"
  // #include "timer-board.h"
}

#define MESSAGE_BAUD_RATE 9600

const uint32_t message_interval{100000};
Gpio_t sensing_flag;
static TimerEvent_t message_timer;

char * message        = "Master, I am here to serve you!\r\n";
int messageLen        = strlen(message);
uint8_t *castMessage  = (uint8_t*)message;
int flagState         = 0;
bool stateSendMessage = false;

volatile uint16_t timer_counter{0};

// declare functions. 
void init_debug_led();
void set_timers();
void init_uart();
void send_message();
void handle_message_interval();
void state_machine();

int main()
{
  BoardInitMcu();
  // BoardInitPeriph();
  
  // Initialize Uart and then the timers.
  init_debug_led();
  init_uart();
  set_timers();

  
  // start main loop, essentially doing nothing but wait for the timer to trigger. 
  while(1)
  {
    state_machine();

    // keep checking if for some reason the timer is not running.
    if(!message_timer.IsRunning)
    {
      TimerStart(&message_timer);
    }

    TimerLowPowerHandler( );
  }
  
  return 0;
}

void state_machine()
{
  if(stateSendMessage == true)
  {
    stateSendMessage = false;
    send_message();    
  }
}

void init_debug_led()
{
  GpioInit(&sensing_flag, PA_8, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0);  // Led pin, for debugging
}

void init_uart()
{
  // UART init & config
  Fifo_t  fifoTx;
  uint8_t uartChar = 'A';
  
  fifoTx.Data  = &uartChar;
  Uart1.FifoTx = fifoTx;
  
  UartInit(&Uart1, 1, UART_TX, UART_RX);
  UartConfig( &Uart1, TX_ONLY, MESSAGE_BAUD_RATE, UART_8_BIT, UART_1_STOP_BIT, NO_PARITY, NO_FLOW_CTRL);
}

void set_timers() {
  // initiate the message timer
  TimerInit( &message_timer, &handle_message_interval);  // pointer to function
  TimerSetValue( &message_timer, message_interval);
  
  // start the timers
  TimerStart(&message_timer);
}

/*
 * Handler for the message timer. 
*/
void handle_message_interval()
{
  stateSendMessage = true;
}

void send_message()
{
  flagState = flagState == 1 ? 0 : 1;
  
  GpioWrite(&sensing_flag, flagState);

  /*
  while(UartPutBuffer(&Uart1, castMessage, messageLen))
  {
    // loop this until we're done sending. 
  };
  */
}
