#include <Arduino.h>

#include "CoolingSystem.h"
#include "FrontPanel.h"
#include "PwrSupply_12V.h"
#include "PwrSupply_Laptop.h"
#include "PwrSupply_USB_PD.h"
#include "PwrSupply_USB_QC.h"
#include "UI_Graphics.h"

// Encoder library
// INA226Lib https://github.com/jarzebski/Arduino-INA226/
// INA3221 https://github.com/beast-devices/Arduino-INA3221
// DS18B20 DallasTemperature

C_FrontPanel Panel;
C_PwrSupply_12V Power_12V;
C_PwrSupply_Laptop Power_Laptop;
C_PwrSupply_USB_QC Power_USB_QC;
C_PwrSupply_USB_PD Power_USB_PD;
C_CoolingSystem CoolingSystem;
C_UI_Graphics UI_Graphics;

C_PwrSupply *PowerSupplies[N_SUPPLIES] = {&Power_12V, &Power_Laptop, &Power_USB_QC, &Power_USB_PD};

void SendDiag() {
    Serial.println("================= DIAG ================= ");

    for (int i = 0; i < 4; i++) {
        Serial.print(" - ");
        Serial.println(UI_Graphics.PowerSupplies_ShortNames[i]);
        Serial.println(PowerSupplies[i]->IsEnabled() ? "    ON" : "    OFF");
        Serial.print("    U = ");
        Serial.print(PowerSupplies[i]->GetVoltage());
        Serial.println(" V");
        Serial.print("    I = ");
        Serial.print(PowerSupplies[i]->GetCurrent());
        Serial.println(" A");
        Serial.print("    P = ");
        Serial.print(PowerSupplies[i]->GetPower());
        Serial.println(" W");
    }

    Serial.println(" - Cooling");

    Serial.print("    Fan RPM: ");
    Serial.print(CoolingSystem.GetFanRPM());
    Serial.println(" RPM");
    Serial.print("    Fan PWM: ");
    Serial.print(CoolingSystem.GetFanPWM());
    Serial.println(" / 255");
    Serial.print("    Temperature: ");
    if (!CoolingSystem.IsSensorOk())
        Serial.print("Sensor ERROR");
    else
        Serial.print(CoolingSystem.GetTemperature());
    Serial.println(" °C");
}

void setup() {
    Serial.begin(115200);

    Panel.Init();
    Power_12V.Init();
    Power_Laptop.Init();
    Power_USB_QC.Init();
    Power_USB_PD.Init();

    CoolingSystem.Init();

    UI_Graphics.Init();

    UI_Graphics.DrawWelcomeScreen();

    delay(2000);
}

void PSU_Buttons() {
    static bool old_buttons[4];

    if (Panel.IsButtonDown(0) && (Panel.IsButtonDown(0) != old_buttons[0])) {
        Power_12V.ToggleEnable();
    }

    if (Panel.IsButtonDown(1) && (Panel.IsButtonDown(1) != old_buttons[1])) {
        Power_Laptop.ToggleEnable();
    }

    if (Panel.IsButtonDown(2) && (Panel.IsButtonDown(2) != old_buttons[2])) {
        Power_USB_QC.ToggleEnable();
    }

    if (Panel.IsButtonDown(3) && (Panel.IsButtonDown(3) != old_buttons[3])) {
        Power_USB_PD.ToggleEnable();
    }

    Panel.SetLed(0, Power_12V.IsEnabled());
    Panel.SetLed(1, Power_Laptop.IsEnabled());
    Panel.SetLed(2, Power_USB_QC.IsEnabled());
    Panel.SetLed(3, Power_USB_PD.IsEnabled());

    old_buttons[0] = Panel.IsButtonDown(0);
    old_buttons[1] = Panel.IsButtonDown(1);
    old_buttons[2] = Panel.IsButtonDown(2);
    old_buttons[3] = Panel.IsButtonDown(3);
}

void CheckDynamicFuse() {
    if (Power_Laptop.GetCurrent() >= 5.0f) {
        Power_12V.SetFuse(C_PwrSupply_12V::FUSE_CURRENT_12V_WITH_LAPTOP_5A);
    } else if (Power_Laptop.GetCurrent() <= 4.0f) {
        Power_12V.SetFuse(C_PwrSupply_12V::FUSE_CURRENT_12V);
    }
}

void loop() {
    static int loopCnt = 0;
    PSU_Buttons();

    Panel.Tasks();
    Power_12V.Tasks();
    Power_Laptop.Tasks();
    Power_USB_QC.Tasks();
    Power_USB_PD.Tasks();

    CheckDynamicFuse();
    Power_12V.CheckFuse();
    Power_Laptop.CheckFuse();
    Power_USB_QC.CheckFuse();
    Power_USB_PD.CheckFuse();

    UI_Graphics.Navigation();
    UI_Graphics.Render();

    if (++loopCnt >= 20) {
        loopCnt = 0;

        CoolingSystem.Tasks();
    }
    delay(2);

    //SendDiag();
}
