/*
  Name:    Interface.cpp
  Author:  Roman Schönfeld & Daniel Hausherr
*/

/***********************************************************************************************
  This work is licensed under a Creative Commons Attribution 4.0 International (CC BY 4.0) License.

  You are free to:

  Share — copy and redistribute the material in any medium or format
  Adapt — remix, transform, and build upon the material
  for any purpose, even commercially.

  The licensor cannot revoke these freedoms as long as you follow the license terms.

  Under the following terms:

  Attribution — You must give appropriate credit, provide a link to the license, and indicate if
  changes were made. You may do so in any reasonable manner, but not in any way that suggests
  the licensor endorses you or your use.

  No additional restrictions — You may not apply legal terms or technological measures that
  legally restrict others from doing anything the license permits.

  Credits:
  Laboratory for Physics and Illumination Technologies,
  University of Applied Sciences Southern Westfalia
  Germany

  Make Light! Support by the BMBF in the development of this device is gratefully acknowledged
***************************************************************************************************/

#include "Sauron.h"
#include "Display.h"
#include "PdResponse.h"

#include "Interface.h"

// local variable
static bool _isMeasurment = false, _update = false;;
static double _tmp = 0.0d;
static uint16_t nmtorgb[] = { (uint16_t)RGB(0xFF, 0x00, 0x90), (uint16_t)RGB(0xFF, 0x00, 0x78), (uint16_t)RGB(0xFF, 0x00, 0x66), (uint16_t)RGB(0xFF, 0x00, 0x56), (uint16_t)RGB(0xFF, 0x00, 0x54), (uint16_t)RGB(0xFF, 0x00, 0x50), (uint16_t)RGB(0xFF, 0x00, 0x8), (uint16_t)RGB(0xFF, 0x39, 0x00), (uint16_t)RGB(0xFF, 0xDB, 0x00),
                              (uint16_t)RGB(0xEC, 0xFF, 0x00), (uint16_t)RGB(0x2F, 0xFF, 0x00), (uint16_t)RGB(0x00, 0xFF, 0x8F), (uint16_t)RGB(0x00, 0xFF, 0xC7),
                              (uint16_t)RGB(0x00, 0xEB, 0xFF), (uint16_t)RGB(0x00, 0x8C, 0xFF), (uint16_t)RGB(0x79, 0x00, 0xFF), (uint16_t)RGB(0x89, 0x00, 0xFF), (uint16_t)RGB(0x91, 0x00, 0xFF)
                            };

integrationTime current_time;
referenceCurrent current_ref;
outputData current_data_output;

photometer_wavelenght current_wavelenght;
detectors current_detector;



// Initialisiert die Menustruktur
void init_menu() {

  current_detector = BFH_203P;
  current_wavelenght = NM_650;

  clear_area_tft(0, 0, 160, 128, BLACK);

  set_cursor_tft(1, 77);
  print_text_tft((char*)"Farbe", WHITE);
  set_cursor_tft(85, 77);
  print_text_tft((char*)"Wellenlaenge", WHITE);
}

