#include <Arduino.h>

#include <WiFi.h>
#include <WebServer.h>
#include <Preferences.h>
#include <Wire.h>
#include <driver/i2s.h>
#include "Audio.h"
#include "TAS5749M_I2C.h"
#include <IRremote.hpp>



// =======================
  // USER SETTINGS
   // ======================= 


const char* ssid     = "Linksys19102";
const char* password = "lzcrcm7fas";

// =======================
//  IR RECEIVER
   //======================= 
const int RECV_PIN = 4; // IR Receiver pin



// =======================
  // I2S PINS (MATCH BOARD)
   //======================= 

#define I2S_BCLK   26
#define I2S_LRCLK  25
#define I2S_DATA   27   


//====================
//I2C PINS
//======================

#define SDA_PIN   21
#define SCL_PIN   22

// =======================
 //  OBJECTS
   //======================= 

Audio audio;
//WebServer server(80);
//Preferences prefs;

// =======================
  // STATION LIST
 //  ======================= 

struct Station {
  const char* name;
  const char* url;
};
/*
Station stations[] = {
  {"BBC Radio 4", "http://stream.live.vc.bbcmedia.co.uk/bbc_radio_fourlw"},
  {"BBC World",  "http://stream.live.vc.bbcmedia.co.uk/bbc_world_service"},
  {"NPR",        "https://npr-ice.streamguys1.com/live.mp3"},
  {"Jazz24",     "https://live.wostreaming.net/direct/ppm-jazz24mp3-ibc1"}
};
*/

Station stations[] = {
  {"BBC Radio 4",        "http://stream.live.vc.bbcmedia.co.uk/bbc_radio_fourlw"},
  {"BBC World Service",  "http://stream.live.vc.bbcmedia.co.uk/bbc_world_service"},
  {"NPR",                "https://npr-ice.streamguys1.com/live.mp3"},
  {"Jazz24",             "https://live.wostreaming.net/direct/ppm-jazz24mp3-ibc1"},
  // More stations added:
  {"Vermont Public",     "https://vpr.streamguys1.com/vpr64.mp3"},      // Public news/music source from Vermont Public Radio :contentReference[oaicite:1]{index=1}
  {"BBC Radio 1",        "http://stream.live.vc.bbcmedia.co.uk/bbc_radio_one"},  // BBC Radio 1 (UK) :contentReference[oaicite:2]{index=2}
  {"BBC Radio 2",        "http://stream.live.vc.bbcmedia.co.uk/bbc_radio_two"},  // BBC Radio 2 (UK) :contentReference[oaicite:3]{index=3}
  {"BBC Radio 3",        "http://stream.live.vc.bbcmedia.co.uk/bbc_radio_three"},// BBC Radio 3 (UK) :contentReference[oaicite:4]{index=4}
  {"BBC 6 Music",        "http://stream.live.vc.bbcmedia.co.uk/bbc_6music"},      // BBC 6 Music (UK) :contentReference[oaicite:5]{index=5}
  {"Times Radio",        "https://timesradio.wireless.radio/stream"}, // UK talk/music station (direct stream where available) :contentReference[oaicite:6]{index=6}
  {"ABC Classic 2",      "https://radio.abc.net.au/stations/classic2/live"}, // Australian classical music station :contentReference[oaicite:7]{index=7}
  {"SomaFM Groove Salad", "https://somafm.com/groovesalad.pls"}, // SomaFM playlist for Groove Salad (chill electronica)*
  {"SomaFM Lush",        "https://somafm.com/lush.pls"},         // SomaFM Lush (ambient)*
  {"Classic FM UK",      "http://media-ice.musicradio.com/ClassicFMMP3"}, // Classic FM (UK)*
  {"KEXP 90.3 Seattle",  "http://live-mp3-128.kexp.org:8000/"}   // KEXP rock/eclectic (US)*
};

const int stationCount = sizeof(stations) / sizeof(stations[0]);
int currentStation = 0;
int currentVolume  = 01;




