// //
#include "DefinitionSystem.h"
//
#include "Error.h"
#include "Command.h"
//
#if defined(INTERFACE_UART)
#include "InterfaceUart.h"
#endif
#if defined(INTERFACE_BT)
#include "InterfaceBt.h"
#endif
#if defined(INTERFACE_WLAN)
#include "InterfaceWlan.h"
#endif
#if defined(INTERFACE_LAN)
#include "InterfaceLan.h"
#endif
//
extern CError     Error;
//
#if defined(INTERFACE_UART)
extern CUart UartCommand;
#endif
#if defined(INTERFACE_BT)
extern CBt BtCommand;
#endif
#if defined(INTERFACE_WLAN)
extern CWlan WlanCommand;
#endif
#if defined(INTERFACE_LAN)
extern CLan LanCommand;
#endif
//
//#########################################################
//  Command - Constructor
//#########################################################
CCommand::CCommand(void)
{
  FState = scUndefined;
#if defined(INTERFACE_UART)
  FUartCommand = new char[UART_COMMANDSIZE];
  for (int IP = 0; IP < UART_PARAMETERCOUNT; IP++)
  {
    FUartParameters[IP] = new char[UART_PARAMETERSIZE];
  }
#endif
#if defined(INTERFACE_BT)
#endif
#if defined(INTERFACE_WLAN)
#endif
#if defined(INTERFACE_LAN)
#endif
}
CCommand::~CCommand(void)
{
  FState = scUndefined;
}
//
//#########################################################
//  Command - Property
//#########################################################
EStateCommand CCommand::GetState(void)
{
  return FState;
}
//
void CCommand::SetState(EStateCommand state)
{
  if (state != FState)
  {
    FState = state;
#ifdef INTERFACE_UART
    UartCommand.WriteEvent(MASK_STATECOMMAND, StateText(FState));
#endif
// #ifdef INTERFACE_BT
// #endif
// #ifdef INTERFACE_WLAN
// #endif
// #ifdef INTERFACE_LAN
// #endif
// #if defined(PROTOCOL_MQTT)
//     MQTTClient.WriteEvent(GetTxdBuffer());
// #endif
// #if defined(PROTOCOL_SDCARD)
// #endif
  }
}
//
//#########################################################
//  Command - Helper
//#########################################################
const char* CCommand::StateText(EStateCommand state)
{
  switch (state)
  {
    case scError:
      return (const char*)"Error";
    case scUndefined:
      return (const char*)"Undefined";
    case scInit:
      return (const char*)"Init";
    case scIdle:
      return (const char*)"Idle";
    case scBusy:
      return (const char*)"Busy";
    default: // not in list -> Undefined
      return (const char*)"Unknown";
  }
}
//
char* CCommand::GetCommand(void)
{
#if defined(INTERFACE_UART)
  return FUartCommand;
#endif
#if defined(INTERFACE_BT) 
#endif
#if defined(INTERFACE_WLAN)
#endif
#if defined(INTERFACE_LAN)
#endif
  return 0;
}
Int16 CCommand::GetParameterCount(void)
{
#if defined(INTERFACE_UART)
  return FUartParameterCount;
#endif
#if defined(INTERFACE_BT)
#endif
#if defined(INTERFACE_WLAN)
#endif
#if defined(INTERFACE_LAN)
#endif
  return 0;
}
char** CCommand::GetParameters(void)
{
#if defined(INTERFACE_UART)
  return FUartParameters;
#endif
#if defined(INTERFACE_BT)
#endif
#if defined(INTERFACE_WLAN)
#endif
#if defined(INTERFACE_LAN)
#endif
  return 0;
}
//
//#########################################################
//  Command - Helper
//#########################################################
//
//#########################################################
//  Command - Handler
//#########################################################
bool CCommand::Open(void)
{
  SetState(scIdle);
  return true;
}
bool CCommand::Close(void)
{
  SetState(scUndefined);
  return true;
}
//
//##################################################################
// Command - Analysis & Execution
//##################################################################
// InterfaceText -> Command/COMMAND, Parameters
bool CCommand::AnalyseInterfaceBlock(void)
{
#if defined(INTERFACE_UART)
  if (0 < UartCommand.GetRxCount())
  {
    if (scIdle != GetState())
    {
      Error.SetCode(ecTimingFailure);
      return false;
    }
    int SizeBlock = INTERFACE_SIZE_RXBLOCK - 1;
    char Block[INTERFACE_SIZE_RXBLOCK];
    if (UartCommand.ReadLine(Block, SizeBlock))
    { 
      UartCommand.WriteLine();
      SetState(scBusy);
      char *PTerminal = (char*)" \t\r\n";
      char* PCommand = strtok(Block, PTerminal);
      if (PCommand)
      { 
        strupr(PCommand);
        strcpy(FUartCommand, PCommand);
        // debug UartCommand.WriteText((char*)"FUartCommand[");
        // debug UartCommand.WriteText(FUartCommand);
        // debug UartCommand.WriteLine((char*)"]");
        FUartParameterCount = 0;
        char *PParameter;
        while (0 != (PParameter = strtok(0, PTerminal)))
        {
          strcpy(FUartParameters[FUartParameterCount], PParameter);
          // debug UartCommand.WriteInt32("P[%i]", FUartParameterCount);
          // debug UartCommand.WriteLine("<%s>", FUartParameters[FUartParameterCount]);
          FUartParameterCount++;
          if (UART_PARAMETERCOUNT < FUartParameterCount)
          {
            Error.SetCode(ecToManyParameters);
            return false;
          }
        }
      }
      return true;
    }
    return false;
  }
#endif
#if defined(INTERFACE_BT)
#endif
#if defined(INTERFACE_WLAN)
#endif
#if defined(INTERFACE_LAN)
#endif
  return false;
}
