#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>

#define BTN_PIN 5
#define TFT_DC 2
#define TFT_CS 15
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// Function to check if a point is in the Mandelbrot set
int mandelbrot(double real, double imag, int maxIterations) {
  double zReal = real;
  double zImag = imag;
  int iterations = 0;

  while (iterations < maxIterations) {
    double zRealSquared = zReal * zReal;
    double zImagSquared = zImag * zImag;

    if (zRealSquared + zImagSquared > 4.0) {
      break; // Point is not in the Mandelbrot set
    }

    double newZReal = zRealSquared - zImagSquared + real;
    double newZImag = 2.0 * zReal * zImag + imag;

    zReal = newZReal;
    zImag = newZImag;

    iterations++;
  }

  return iterations;
}

void setup() {
  pinMode(BTN_PIN, INPUT_PULLUP);

  tft.begin();
  tft.setRotation(1);

  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);
  tft.print("Start");
  
  Serial.begin(115200);
  Serial.println("Appliction " __FILE__ " complied " __DATE__ " at " __TIME__ ".");

}

void loop() {
  if (1) { //digitalRead(BTN_PIN) == LOW) {
    // Measure computation time
    unsigned long startTime = micros();

    // Draw Mandelbrot fractal
    const int maxIterations = 100;
    const double zoom = 0.005;
    for (int y = 0; y < tft.height(); y++) {
      Serial.println(y);
      for (int x = 0; x < tft.width(); x++) {
        double real = (x - tft.width() / 2) * zoom;
        double imag = (y - tft.height() / 2) * zoom;
        int iterations = mandelbrot(real, imag, maxIterations);
        tft.drawPixel(x, y, tft.color565(iterations % 256, 0, 0));
      }
    }

    unsigned long endTime = micros();
    unsigned long computationTime = endTime - startTime;

    // Display computation time
    tft.setCursor(10, 10);
    tft.print("Computation Time: ");
    tft.print(computationTime);
    tft.print(" us");
  }

  delay(100);
}