#include "DefinitionSystem.h"
//
#ifdef INTERFACE_UART
//
#ifndef InterfaceUart_h
#define InterfaceUart_h
//
#include <stdio.h>
#include <stdarg.h>
#include <Arduino.h>
#include <HardwareSerial.h>
//
#include "InterfaceBase.h"
//
//----------------------------------------------------
//  Constant
//----------------------------------------------------
const byte UART_SIZE_RXBLOCK = 32;
const byte UART_SIZE_TXBLOCK = 32;
const Boolean UART_INIT_RXECHO    = true;
//
//----------------------------------------------------
//  CUartBase
//----------------------------------------------------
class CUartBase : public CInterfaceBase
{
  protected:
  char FRXBlock[UART_SIZE_RXBLOCK];
  char FTXBlock[UART_SIZE_TXBLOCK];
  Boolean FRXEcho;
  //
  public:
  CUartBase(void);
  //
  char* GetRXBlock(void)
  {
    return FRXBlock;
  }
  char* GetTXBlock(void)
  {
    return FTXBlock;
  }
  void SetRXEcho(Boolean rxecho);
  Boolean GetRXEcho(void);
  //
  virtual Boolean Open(int baudrate) = 0;
  virtual Boolean Close(void) = 0;
  //
  virtual Boolean WriteCharacter(char character) = 0;
  virtual Boolean WriteText(char* ptext) = 0;
  virtual Boolean WriteLine(void) = 0;
  virtual Boolean WriteLine(char* pline) = 0;
  //
  virtual UInt8 GetRxCount(void) = 0;
  virtual Boolean ReadCharacter(char &rxcharacter) = 0;
  virtual Boolean ReadLine(char* prxline, int &rxsize) = 0;
};
//
//----------------------------------------------------
//  CUartHS
//----------------------------------------------------
class CUartHS : public CUartBase
{
  protected:
  HardwareSerial* FPSerial;
  
  public:
  CUartHS(HardwareSerial *serial);
  //
  virtual Boolean Open(int baudrate);
  virtual Boolean Close(void);
  //
  virtual Boolean WriteCharacter(char character);
  virtual Boolean WriteText(char* ptext);
  virtual Boolean WriteLine(void);
  virtual Boolean WriteLine(char* pline);
  //
  virtual UInt8 GetRxCount(void);
  virtual Boolean ReadCharacter(char &rxcharacter);
  virtual Boolean ReadLine(char* prxline, int &rxsize);
};

// #if (defined(PROCESSOR_TEENSY32) || defined(PROCESSOR_TEENSY36))
// class CUartUS : public CUartBase
// {
//   protected:
//   usb_serial_class* FPSerial;
//   //  
//   public:
//   CUartU(usb_serial_class *serial)
//   {
//     FPSerial = serial;
//   } 
// };
// #endif

class CUart
{
  private:
  CUartBase* FPUartBase;
  int FPinRXD, FPinTXD;
  //
  public:
  CUart(HardwareSerial* pserial);
  CUart(HardwareSerial* pserial, int pinrxd, int pintxd);
// #if (defined(PROCESSOR_TEENSY32) || defined(PROCESSOR_TEENSY36))
//   CUart(usb_serial_class &serial);
// #endif
  //
  // Property
  char* GetRXBlock(void)
  {
    return FPUartBase->GetPRXBlock();
  }
  char* GetTXBlock(void)
  {
    return FPUartBase->GetPTXBlock();
  }
  void SetRXEcho(Boolean rxecho);
  Boolean GetRXEcho(void);
  //
  // Handler
  Boolean Open(int baudrate);
  Boolean Close(void);
  //
  // Write
  Boolean WriteCharacter(char character);
  Boolean WriteText(const char* ptext);
  Boolean WriteText(const char* mask, const char* ptext);
  Boolean WriteLine(const char* pline);
  Boolean WriteLine(const char* mask, const char* pline);
  Boolean WriteCharacter(const char* mask, char character);
  Boolean WritePChar(const char* mask, char* pvalue);
  Boolean WriteString(const char* mask, String value);
  Boolean WriteByte(const char* mask, Byte value);
  Boolean WriteDual(const char* mask, UInt16 value);
  Boolean WriteQuad(const char* mask, UInt32 value);
  Boolean WriteInt16(const char* mask, Int16 value);
  Boolean WriteUInt16(const char* mask, UInt16 value);
  Boolean WriteInt32(const char* mask, Int32 value);
  Boolean WriteUInt32(const char* mask, UInt32 value);
  Boolean WriteFloat32(const char* mask, Float32 value);
  Boolean WriteDouble64(const char* mask, Double64 value);
  Boolean WriteLine(void);
  // Boolean WritePrompt(void);
  // Boolean WriteLinePrompt(void);
  Boolean WriteComment(void);
  Boolean WriteComment(String comment);
  Boolean WriteComment(const char* mask, String comment);
  Boolean WriteEvent(const char* event);
  Boolean WriteEvent(const char* mask, const char* event);
  Boolean WriteResponse(String comment);
  Boolean WriteResponse(const char* mask, String comment);
  //
  // Read
  UInt8 GetRxCount(void);
  Boolean ReadCharacter(char &rxcharacter);
  Boolean ReadText(char* ptext);
  Boolean ReadLine(char* rxline, int &rxsize);
  //
  // ??? Boolean Execute(void);
};
//
#endif // InterfaceUart_h
//
#endif // INTERFACE_UART
//
//
