#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"

#define OFF 0
#define ON 1
#define N_SEGMENTS 7
#define N_DIGITS_IN_DISPLAY 4

int n; // global variable to hold the counter value

gpio_num_t gpio_for_segment[N_SEGMENTS] = {
  GPIO_NUM_14,  // a segment
  GPIO_NUM_32,  // b segment
  GPIO_NUM_15,  // c segment
  GPIO_NUM_13,  // d segment
  GPIO_NUM_12,  // e segment
  GPIO_NUM_26,  // f segment
  GPIO_NUM_4    // g segment
};

// segment on/off values for each digit
int segment_level[][N_SEGMENTS] = {
  { OFF, ON, ON, ON, ON, ON, ON },    // 0
  { OFF, OFF, OFF, OFF, ON, ON, OFF },// 1
  { ON, OFF, ON, ON, OFF, ON, ON },   // 2
  { ON, OFF, OFF, ON, ON, ON, ON },   // 3
  { ON, ON, OFF, OFF, ON, ON, OFF },  // 4
  { ON, ON, OFF, ON, ON, OFF, ON },   // 5
  { ON, ON, ON, ON, ON, OFF, ON },    // 6
  { OFF, OFF, OFF, OFF, ON, ON, ON }, // 7
  { ON, ON, ON, ON, ON, ON, ON },     // 8
  { ON, ON, OFF, OFF, ON, ON, ON }   // 9
};

gpio_num_t gpio_for_control[] = {
  GPIO_NUM_27, // digit 1
  GPIO_NUM_25, // digit 2
  GPIO_NUM_33, // digit 3
  GPIO_NUM_2   // digit 4
};

void turnOffDisplay() {
  // turn off all digit control pins
  for (int i=0; i < N_DIGITS_IN_DISPLAY; i++) {
    gpio_reset_pin(gpio_for_control[i]);
    gpio_set_direction(gpio_for_control[i], GPIO_MODE_OUTPUT);
    gpio_set_level(gpio_for_control[i], ON);
  }
}

void resetSegments() {
  // turn off all segment control pins
  for (int i=0; i < N_SEGMENTS; i++) {
    gpio_reset_pin(gpio_for_segment[i]);
    gpio_set_direction(gpio_for_segment[i], GPIO_MODE_OUTPUT);
    gpio_set_level(gpio_for_segment[i], OFF);
  }
}

void initDisplay() {
  resetSegments();
  turnOffDisplay();
  
  gpio_reset_pin(GPIO_NUM_19);
  gpio_set_direction(GPIO_NUM_19, GPIO_MODE_INPUT);
}

#define DELAY_TIME 10
#define COUNTER_TIME 500

// display task
void display(void *arg) {
  int number;
  int digit;
  
  while(1) {
    number = n;
    int negative = 0;
    
    // handle sign of number
    if (number < 0) {
      negative = 1;
      number = -number;
    }
    
    for (int i = 0; i < N_DIGITS_IN_DISPLAY; i++) {
      turnOffDisplay();
      digit = number % 10;
      number /= 10;
      
      // handle negative sign display