// ---- Audio debug callbacks ----

void audio_info(const char *info) {
  Serial.print("INFO: ");
  Serial.println(info);
}

void audio_showstation(const char *info) {
  Serial.print("STATION: ");
  Serial.println(info);
}

void audio_showstreamtitle(const char *info) {
  Serial.print("NOW PLAYING: ");
  Serial.println(info);
}

void audio_bitrate(const char *info) {
  Serial.print("BITRATE: ");
  Serial.println(info);
}

void audio_error(const char *info) {
  Serial.print("ERROR: ");
  Serial.println(info);
}



//////////////////////////////////////////////
//////////////////////////////////////////
// lcd display function
//////////////////////////////////////////

void updateLCD() {
  String line0 = "Station:";
  line0 += stations[currentStation].name;
 Serial.println(line0);
  
}


////////////////////////////////////////////
// IR Task
////////////////////////////////////////////

void IRTask(void *pvParameters) {
  for (;;) {
    if (IrReceiver.decode()) {

      uint32_t code = IrReceiver.decodedIRData.decodedRawData;

  switch (code)
    {
        case 4161210119: // VOL+
            currentVolume += 1;
            if (currentVolume > 70) currentVolume = 70;
           
             audio.setVolume(currentVolume);
            Serial.print("Volume Up: ");
            Serial.println(currentVolume);
            break;
        case 4094363399: // VOL-
            currentVolume -= 1;
            if (currentVolume < 0) currentVolume = 0;
           
            audio.setVolume(currentVolume);
            Serial.print("Volume Down: ");
            Serial.println(currentVolume);
            break;

        case 3977381639://IR_CH_UP:
            currentStation++;
            if (currentStation >= stationCount) currentStation = 0;

            audio.stopSong();
            audio.connecttohost(stations[currentStation].url);
            updateLCD();
           break;

          case 4010804999: //IR_CH_DOWN:
              currentStation--;
             if (currentStation < 0) currentStation = stationCount - 1;

             audio.stopSong();
             audio.connecttohost(stations[currentStation].url);
            updateLCD();
          break;
    
    }

      IrReceiver.resume();
    }
    vTaskDelay(5);
  }
}




// =======================
   //SETUP
  // ======================= //

void setup() {

  Serial.begin(9600);
  Wire.begin(SDA_PIN, SCL_PIN);
  delay(1000);

 Serial.println("\nESP32 Internet Radio starting...");



delay(10);
  IrReceiver.begin(RECV_PIN, DISABLE_LED_FEEDBACK);

xTaskCreatePinnedToCore(
  IRTask,
  "IR Task",
  4096,
  NULL,
  1,
  NULL,
  0  //  Core 0
);

    Serial.print("Connecting to WiFi: ");
  Serial.println(ssid);

 
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  
  }

  Serial.println("\nWiFi connected!");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
 


 delay(20);



 
  
TAS5749_I2C_INT();


 // Force I2S clocking
 
  i2s_set_clk(
    I2S_NUM_0,
    48000,                 // sample rate
    I2S_BITS_PER_SAMPLE_32BIT,
     I2S_CHANNEL_MONO 
  );
  
 // Audio library
 audio.setPinout(I2S_BCLK, I2S_LRCLK, I2S_DATA);
 audio.setVolume(currentVolume);
 audio.connecttohost("http://vis.media-ice.musicradio.com/CapitalMP3");//("http://stream.live.vc.bbcmedia.co.uk/bbc_world_service");//

}

// =======================
  // LOOP
  // ======================= 

void loop() {
  audio.loop();

}








