#include <Wire.h> // I2C 
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "EncoderHandler.h" // Include the encoder handler
#include "AD.h" // Include the ad handler
#include <math.h> // for sine drawing

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // OLED Reset pin or -1 if sharing Arduino reset pin
#define SCREEN_ADDRESS 0x3C // See datasheet for OLED Address; 0x3C for 128x32 and 128x64

// I2C screen A4(SDA), A5(SCL)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#include <Fonts/FreeSans12pt7b.h>

/*
Signal generator HW SPI
FNC: configurable,
DAT (MOSI (Master Out Slave In)) : D11,
CLK: D13
no MISO (no feedback)
*/
#define FNC 10
AD ad(FNC);

// uint8_t menu_id;

void setup() {

  encoder.setAccelerationEnabled(true);

  // Display init
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }
  // Display config
  //display.setFont(&FreeSans12pt7b);  // Set custom font
  display.setTextSize(1); // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.cp437(true); // Use full 256 char 'Code Page 437' font

  // attach HW interrupt to ISR encoder handler
  Timer1.initialize(1000); // 1000 us, 1kHz
  Timer1.attachInterrupt(timerIsr);

  Serial.begin(9600);
  Serial.println("Setup complete");

  showSplash();
  showStatic(); // start showing the initial wave
  Serial.println("Back");
  display.clearDisplay();
  textNormal("setup end");
  display.display();
}

void showSplash() {
  // Display welcome message for 2 seconds
  display.clearDisplay();
  display.setCursor(0, 0);
  textNormal("Signal Generator");

  // Calculate the center and radius of the circle
  int center_x = SCREEN_WIDTH / 2;
  int center_y = SCREEN_HEIGHT / 2;
  int radius = 12; // Half of the wave height

  // Draw the circle (optional, for visualization)
  display.drawCircle(center_x, center_y, radius+4, SSD1306_WHITE);

  float step_size = 2.0 * PI / (2 * radius);

  // Draw the sinusoidal wave
  for (int x = center_x - radius; x <= center_x + radius; x++) {
    int y = center_y + (int)(radius * sin((x - (center_x - radius)) * step_size));
    display.drawPixel(x, y, SSD1306_WHITE);
  }

  display.display();
  delay(500);
  display.clearDisplay();
  display.display();
}

// Template function to display "normal" text
template <typename T>
void textNormal(T text) {
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.print(text);
}

// Template function to display "selected" text
template <typename T>
void textSelected(T text) {
  display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Draw inverted text
  display.print(text);
  display.setTextColor(SSD1306_WHITE); // Draw white text
}
void showStatic() {
  encoder_state.value = ad.getFrequency(0);
  showStaticInfo();
  // stay here until encoder switch is pressed
  while (encoder_state.button != CheapClickEncoder::Clicked) {
    handleEncoder();
    if (encoder_state.changing == false) {
      ad.setFrequency(encoder_state.value, 0);
      //Serial.println(ad.getFrequency(0));
      showStaticInfo();

    } else {
      // display changes
      //Serial.println("Changing");
    }
  }
  Serial.println("return from static");
  return;
}
// show the static wave screen
void showStaticInfo() {
  // enable encoder to change freq
//   menu_id = 1;

  display.setTextSize(1);
  // display wave info
  display.clearDisplay();

  display.setCursor(0, 0);
  display.print(ad.getChannelTxt());

  display.setCursor(80, 0);
  display.print(ad.getFormTxt());

  display.setTextSize(2);
  display.setCursor(35, 16);
  display.println(ad.getFreqTxt());

  display.setCursor(50, 40);
  display.print("Hz");
  display.display();
}


void loop() {


}