#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;
boolean check=false;
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
};


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
};
int segment_levelminus[][N_SEGMENTS]={
  {OFF,OFF,OFF,ON,OFF,OFF,OFF}
};

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() {
  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() {
  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 5

// display task
void display(void *arg)
{   
    int number;
    int digit;

    while(1) {
      number = n;
      for (int i = 0; i < N_DIGITS_IN_DISPLAY; i++) {
          turnOffDisplay();
          digit = number % 10;
          number /= 10;
            for (int s = 0; s < N_SEGMENTS; s++) {
                gpio_set_level(gpio_for_segment[s], segment_level[digit][s]);
            }
            gpio_set_level(gpio_for_control[i], OFF);
            vTaskDelay(DELAY_TIME / portTICK_PERIOD_MS);
          
      }
    } 
}



// counter task
void counter(void *arg) {
  label1:
  for (n = 0; n < 1000; n++) {
      if ( gpio_get_level(GPIO_NUM_19) == OFF){
        n=0;

      };
      if(n==999){
        goto label;
      }
      vTaskDelay(COUNTER_TIME / portTICK_PERIOD_MS);
  }
  label :
    for (n = 999; n >0; n--) {
      if ( gpio_get_level(GPIO_NUM_19) == OFF){
      n=0;
      };
      if(n==0){
        !check;
        gpio_set_level(gpio_for_control[0], OFF);

        goto label1;
      }
      vTaskDelay(COUNTER_TIME / portTICK_PERIOD_MS);
  }
  
}


extern "C" void app_main() {

  initDisplay(); 
  

  xTaskCreate(&display, "displayNumber", 2048,NULL,5,NULL );
  xTaskCreate(&counter, "counter", 2048,NULL,5,NULL );
  
}