#pragma once
#ifndef SW_USBSERVER_H
#define SW_USBSERVER_H

#define HID_REPORT_LENGTH 640

#define SER_STAT_STOPPED    0
#define SER_STAT_SEARCHING  1
#define SER_STAT_CONNECTING 2
#define SER_STAT_CONNECTED  3
#define SER_STAT_RUNNING    4

#define HANDSHAKE_MSG_TER "SMARTWHEELS_HANDSHAKE_TERMINAL"
#define HANDSHAKE_MSG_PC  "SMARTWHEELS_HANDSHAKE_PC"
#define TICK_MSG_PC "PCTICK"

#include <mbed.h>
#include <rtos.h>
#include <list>
#include <string>

namespace SW
{
    class USBServer : public Serial
    {
    public:
        USBServer(uint16_t vendor_id=0x1234, uint16_t product_id=0x0006);
        
        virtual ~USBServer();
        
        void Update(float deltaTime);
        
        bool PushReliableMsg(const char type, const std::string & msg);
        
        bool PushUnreliableMsg(const char type, const std::string & msg);
        
        void Terminate();
        
        uint8_t GetStatus() const;
        
    private:
        
        bool m_shouldTerminate;
        
        uint8_t m_stat;
        
        Thread * m_usbThread;
        
        std::list<std::string> m_msgQueue;
        
        Mutex m_qlocker;
        
        char * m_recvBuf;
        
        unsigned char m_bufPos;
        
        bool m_hasMsgIn;
        
        bool m_isReading;
        
        void RunningThread();
        
        void ConnectingThread();
        
        void RxCallback();
    };
}
#endif