/*

#include <Arduino.h>
#include <WiFi.h>
#include <Wire.h>
#include <driver/i2s.h>
#include "Audio.h"
#include "TAS5749M_I2C.h"
#include <IRremote.hpp>
#include <LiquidCrystal_I2C.h>


const char* ssid     = "Linksys19102";
const char* password = "lzcrcm7fas";


#define RECV_PIN 4


LiquidCrystal_I2C lcd(0x27, 16, 2);


#define I2S_BCLK   26
#define I2S_LRCLK  25
#define I2S_DATA   27


#define SDA_PIN 21
#define SCL_PIN 22


Audio audio;


struct Station {
  const char* name;
  const char* url;
};

Station stations[] = {
  {"BBC Radio 4", "http://stream.live.vc.bbcmedia.co.uk/bbc_radio_fourlw"},
  {"BBC World",  "http://stream.live.vc.bbcmedia.co.uk/bbc_world_service"},
  {"NPR",        "https://npr-ice.streamguys1.com/live.mp3"},
  {"Jazz24",     "https://live.wostreaming.net/direct/ppm-jazz24mp3-ibc1"},
  {"Capital FM", "http://vis.media-ice.musicradio.com/CapitalMP3"}
};

const int stationCount = sizeof(stations) / sizeof(stations[0]);
volatile int currentStation = 4;
volatile int currentVolume  = 03;


String lcdLine0 = "";
String lcdLine1 = "";
SemaphoreHandle_t lcdMutex;


void LCDTask(void *pvParameters) {
  for (;;) {

    xSemaphoreTake(lcdMutex, portMAX_DELAY);

    lcd.setCursor(0, 0);
    lcd.print(lcdLine0);
    lcd.print("                ");

    lcd.setCursor(0, 1);
    lcd.print(lcdLine1);
    lcd.print("                ");

    xSemaphoreGive(lcdMutex);

    vTaskDelay(pdMS_TO_TICKS(200));
  }
}


void IRTask(void *pvParameters) {
  for (;;) {
    if (IrReceiver.decode()) {

      uint32_t code = IrReceiver.decodedIRData.decodedRawData;

      switch (code) {

        case 4161210119: // VOL+
          if (++currentVolume > 70) currentVolume = 70;
          audio.setVolume(currentVolume);
          lcdLine1 = "VOL: " + String(currentVolume);
          break;

        case 4094363399: // VOL-
          if (--currentVolume < 0) currentVolume = 0;
          audio.setVolume(currentVolume);
          lcdLine1 = "VOL: " + String(currentVolume);
          break;

        case 3977381639: // CH+
          currentStation++;
          if (currentStation >= stationCount) currentStation = 0;
          audio.stopSong();
          audio.connecttohost(stations[currentStation].url);
          lcdLine0 = stations[currentStation].name;
          break;

        case 4010804999: // CH-
          currentStation--;
          if (currentStation < 0) currentStation = stationCount - 1;
          audio.stopSong();
          audio.connecttohost(stations[currentStation].url);
          lcdLine0 = stations[currentStation].name;
          break;
      }

      IrReceiver.resume();
    }
    vTaskDelay(pdMS_TO_TICKS(10));
  }
}


void setup() {

  Serial.begin(9600);
  Wire.begin(SDA_PIN, SCL_PIN);

  lcd.init();
  lcd.backlight();

  lcdMutex = xSemaphoreCreateMutex();

  lcdLine0 = "ESP32 Radio";
  lcdLine1 = "Starting...";

  IrReceiver.begin(RECV_PIN, DISABLE_LED_FEEDBACK);

  xTaskCreatePinnedToCore(LCDTask, "LCD Task", 4096, NULL, 1, NULL, 0);
  xTaskCreatePinnedToCore(IRTask,  "IR Task",  4096, NULL, 2, NULL, 0);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
delay(100);
  TAS5749_I2C_INT();
  delay(100);
  i2s_set_clk(I2S_NUM_0, 48000, I2S_BITS_PER_SAMPLE_32BIT, I2S_CHANNEL_MONO);

  audio.setPinout(I2S_BCLK, I2S_LRCLK, I2S_DATA);
  audio.setVolume(currentVolume);
  audio.connecttohost(stations[currentStation].url);

  lcdLine0 = stations[currentStation].name;
  lcdLine1 = "VOL: " + String(currentVolume);
}


void loop() {
  audio.loop();
}
*/