#ifndef BASICAIO_TOOLS_H
#define BASICAIO_TOOLS_H

#include <Arduino.h>

// =====================================================
// BASICAIO TOOLS - ARCHIVO DOCENTE
// -----------------------------------------------------
// Este es el unico archivo que deberia modificar el docente.
//
// Para agregar una herramienta nueva:
// 1. Copiar una ficha completa.
// 2. Cambiar el nombre de la funcion.
// 3. Cambiar la descripcion y los argumentos.
// 4. Escribir el codigo Arduino.
// 5. Dejar el REGISTER_TOOL pegado debajo de la funcion.
//
// =====================================================

// -----------------------------------------------------
// Configuracion inicial de hardware
// -----------------------------------------------------
void setupTeacherHardware() {
  pinMode(LED_BUILTIN, OUTPUT);
}


// =====================================================
// TOOL: led_on
// DESCRIPCION: Enciende el LED integrado de Arduino
// ARGUMENTOS: ninguno
// =====================================================
String led_on() {
  digitalWrite(LED_BUILTIN, HIGH);
  return "OK LED_ON";
}

REGISTER_TOOL(
  "led_on",
  "Turn on the built-in LED",
  "{\"type\":\"object\",\"properties\":{},\"required\":[]}",
  led_on
)


// =====================================================
// TOOL: led_off
// DESCRIPCION: Apaga el LED integrado de Arduino
// ARGUMENTOS: ninguno
// =====================================================
String led_off() {
  digitalWrite(LED_BUILTIN, LOW);
  return "OK LED_OFF";
}

REGISTER_TOOL(
  "led_off",
  "Turn off the built-in LED",
  "{\"type\":\"object\",\"properties\":{},\"required\":[]}",
  led_off
)


// =====================================================
// TOOL: digital_write
// DESCRIPCION: Escribe HIGH o LOW en un pin digital
// ARGUMENTOS:
//   pin   : numero de pin
//   value : HIGH, LOW, 1 o 0
// =====================================================
String digital_write_tool() {
  int pin = getIntArg("pin", 13);
  String value = getStringArg("value", "LOW");

  pinMode(pin, OUTPUT);

  bool high = false;
  if (value == "HIGH" || value == "high" || value == "1") {
    high = true;
  }

  digitalWrite(pin, high ? HIGH : LOW);
  return String("OK WRITE ") + String(pin);
}

REGISTER_TOOL(
  "digital_write",
  "Write HIGH or LOW to pin",
  "{\"type\":\"object\",\"properties\":{\"pin\":{\"type\":\"integer\"},\"value\":{\"type\":\"string\",\"enum\":[\"HIGH\",\"LOW\",\"1\",\"0\"]}},\"required\":[\"pin\",\"value\"]}",
  digital_write_tool
)


// =====================================================
// TOOL: digital_read
// DESCRIPCION: Lee el valor de un pin digital
// ARGUMENTOS:
//   pin : numero de pin
// =====================================================
String digital_read_tool() {
  int pin = getIntArg("pin", 0);

  pinMode(pin, INPUT_PULLUP);
  int value = digitalRead(pin);

  return String(value);
}

REGISTER_TOOL(
  "digital_read",
  "Read digital pin",
  "{\"type\":\"object\",\"properties\":{\"pin\":{\"type\":\"integer\"}},\"required\":[\"pin\"]}",
  digital_read_tool
)


// =====================================================
// TOOL: analog_write
// DESCRIPCION: Escribe un valor PWM en un pin compatible
// ARGUMENTOS:
//   pin   : numero de pin PWM
//   value : valor entre 0 y 255
// =====================================================
String analog_write_tool() {
  int pin = getIntArg("pin", 9);
  int value = getIntArg("value", 0);

  if (value < 0) value = 0;
  if (value > 255) value = 255;

  pinMode(pin, OUTPUT);
  analogWrite(pin, value);

  return String("OK ANALOG_WRITE pin=") + String(pin) + String(" value=") + String(value);
}

REGISTER_TOOL(
  "analog_write",
  "PWM write",
  "{\"type\":\"object\",\"properties\":{\"pin\":{\"type\":\"integer\"},\"value\":{\"type\":\"integer\"}},\"required\":[\"pin\",\"value\"]}",
  analog_write_tool
)


// =====================================================
// TOOL: analog_read
// DESCRIPCION: Lee un pin analogico
// ARGUMENTOS:
//   pin : pin analogico. Ejemplo: A0 o 0
// =====================================================
String analog_read_tool() {
  String pinText = getStringArg("pin", "A0");
  int pin = A0;

  if (pinText == "A0" || pinText == "a0") pin = A0;
  else if (pinText == "A1" || pinText == "a1") pin = A1;
  else if (pinText == "A2" || pinText == "a2") pin = A2;
  else if (pinText == "A3" || pinText == "a3") pin = A3;
  else if (pinText == "A4" || pinText == "a4") pin = A4;
  else if (pinText == "A5" || pinText == "a5") pin = A5;
  else pin = pinText.toInt();

  int value = analogRead(pin);
  return String(value);
}

REGISTER_TOOL(
  "analog_read",
  "Analog read",
  "{\"type\":\"object\",\"properties\":{\"pin\":{\"type\":\"string\"}},\"required\":[\"pin\"]}",
  analog_read_tool
)


// =====================================================
// TOOL: esperar
// DESCRIPCION: Espera una cantidad de milisegundos
// ARGUMENTOS:
//   ms : tiempo a esperar en milisegundos
// =====================================================
String esperar() {
  int ms = getIntArg("ms", 0);

  if (ms < 0) ms = 0;
  delay(ms);

  return String("OK ESPERAR ") + String(ms) + String("ms");
}

REGISTER_TOOL(
  "esperar",
  "Esperar N milisegundos",
  "{\"type\":\"object\",\"properties\":{\"ms\":{\"type\":\"integer\",\"description\":\"Tiempo a esperar en ms\"}},\"required\":[\"ms\"]}",
  esperar
)


// =====================================================
// PLANTILLA PARA NUEVA HERRAMIENTA
// -----------------------------------------------------
// Copiar desde aqui, pegar debajo y modificar.
// =====================================================
/*
String mi_herramienta() {
  int pin = getIntArg("pin", 13);

  // Escribir aqui el codigo Arduino

  return "Resultado de mi herramienta";
}

REGISTER_TOOL(
  "mi_herramienta",
  "Descripcion visible desde BASICAIO",
  "{\"type\":\"object\",\"properties\":{\"pin\":{\"type\":\"integer\"}},\"required\":[\"pin\"]}",
  mi_herramienta
)
*/

#endif
