//
#include "DefinitionSystem.h"
//
#if defined(INTERFACE_UART)
//
#include "Error.h"
#include "InterfaceUart.h"
//
extern CError Error;
//
//####################################################
//  CUartBase
//####################################################
//----------------------------------------------------
//  CUartBase - Constructor
//----------------------------------------------------
CUartBase::CUartBase(void)
{
  FRXIndex = 0;
  FRXBlock[0] = 0;
  FRXEcho = UART_INIT_RXECHO;
}
//
//----------------------------------------------------
//  CUartBase - Property
//----------------------------------------------------
void CUartBase::SetRXEcho(Boolean rxecho)
{
  FRXEcho = rxecho;
}
Boolean CUartBase::GetRXEcho(void)
{
  return FRXEcho;
}
//
//----------------------------------------------------
//  CUartBase - Handler
//----------------------------------------------------
// Boolean Open(int baudrate);
// Boolean Close(void);
//
//----------------------------------------------------
//  CUartBase - Write
//----------------------------------------------------
// Boolean Write(char* text);
// Boolean WriteLine(void);
// Boolean WriteLine(char* line);
//
//----------------------------------------------------
//  CUartBase - Read
//----------------------------------------------------
// Boolean ReadLine(char* rxline, int *rxsize);
//








//
//####################################################
//  CUartHS
//####################################################
//----------------------------------------------------
//  CUartHS - Constructor
//----------------------------------------------------
CUartHS::CUartHS(HardwareSerial* pserial)
{
  FPSerial = pserial;
} 
//
//----------------------------------------------------
//  CUartHS - Property
//----------------------------------------------------

//
//----------------------------------------------------
//  CUartHS - Handler
//----------------------------------------------------
Boolean CUartHS::Open(int baudrate)
{
  FPSerial->begin(baudrate);
  return true;
} 
Boolean CUartHS::Close(void)
{
  FPSerial->end();
  return true;
} 
//
//----------------------------------------------------
//  CUartHS - Write
//----------------------------------------------------
Boolean CUartHS::WriteCharacter(char character)
{
  FPSerial->print(character);
  return true;
}

Boolean CUartHS::WriteText(char* ptext)
{
  FPSerial->print(ptext);
  return true;
}

Boolean CUartHS::WriteLine(void)
{
  FPSerial->write(TERMINAL_NEWLINE);
  return true;  
} 

Boolean CUartHS::WriteLine(char* pline)
{
  FPSerial->write(pline);
  FPSerial->write(TERMINAL_NEWLINE);
  return true;
} 
//
//----------------------------------------------------
//  CUartHS - Read
//----------------------------------------------------
UInt8 CUartHS::GetRxCount(void)
{
  return FPSerial->available();
}

Boolean CUartHS::ReadCharacter(char &rxcharacter)
{
  rxcharacter = (char)0x00;
  if (0 < FPSerial->available())
  {
    rxcharacter = FPSerial->read();
    if (FRXEcho)
    {
      switch (rxcharacter)
      {
        case (char)0x0D:
        case (char)0x0A:
          break;
        default:
          FPSerial->write(rxcharacter);
          break;
      }
    }
    return true;
   }
   return false;
}

