//
//--------------------------------
//  Library Led
//--------------------------------
//
#include "Led.h"
#include "DispatcherLedSystem.h"
//
extern CDispatcherLedSystem DispatcherLedSystem;
//
CLed::CLed(String id, int pin)
{
  FPin = pin;
  FID = id;
  FInverted = false;
  FState = slUndefined;
  //
  FStateBlink = slbZero;
  FPulseCountPreset = INIT_PULSECOUNT;
  FPulseCountActual = INIT_PULSECOUNT;
  FPulsePeriodms = INIT_PULSEPERIODMS;
  FPulseWidthms =  INIT_PULSEWIDTHMS;
}

CLed::CLed(String id, int pin, bool inverted)
{
  FPin = pin;
  FID = id;
  FInverted = inverted;
  FState = slUndefined;
  //
  FStateBlink = slbZero;
  FPulseCountPreset = INIT_PULSECOUNT;
  FPulseCountActual = INIT_PULSECOUNT;
  FPulsePeriodms = INIT_PULSEPERIODMS;
  FPulseWidthms =  INIT_PULSEWIDTHMS;
}

EStateLed CLed::GetState(void)
{
  return FState;
}  

Boolean CLed::IsInverted(void)
{
  return FInverted;
}

Boolean CLed::Open()
{
  pinMode(FPin, OUTPUT);
  SetOff();
  FState = slOff;
  return true;
}

Boolean CLed::Close()
{
  SetOff();
  pinMode(FPin, INPUT);
  FState = slUndefined;
  return true;
}

void CLed::SetOn()
{
  if (FInverted)
  {
    digitalWrite(FPin, LOW);
  }
  else
  {
    digitalWrite(FPin, HIGH);
  }
  FState = slOn;
}

void CLed::SetOff()
{
  if (FInverted)
  {
    digitalWrite(FPin, HIGH);
  }
  else
  {
    digitalWrite(FPin, LOW);
  }
  FState = slOff;
}

void CLed::Toggle(void)
{
  if (slOn == FState)
  {
    SetOff();
  }
  else
  {
    SetOn();
  }
}
//
//-------------------------------------------------------------------------------
//  Led - Process Blink
//-------------------------------------------------------------------------------
//
EStateLedBlink CLed::GetStateBlink(void)
{
  return FStateBlink;
}  

UInt32 CLed::GetPulsePeriodms(void)
{
  return FPulsePeriodms;
}

UInt32 CLed::GetPulseWidthms(void)
{
  return FPulseWidthms;
}

UInt32 CLed::GetPulseCountPreset(void)
{
  return FPulseCountPreset;  
}

UInt32 CLed::GetPulseCountActual(void)
{
  return FPulseCountActual;  
}

void CLed::Blink_Start(UInt32 pulsecount, UInt32 pulseperiodms, UInt32 pulsewidthms)
{ // bls 10 100 90
  FPulseCountPreset = pulsecount;
  FPulsePeriodms = pulseperiodms;
  FPulseWidthms = pulsewidthms;
  FStateBlink = slbInit;
}

void CLed::Blink_Abort(void)
{
  SetOff();
  FStateBlink = slbZero;
}
//
// bls 10 100 50
void CLed::Blink_Execute(char* pbuffer)
{
  switch (FStateBlink)
  {
    case slbZero:
      break;
    case slbInit:
      FTimeStartms = millis();
      SetOn();
      // ??? DispatcherLedSystem.WritePrompt();
      sprintf(pbuffer, "S[%s] Init", FID.c_str());
      DispatcherLedSystem.WriteEvent(pbuffer);
      //
      FPulseCountActual = 1;
      sprintf(pbuffer, "BL[%s] H %u %u", FID.c_str(), FPulseCountActual, FPulseCountPreset);
      DispatcherLedSystem.WriteEvent(pbuffer);
      FStateBlink = slbHigh;
      break;
    case slbHigh:
      if (FPulseWidthms < (millis() - FTimeStartms))
      {
        SetOff();
        sprintf(pbuffer, "BL[%s] L %u %u", FID.c_str(), FPulseCountActual, FPulseCountPreset);
        DispatcherLedSystem.WriteEvent(pbuffer);
        FStateBlink = slbLow;
      }
      break;
    case slbLow:
      if (FPulsePeriodms < (millis() - FTimeStartms))
      {
        if (FPulseCountActual < FPulseCountPreset)
        {
          FPulseCountActual++;
          SetOn();
          FTimeStartms = millis();
          sprintf(pbuffer, "BL[%s] H %u %u", FID.c_str(), FPulseCountActual, FPulseCountPreset);
          DispatcherLedSystem.WriteEvent(pbuffer);
          FStateBlink = slbHigh;
        }
        else
        {
          sprintf(pbuffer, "S[%s] Zero", FID.c_str());
          DispatcherLedSystem.WriteEvent(pbuffer);
          FStateBlink = slbZero;
        }
      }
      break;
    default:
      //sprintf(pbuffer, "SBL%s Zero", FID.c_str());
      //DispatcherLedSystem.WriteEvent(pbuffer);
      FStateBlink = slbZero;
      break;
  }
}
