#include "lubeapp.h"

uint32_t lubePulseTimestamp = 0;

void RunLubeApp(uint32_t add_milimeters)
{

    globals.TankPercentage = PersistenceData.tankRemain_microL / (LubeConfig.tankCapacity_ml * 10);

    MaintainDTC(DTC_TANK_EMPTY, (PersistenceData.tankRemain_microL < LubeConfig.amountPerDose_microL));
    MaintainDTC(DTC_TANK_LOW, (globals.TankPercentage < LubeConfig.TankRemindAtPercentage));

    // Add traveled Distance in mm
    PersistenceData.TravelDistance_highRes_mm += add_milimeters;
    PersistenceData.odometer_mm += add_milimeters;
    if (PersistenceData.odometer_mm >= 1000000)
    {
        PersistenceData.odometer++;
        PersistenceData.odometer_mm = 0;
    }

    switch (globals.systemStatus)
    {
    case sysStat_Startup:
        strcpy_P(globals.systemStatustxt, PSTR("Startup"));
        if (millis() > STARTUP_DELAY)
        {
            globals.systemStatus = sysStat_Normal;
            globals.resumeStatus = sysStat_Normal;
        }
        break;

    case sysStat_Normal:
        strcpy_P(globals.systemStatustxt, PSTR("Normal"));
        if (PersistenceData.TravelDistance_highRes_mm / 1000 > LubeConfig.DistancePerLube_Default)
        {
            LubePulse();
            PersistenceData.TravelDistance_highRes_mm = 0;
        }
        break;

    case sysStat_Rain:
        strcpy_P(globals.systemStatustxt, PSTR("Rain"));
        if (PersistenceData.TravelDistance_highRes_mm / 1000 > LubeConfig.DistancePerLube_Rain)
        {
            LubePulse();
            PersistenceData.TravelDistance_highRes_mm = 0;
        }
        break;
    case sysStat_Purge:
        strcpy_P(globals.systemStatustxt, PSTR("Purge"));
        if (globals.purgePulses > 0)
        {
            if (lubePulseTimestamp + LUBE_PULSE_PAUSE_MS < millis())
            {
                LubePulse();
                globals.purgePulses--;
                Debug_pushMessage("Purge remain: %d\n", globals.purgePulses);
            }
        }
        else
        {
            globals.systemStatus = globals.resumeStatus;
        }
        break;
    case sysStat_Error:
        strcpy_P(globals.systemStatustxt, PSTR("Error"));
        break;
    case sysStat_Shutdown:
        strcpy_P(globals.systemStatustxt, PSTR("Shutdown"));
        break;
    default:
        break;
    }

    // maintain Pin-State of Lube-Pump
    if (lubePulseTimestamp > millis())
        digitalWrite(GPIO_PUMP, HIGH);
    else
        digitalWrite(GPIO_PUMP, LOW);
}

void LubePulse()
{
    if (PersistenceData.tankRemain_microL > 0) // Only Lube if theres Oil remaining!
    {
        lubePulseTimestamp = millis() + LUBE_PULSE_LENGHT_MS;

        if (PersistenceData.tankRemain_microL < LubeConfig.amountPerDose_microL) // Prevent underrun and shiftover
            PersistenceData.tankRemain_microL = 0;
        else
            PersistenceData.tankRemain_microL = PersistenceData.tankRemain_microL - LubeConfig.amountPerDose_microL;
    }
}