void compute_value_nano(void*) {

  bool first = true, config_change = true, tmp_cof_change = true, timeout = false;
  uint8_t num_ch_to_read = 1, x = 2, y = 122, tmp = 0;
  int8_t isMicroWatt = -1;

  static int16_t prevDigits[] = { -1, -1, -1, -1, -1};
  uint16_t ready_pin_timeouts = 0, faktor_einheit = 0, counts_current = 0, data_buffer[num_ch_to_read], time_break = 0;
  int16_t digits[] = {0, 0, 0, 0, 0} , digitPos[] = {32, 44, 56, 74, 86};

  double power = 0.0d, counts_1mW_normiert = 1.0d, peek_max = 0.0d;

  if ((uint8_t)current_wavelenght < 16) {
    drawArrowUp(x, y - 27, (char*)colortowavelenght((uint8_t)(current_wavelenght - 1)),  nmtorgb[(uint8_t)(current_wavelenght - 1)]);
    set_cursor_tft(95, y - 33);
    print_text_tft((char*)numtochar((uint8_t)(current_wavelenght - 1)), nmtorgb[(uint8_t)(current_wavelenght - 1)]);
  }
  if ((uint8_t)current_wavelenght >= 1) {
    drawArrowDown(x, y + 3, (char*)colortowavelenght((uint8_t)(current_wavelenght + 1)),  nmtorgb[(uint8_t)(current_wavelenght + 1)]);
    set_cursor_tft(95, y - 3);
    print_text_tft((char*)numtochar((uint8_t)(current_wavelenght + 1)), nmtorgb[(uint8_t)(current_wavelenght + 1)]);
  }

  

  set_text_size_tft(2);
  set_cursor_tft(64, 10);
  print_text_tft((char*)".", WHITE);
  set_text_size_tft(1);
  
_isMeasurment = true;

  while (true) {

    while (true) {

      if ((uint16_t)analogRead(_Y_MOVE) < 124) {
        if (current_wavelenght < 17) {
          tmp = 0;
          tmp = (uint8_t)current_wavelenght;
          tmp += 1;
          current_wavelenght = (photometer_wavelenght)tmp;

          clear_area_tft(1, 87, 159, 10, BLACK);
          drawArrowUp(x, y - 27, (char*)colortowavelenght((uint8_t)(current_wavelenght - 1)),  nmtorgb[(uint8_t)(current_wavelenght - 1)]);
          set_cursor_tft(95, y - 33);
          print_text_tft((char*)numtochar((uint8_t)(current_wavelenght - 1)), nmtorgb[(uint8_t)(current_wavelenght - 1)]);

          clear_area_tft(1, 118, 159, 10, BLACK);
          drawArrowDown(x, y + 3, (char*)colortowavelenght((uint8_t)(current_wavelenght + 1)),  nmtorgb[(uint8_t)(current_wavelenght + 1)]);
          set_cursor_tft(95, y - 3);
          print_text_tft((char*)numtochar((uint8_t)(current_wavelenght + 1)), nmtorgb[(uint8_t)(current_wavelenght + 1)]);

          config_change = true;
          tmp_cof_change = config_change;

          if ((uint8_t)current_wavelenght == (uint8_t)(NM_COUNT - 1))
            clear_area_tft(1, 118, 110, 10, BLACK);
        }
      }
      else if ((uint16_t)analogRead(_Y_MOVE) > 900) {
        if (current_wavelenght >= 1) {
          tmp = 0;
          tmp = (uint8_t)current_wavelenght;
          tmp -= 1;
          current_wavelenght = (photometer_wavelenght)tmp;

          clear_area_tft(1, 87, 159, 10, BLACK);
          drawArrowUp(x, y - 27, (char*)colortowavelenght((uint8_t)(current_wavelenght - 1)),  nmtorgb[(uint8_t)(current_wavelenght - 1)]);
          set_cursor_tft(95, y - 33);
          print_text_tft((char*)numtochar((uint8_t)(current_wavelenght - 1)), nmtorgb[(uint8_t)(current_wavelenght - 1)]);

          clear_area_tft(1, 118, 159, 10, BLACK);
          drawArrowDown(x, y + 3, (char*)colortowavelenght((uint8_t)(current_wavelenght + 1)), nmtorgb[(uint8_t)(current_wavelenght + 1)]);
          set_cursor_tft(95, y - 3);
          print_text_tft((char*)numtochar((uint8_t)(current_wavelenght + 1)), nmtorgb[(uint8_t)(current_wavelenght + 1)]);

          config_change = true;
          tmp_cof_change = config_change;


          if ((uint8_t)current_wavelenght == (uint8_t)(NM_COUNT - NM_COUNT))
            clear_area_tft(1, 87, 130, 10, BLACK);
        }
      }

      if (tmp_cof_change) {
        clear_area_tft(1, 100, 159, 16, BLACK);

        set_text_size_tft(2);
        set_cursor_tft(1, 100);
        print_text_tft((char*)colortowavelenght((uint8_t)(current_wavelenght)), nmtorgb[(uint8_t)(current_wavelenght)]);
        set_cursor_tft(95, 100);
        print_text_tft((char*)numtochar((uint8_t)(current_wavelenght)), nmtorgb[(uint8_t)(current_wavelenght)]);
        set_text_size_tft(1);
      }

      tmp_cof_change = false;

      time_break++;

      if (time_break >= 8) {
        time_break = 0;
        break;
      } else
        delay(100);
    }

    if (define_matching_range() != 0) {
      break;
    }

    if (set_mode(true) == 0) {  // Parameter TRUE falls Messung starten und FALSE falls Messung beenden
      while (analogRead(_READY_PIN) <= 10) {
        ready_pin_timeouts++;
        if (ready_pin_timeouts > (uint16_t)((pow(2.0d, (double)current_time) + 0.5d) * 4)) {
          _isMeasurment = false;
          timeout = true;
          break;
        }
        else {
          delay(1);
        }
      }

      ready_pin_timeouts = 0;

      if (timeout)
        break;
    }
    else {
      break;
    }
    
    if ((raw_counts(data_buffer, num_ch_to_read) == 0)) {

      counts_current = data_buffer[((uint8_t)current_data_output - (uint8_t)current_data_output)];            // Counts aktuell

      get_sfh_203_characteristic(&counts_1mW_normiert);

      power = (double)((double)counts_current / counts_1mW_normiert );
      power /= (double)(pow(4, (4 - (uint8_t)current_ref)));


      if (power < 1.0) {
        faktor_einheit = 1000.0;
        if (isMicroWatt != 1) {

          set_text_size_tft(2);
          set_cursor_tft(106, 10);
          print_text_tft((char*)"mW", BLACK);

          drawMicro(106, 14, 2, WHITE);
          set_cursor_tft(116, 10);
          print_text_tft((char*)"W", WHITE);
          set_text_size_tft(1);

          isMicroWatt = 1;
        }
      }
      else {
        faktor_einheit = 1.0;
        if (isMicroWatt != 0) {

          set_text_size_tft(2);
          drawMicro(106, 14, 2, BLACK);
          set_cursor_tft(116, 10);
          print_text_tft((char*)"W", BLACK);


          set_cursor_tft(106, 10);
          print_text_tft((char*)"mW", WHITE);
          set_text_size_tft(1);

          isMicroWatt = 0;
        }
      }

      if (config_change) {
        peek_max = 0.0;

        set_cursor_tft(20, 35);
        clear_area_tft(83, 35, 40, 10, BLACK);
        print_text_tft((char*)"Max. Wert: ", WHITE);
        print_value_tft_double((peek_max * faktor_einheit), WHITE);

        if (faktor_einheit == 1000 ) {
          clear_area_tft(123, 35, 45, 10, BLACK);
          drawMicro(127, 37, 1, WHITE);
          set_cursor_tft(133, 35);
          print_text_tft((char*)"W", WHITE);

        } else {
          clear_area_tft(123, 35, 50, 10, BLACK);
          set_cursor_tft(123, 35);
          print_text_tft((char*)"mW", WHITE);
        }

        config_change = false;

      } else if (power > peek_max) {
        peek_max = power;

        set_cursor_tft(83, 35);
        clear_area_tft(83, 35, 40, 10, BLACK);
        print_value_tft_double((peek_max * faktor_einheit), WHITE);

        if (faktor_einheit == 1000 ) {
          clear_area_tft(123, 35, 45, 10, BLACK);
          drawMicro(127, 37, 1, WHITE);
          set_cursor_tft(133, 35);
          print_text_tft((char*)"W", WHITE);

        } else {
          clear_area_tft(123, 35, 50, 10, BLACK);
          set_cursor_tft(123, 35);
          print_text_tft((char*)"mW", WHITE);
        }
      }

      if (power <= 1) {
        clear_area_tft(1, 49, 159, 20, BLACK);
      }
      if (power > 1 ) {
        clear_area_tft(1, 49, 159, 20, RED);
        set_cursor_tft(20, 56);
        print_text_tft("Laserleistung zu Hoch", YELLOW);
      }


      _tmp = (power * faktor_einheit);

      Serial.println(_tmp);
      
      digits[4] = (((uint16_t)((_tmp / 2) * 100.0f) * 2) % 10);

      digits[3] = ((uint16_t)(_tmp * 10.0f) % 10);

      digits[2] = ((uint16_t)_tmp % 10);

      digits[1] = ((uint16_t)(_tmp / 10.0f) % 10);

      digits[0] = ((uint16_t)(_tmp / 100.0f) % 10);

      set_text_size_tft(2);

      for (uint8_t i = 0; i < 5; i++)
      {
        if ((prevDigits[i] != digits[i]))
        {
          set_cursor_tft(digitPos[i], 10);
          if (prevDigits[i] != -1)
          {
            print_value_tft(prevDigits[i], BLACK);
            set_cursor_tft(digitPos[i], 10);
          }
          print_value_tft(digits[i], WHITE);
          prevDigits[i] = digits[i];
        }
      }

      set_text_size_tft(1);
    }
    else {
      break;
    }
  }

  _isMeasurment = false;
}