Boolean CUartHS::ReadLine(char* prxline, int &rxsize)
{ // Separator: CR or LF
  // !!! stay rxsize, use as limit !!!
  while (0 < FPSerial->available())
  {
    char RXC = (char)FPSerial->read();
    if (FRXEcho)
    {
      switch (RXC)
      {
        case (char)0x0D:
        case (char)0x0A:
          break;
        default:
          FPSerial->write(RXC);
          break;
      }
    }
    switch (RXC)
    {
      case (char)SEPARATOR_CR:
      case (char)SEPARATOR_LF:
        if (0 < FRXIndex)
        {          
          FRXBlock[FRXIndex] = SEPARATOR_ZERO;
          if (0 < strlen(FRXBlock))
          {
            strcpy(prxline, FRXBlock);
            rxsize = 1 + FRXIndex;
            FRXIndex = 0;
            FRXBlock[FRXIndex] = SEPARATOR_ZERO;
            return true;
          }
        }
        return false;
      default:
        FRXBlock[FRXIndex] = RXC;
        FRXIndex++;
        if (rxsize <= (1 + FRXIndex))
        {
          Error.SetCode(ecReceiveBufferOverflow);
          return false;
        }
    }
  }
  return false;
} 
//
//----------------------------------------------------
//  CUartxx - Handler
//----------------------------------------------------
// Boolean Open(int baudrate);
// Boolean Close(void);
//
//----------------------------------------------------
//  CUartBase - Write
//----------------------------------------------------
// Boolean WriteLine(void);
// Boolean WriteLine(char* line);
//
//----------------------------------------------------
//  CUartBase - Read
//----------------------------------------------------
// Boolean Read(char* rxtext, int *rxsize);
// Boolean ReadLine(char* rxline, int *rxsize);
//
//####################################################
//  CUart
//####################################################
//----------------------------------------------------
//  CUart - Constructor
//----------------------------------------------------
CUart::CUart(HardwareSerial* pserial)
{
  FPUartBase = (CUartBase*)new CUartHS(pserial);
}
//
//----------------------------------------------------
//  CUart - Property
//----------------------------------------------------
void CUart::SetRXEcho(Boolean rxecho)
{
  FPUartBase->SetRXEcho(rxecho);
}
Boolean CUart::GetRXEcho(void)
{
  return FPUartBase->GetRXEcho();
}
//
//----------------------------------------------------
//  CUart - Handler
//----------------------------------------------------
Boolean CUart::Open(int baudrate)
{
  return FPUartBase->Open(baudrate);
}
Boolean CUart::Close(void)
{
  return FPUartBase->Close();
}
//
//----------------------------------------------------
//  CUart - Read
//----------------------------------------------------
UInt8 CUart::GetRxCount(void)
{
  return FPUartBase->GetRxCount();
}

