import processing.serial.*;

Serial myPort;
float temp = 0; 
float smoothedTemp = 0; 

// Configuración del indicador
float cx, cy; 
float diameter; 
float startAngle = PI + QUARTER_PI; 
float endAngle = TWO_PI + PI - QUARTER_PI; 
float minTemp = 20;
float maxTemp = 50;

void setup() {
  size(800, 600);
  smooth(8); 
  
  cx = width / 2;
  cy = height / 2 + 50; 
  diameter = width * 0.65; 
  
  // Listar puertos
  printArray(Serial.list());
  
  // RECUERDA: Cambia el [0] por el número de tu puerto si no funciona
  try {
    myPort = new Serial(this, Serial.list()[0], 115200);
    myPort.bufferUntil('\n');
  } catch (Exception e) {
    println("Error: No se pudo abrir el puerto. Revisa el índice [0, 1, 2...]");
  }
  
  background(15);
}

void draw() {
  background(15); // Limpia la pantalla en cada frame
  
  // 1. Suavizado de movimiento
  smoothedTemp = lerp(smoothedTemp, temp, 0.08);
  
  // 2. Dibujar el FONDO del arco (Gris oscuro)
  noFill(); // <--- IMPORTANTE: Evita el relleno sólido
  strokeWeight(45); 
  stroke(40); 
  strokeCap(ROUND); 
  arc(cx, cy, diameter, diameter, startAngle, endAngle);
  
  // 3. Dibujar los marcadores (Rayitas y números)
  drawMarkers();
  
  // 4. Dibujar la BARRA DE PROGRESO (Color dinámico)
  float tempAngle = map(smoothedTemp, minTemp, maxTemp, startAngle, endAngle);
  tempAngle = constrain(tempAngle, startAngle, endAngle);
  
  // Cálculo de color (Azul -> Rojo)
  float colorRatio = map(smoothedTemp, minTemp, maxTemp, 0, 1);
  colorRatio = constrain(colorRatio, 0, 1);
  color barColor = lerpColor(color(0, 100, 255), color(255, 40, 0), colorRatio);
  
  // Dibujamos el arco de color
  noFill(); 
  stroke(barColor);
  strokeWeight(45);
  if (smoothedTemp > minTemp) {
    arc(cx, cy, diameter, diameter, startAngle, tempAngle);
  }
  
  // 5. Brillo estético (Línea fina exterior)
  strokeWeight(2);
  stroke(255, 30);
  arc(cx, cy, diameter + 55, diameter + 55, startAngle, endAngle);

  // 6. Display numérico central
  drawNumericDisplay(barColor);
}

void drawMarkers() {
  int numMarkers = 7; 
  for (int i = 0; i < numMarkers; i++) {
    float angle = map(i, 0, numMarkers - 1, startAngle, endAngle);
    float labelTemp = map(i, 0, numMarkers - 1, minTemp, maxTemp);
    
    float rOuter = diameter / 2 + 20;
    float rInner = diameter / 2 - 20;
    
    stroke(80); 
    strokeWeight(3);
    line(cx + cos(angle)*rInner, cy + sin(angle)*rInner, cx + cos(angle)*rOuter, cy + sin(angle)*rOuter);
    
    // Números
    fill(120);
    textAlign(CENTER, CENTER);
    textSize(18);
    float rText = diameter / 2 + 50;
    text(int(labelTemp) + "°", cx + cos(angle)*rText, cy + sin(angle)*rText);
  }
}

void drawNumericDisplay(color c) {
  // Caja del número
  fill(0, 100);
  noStroke();
  rectMode(CENTER);
  rect(cx, cy - 30, 220, 110, 15);
  
  // Valor de temperatura
  fill(255);
  textSize(70);
  textAlign(CENTER, CENTER);
  text(nf(smoothedTemp, 0, 1), cx - 20, cy - 40);
  
  // Unidad
  fill(c);
  textSize(30);
  text("°C", cx + 70, cy - 30);
  
  fill(100);
  textSize(14);
  text("TEMPERATURA AMBIENTE", cx, cy + 10);
}

void serialEvent(Serial p) {
  String inString = p.readStringUntil('\n');
  if (inString != null) {
    inString = trim(inString);
    float m = float(inString);
    if (!Float.isNaN(m)) {
      temp = m;
    }
  }
}
