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

#define ON 0
#define OFF 1
#define SEGMENTS 7
#define DIGITS 4
#define DELAY 10
int COUNTER_DELAY = 1000;

int n;
int direction = 1;
boolean positiveSign = true;

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

int digits[][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
  {ON, OFF, OFF, OFF, OFF, OFF, OFF} //-
};

gpio_num_t gpio_for_control[] = 
{
  GPIO_NUM_27, //DIGIT_4
  GPIO_NUM_25, //DIGIT_3
  GPIO_NUM_33, //DIGIT_2
  GPIO_NUM_2   //DIGIT_1
};

void displayOff(){
  for(int i = 0; i < DIGITS; i++){
    gpio_set_level(gpio_for_control[i], ON);
  }
}

void displaySet(){
  for(int i = 0; i < DIGITS; 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], OFF);
  }
}

void resetSegments(){
  for(int i = 0; i < 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 start(){
  resetSegments();
  displaySet();

  gpio_reset_pin(GPIO_NUM_19);
  gpio_set_direction(GPIO_NUM_19, GPIO_MODE_INPUT);
  gpio_set_direction(GPIO_NUM_21, GPIO_MODE_INPUT);
}

void display(void *arg){
  int number;
  int currDigit;
  while(1){
    number = n;
    for(int i = 0; i < DIGITS; i++){
      displayOff();
      currDigit = number % 10;
      number = number/10;
      //printf("%d\n", number);
      if(positiveSign == false && i == 3 && direction > 0)
      {
        //printf("Entre al primer if\n");
        gpio_set_level(GPIO_NUM_14, ON);
        for(int k = 1; k < SEGMENTS; k++){
          gpio_set_level(gpio_for_segment[k], OFF);
        }
          gpio_set_level(gpio_for_control[i], OFF);
      }
      if(i!=3){
        //printf("Entre al segundo if\n");
      for(int j = 0; j < SEGMENTS; j++){
        gpio_set_level(gpio_for_segment[j], digits[currDigit][j]);
      }
      gpio_set_level(gpio_for_control[i], OFF);
      }
      vTaskDelay(DELAY/portTICK_PERIOD_MS);
    }
  }
}

void counter(void *arg){
    for (n = 0; n < 1000; n += direction) {
        //printf("%d\n", n);
        if (n == 999){
          direction = -1;
        }
        if(n == 0 && direction == -1){
          direction = 1;
          positiveSign = !positiveSign;
        }
        if(gpio_get_level(GPIO_NUM_19) == ON) {n = 0; direction = 1; positiveSign = true;}
        if(gpio_get_level(GPIO_NUM_21) == OFF) {direction = direction * -1;}
        vTaskDelay(COUNTER_DELAY/portTICK_PERIOD_MS);
    }
}

extern "C" void app_main()
{
  start();

  //if(gpio_get_level(GPIO_NUM_18) == OFF){COUNTER_DELAY += 10;} //Se Supone que funcionara como un COUNTER_DELAY multiplier.//

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