Boolean CUart::ReadLine(char* prxline, int &rxsize)
{
  return FPUartBase->ReadLine(prxline, rxsize);
}
// String CUart::ReadLine(void)
// {
//   return FPUartBase->ReadLine();
// }
// String CUart::ReadString(void)
// {
//   return FPUartBase->ReadString();
// }
// Byte CUart::ReadByte(void)
// {
//   return FPUartBase->ReadByte();
// }
// UInt16 CUart::ReadDual(void)
// {
//   return FPUartBase->ReadDual();
// }
// UInt32 CUart::ReadQuad(void)
// {
//   return FPUartBase->ReadQuad();
// }
// Int16 CUart::ReadInt16(void)
// {
//   return FPUartBase->ReadInt16();
// }
// UInt16 CUart::ReadUInt16(void)
// {
//   return FPUartBase->ReadUInt16();
// }
// Int32 CUart::ReadInt32(void)
// {
//   return FPUartBase->ReadInt32();
// }
// UInt32 CUart::ReadUInt32(void)
// {
//   return FPUartBase->ReadUInt32();
// }
// Float32 CUart::ReadFloat32(void)
// {
//   return FPUartBase->ReadFloat32();
// }
// Double64 CUart::ReadDouble64(void)
// {
//   return FPUartBase->ReadDouble64();
// }
//
//----------------------------------------------------
//  CUart - Write
//----------------------------------------------------
Boolean CUart::WriteLine(void)
{
  return FPUartBase->WriteLine();
}
Boolean CUart::WriteText(const char* ptext)
{
  return FPUartBase->WriteText((char*)ptext);
}
Boolean CUart::WriteText(const char* mask, const char* ptext)
{
  if (0 != ptext)
  {
    return FPUartBase->WriteText(FPUartBase->ConvertPChar(mask, (char*)ptext));
  }  
  return FPUartBase->WriteText(FPUartBase->ConvertPChar(mask, (char*)""));
}
Boolean CUart::WriteLine(const char* pline)
{
  return FPUartBase->WriteLine((char*)pline);
}
Boolean CUart::WriteLine(const char* mask, const char* pline)
{
  if (0 != pline)
  {
    return FPUartBase->WriteLine(FPUartBase->ConvertPChar(mask, (char*)pline));
  }  
  return FPUartBase->WriteLine(FPUartBase->ConvertPChar(mask, (char*)""));
}  
Boolean CUart::WritePChar(const char* mask, char* value)
{
  if (0 != value)
  {    
    return FPUartBase->WriteText(FPUartBase->ConvertPChar(mask, value));
  }
  return FPUartBase->WriteText((char*)mask);
}
Boolean CUart::WriteString(const char* mask, String value)
{
  return FPUartBase->WriteText(FPUartBase->ConvertString(mask, value));
}
Boolean CUart::WriteByte(const char* mask, Byte value)
{
  return FPUartBase->WriteText(FPUartBase->ConvertByte(mask, value));
}
Boolean CUart::WriteDual(const char* mask, UInt16 value)
{
  return FPUartBase->WriteText(FPUartBase->ConvertDual(mask, value));
}
Boolean CUart::WriteQuad(const char* mask, UInt32 value)
{
  return FPUartBase->WriteText(FPUartBase->ConvertQuad(mask, value));
}
Boolean CUart::WriteInt16(const char* mask, Int16 value)
{
  return FPUartBase->WriteText(FPUartBase->ConvertInt16(mask, value));
}
Boolean CUart::WriteUInt16(const char* mask, UInt16 value)
{
  return FPUartBase->WriteText(FPUartBase->ConvertUInt16(mask, value));
}
Boolean CUart::WriteInt32(const char* mask, Int32 value)
{
  return FPUartBase->WriteText(FPUartBase->ConvertInt32(mask, value));
}
Boolean CUart::WriteUInt32(const char* mask, UInt32 value)
{
  return FPUartBase->WriteText(FPUartBase->ConvertUInt32(mask, value));
}
Boolean CUart::WriteFloat32(const char* mask, Float32 value)
{  
  return FPUartBase->WriteText(FPUartBase->ConvertFloat32(mask, value));
}
Boolean CUart::WriteDouble64(const char* mask, Double64 value)
{  
  return FPUartBase->WriteText(FPUartBase->ConvertDouble64(mask, value));
}
//
//------------------------------------------------------------------------
// Uart - Write - Specials
//------------------------------------------------------------------------
Boolean CUart::WriteComment(void)
{
  return FPUartBase->WriteCharacter(TERMINAL_COMMENT[0]);
}
Boolean CUart::WriteComment(String comment)
{
  sprintf(FPUartBase->GetPTXBlock(), "%s%s", TERMINAL_COMMENT, comment.c_str());
  return FPUartBase->WriteText(FPUartBase->GetPTXBlock());
}
Boolean CUart::WriteResponse(String text)
{  
  sprintf(FPUartBase->GetPTXBlock(), "%s%s", TERMINAL_RESPONSE, text.c_str());
  return FPUartBase->WriteLine(FPUartBase->GetPTXBlock());
}

Boolean CUart::WriteEvent(const char* event)
{
  sprintf(FPUartBase->GetPTXBlock(), "%s%s", TERMINAL_EVENT, event);
  return FPUartBase->WriteLine(FPUartBase->GetPTXBlock());
}
Boolean CUart::WriteEvent(const char* mask, const char* event)
{  
  sprintf(FPUartBase->GetPTXBlock(), mask, event);
  FPUartBase->WriteText((char*)TERMINAL_EVENT);
  return FPUartBase->WriteLine(FPUartBase->GetPTXBlock());
}

//
//-------------------------------------------------------------------
//  Uart - Execute
//-------------------------------------------------------------------
// Boolean CUart::Execute(void)
// {
//   // while (0 < GetRxCount())
//   // {
//   //   Char C = F
//   //   switch (C)
//   //   {
//   //     case (byte)SEPARATOR_CR:
//   //     case (byte)SEPARATOR_LF:
//   //       FRxdBufferIndex, SEPARATOR_ZERO);
//   //       FRxdBufferIndex = 0; // restart
//   //       strupr(FRxdBuffer);
//   //       strcpy(FCommandText, FRxdBuffer);
//   //       return true;
//   //     default: 
//   //       FRxdBuffer[FRxdBufferIndex] = C;
//   //       FRxdBufferIndex++;
//   //       break;
//   //   }
//   // }  
// }











#endif // INTERFACE_UART
//