#if !defined( _IOACOMPORT_H )
#define _IOACOMPORT_H

#include "SerialLink.h"

class IoACOMPort : public IoASerialLink
{
public:
    IoACOMPort( );
    ~IoACOMPort( ) {  Close( ); }  // note: base class destructor cannot call IoACOMPort::Close( )

    // COM port specifics
    int SetPort( int Port );
    int Port( ) const { return m_nPort; }

    int SetInputQueueSize( int InputQueueSize );
    int InputQueueSize( ) const { return m_nInputQueueSize; }

    int SetOutputQueueSize( int OutputQueueSize );
    int OutputQueueSize( ) const { return m_nOutputQueueSize; }

    // Implementation of IoASerialLink pure virtual functions
    void Detach( ) { Close( ); IoASerialLink::Detach( ); }

    int Open( );
    void Close( );

    int ReadChar( unsigned char& Cha, DWORD TimeoutInMilliseconds = INFINITE );
    int ReadChar( unsigned char& Cha, const IoATimer& Timeout );

    int WriteChar( unsigned char Cha, DWORD TimeoutInMilliseconds = INFINITE );
    int WriteChar( unsigned char Cha, const IoATimer& Timeout );

    int ReadBytes( unsigned char *Buffer, int Size, DWORD TimeoutInMilliseconds = INFINITE );
    int ReadBytes( unsigned char *Buffer, int Size, const IoATimer& Timeout );

    int WriteBytes( const unsigned char *Buffer, int Size, DWORD TimeoutInMilliseconds = INFINITE );
    int WriteBytes( const unsigned char *Buffer, int Size, const IoATimer& Timeout );

    int QueuedInput( ) const;
    int QueuedOutput( ) const;

    int WaitForInput( double Timeout = 1.0, int ByteCount = 1 );
    int WaitForOutput( double Timeout = 1.0, int ByteCount = 0 );

    int Purge( );
    int PurgeInput( );
    int PurgeOutput( );

    int Break( int On );
    int Break( double Duration = 0.2 );

    int SetBaudRate( int BaudRate );

    HANDLE Handle( ) const { return m_hCOMPort; }

private:
    void ClearCommError( const char *Function );

    // COM port variables
    int m_nPort;

    int m_nInputQueueSize;
    int m_nOutputQueueSize;

    HANDLE m_hCOMPort;

    DCB m_DCB;

    OVERLAPPED m_OverlappedRead;
    OVERLAPPED m_OverlappedWrite;
    OVERLAPPED m_OverlappedWait;
};

#endif
