//-----------------------------------------------------------------------------
#ifndef SerCamApiH
#define SerCamApiH SerCamApiH
//-----------------------------------------------------------------------------
#include <common/System/Platform.h>
#include <string>
#include <vector>

namespace mv
{

typedef void ( *FStatus )( size_t bytesSent, size_t bytesToSend );

class SerCamApi
{
    DISALLOW_COPY_AND_ASSIGN( SerCamApi )
public:
    explicit        SerCamApi() : m_Timeout( 5000 ) {}
    ~SerCamApi( void ) {}

    void            CallFunc( std::string& inStr, std::string& outStr, bool bFormattedOutput = false );
    void            FlashUpdate( std::string& filename, unsigned int addr, size_t blocksize,
                                 std::string& version, bool& bFactory, FStatus callback = 0 );
    void            FlashRead( unsigned int addr, size_t count, std::vector<unsigned char>& vContent,
                               size_t blocksize, FStatus callback = 0 );
    int             SetTimeout( int timeout_ms )
    {
        int tmp = m_Timeout;
        m_Timeout = timeout_ms;
        return tmp;
    }
    int             GetTimeout( void ) const
    {
        return m_Timeout;
    }

    void            GetAvailablePorts( std::vector<std::string>& ports );
    bool            SetCurrentPort( const std::string& port );
    void            SetCurrentDevice( const int deviceNr );
    void            SetBaudrate( const unsigned long baudrate );

    void            Register( const std::string& desc );
    void            RegisterEnum( const std::string& name, int value32Bit, std::string& str );

    // only for backward compatibility
    void*           GetFuncMgr( void );
    void*           GetPortMgr( void );

    //---- Deprecated
    void            GetVersion( std::string& version, bool& bFactory );
    void            ReadSnr( std::string& serialNumber );
    void            WriteSnr( std::string& serialNumber );
    unsigned int    ReadDigIO( void );
    void            WriteDigIO( unsigned int digio );
    void            TestImage( bool bEnable );
    void            SavePara( void );
    void            LoadPara( void );
    void            SetDefaultPara( void );
    void            RamTest( void );
    void*           GetInternalObj( void );
private:
    void            WaitForDevice( std::string& version, bool& bFactory );
    int             FuncCall( std::vector<unsigned char>& vStream, int timeout_ms = -1 );
    int             m_Timeout;
};

/*------------------ Example
void main()
{

    SerCamApi   serCamApi();

    serCamApi.SetCurrentPort("CL_Port0");
    serCamApi.SetBaudrate(115200);

    serCamApi.Register(string("GetVersion#0@b[ErrorCode]s[Version]b[isUserConfig]/"));
    serCamApi.Register(string("SelBaudrate#1@b[ErrorCode]/b[Baudselect0-7]"));
    serCamApi.Register(string("MemoryRead#16@b[ErrorCode]ia[MemoryContent:x]/i[Avalon_Address]b[NrOfWords]"));
    serCamApi.Register(string("MemoryWrite#17@b[ErrorCode]/i[Avalon_Address]ia[MemoryContent]"));
    serCamApi.Register(string("I2CRead#18@b[ErrorCode]ba[Data]/b[Addr]b[SubAddr]b[Length]"));
    serCamApi.Register(string("I2CWrite#19@b[ErrorCode]/b[Addr]b[SubAddr]ba[MemoryContent]"));
    serCamApi.Register(string("SPIRead#20@b[ErrorCode]b[MemoryContent]/b[Address]"));
    serCamApi.Register(string("SPIWrite#21@b[ErrorCode]/b[Address]b[MemoryContent]"));
    serCamApi.Register(string("SPIConfig#22@b[ErrorCode]/w[Prescaler]b[NrOfBits]b[Config_1bThrow1Away_1bSampIn_1bSampOut_2bChoose_1bClk_1bCS]w[delayFront]w[delayBack]"));
    serCamApi.Register(string("CamCtrl_Mode#32@b[ErrorCode]/b[Mode]"));
    serCamApi.Register(string("CamCtrl_Timing#33@b[ErrorCode]/w[Capacity_Reset]w[Store_Bright]w[Store_Dark]w[Pixel_Reset]b[Linestart_Delay]"));
    serCamApi.Register(string("CamCtrl_IntegrationLine#34@b[ErrorCode]/w[Integration_Line]"));
    serCamApi.Register(string("CamCtrl_Dimension#35@b[ErrorCode]/w[Frame_Width]w[Frame_Height]w[AOI_X_Start]w[AOI_Y_Start]w[AOI_X_End]w[AOI_Y_End]"));
    serCamApi.Register(string("TestImage#36@b[ErrorCode]/b[Enable]"));
    serCamApi.Register(string("CamCtrl_SetGain#37@b[ErrorCode]/w[gain_in_db_x1000]"));
    serCamApi.Register(string("CamCtrl_GetGain#38@b[ErrorCode]w[gain_in_db_x1000]/"));
    serCamApi.Register(string("CamCtrl_Offset#39@b[ErrorCode]/w[offset_0_to_4095]"));
    serCamApi.Register(string("SetDigout#48@b[ErrorCode]/b[DigState]"));
    serCamApi.Register(string("GetDigin#49@b[ErrorCode]b[DigState]/"));
    serCamApi.Register(string("FlashRead#64@b[ErrorCode]ba[MemoryContent]/i[Address]b[length]"));
    serCamApi.Register(string("FlashWrite#65@b[ErrorCode]/i[Address]ba[MemoryContent]"));
    serCamApi.Register(string("StartUpdate#66@b[ErrorCode]/"));
    serCamApi.Register(string("EndUpdate#67@b[ErrorCode]/i[StartAddress]i[EndAddress]i[CRC]"));
    serCamApi.Register(string("WriteDbgReg#66@b[ErrorCode]/i[doubleWord]"));
    serCamApi.Register(string("ReadSnr#240@b[ErrorCode]s[SerialNumber]/"));
    serCamApi.Register(string("WriteSnr#241@b[ErrorCode]/s[SerialNumber]"));
    serCamApi.Register(string("RamTest#242@b[ErrorCode]/"));

    string inStr;
    string outStr;

    inStr = "GetVersion";
    serCamApi.CallFunc(inStr, outStr);
    printf("inStr:   %s\n", inStr.c_str());
    printf("outStr:  %s\n\n", outStr.c_str());

    inStr.clear();
    outStr.clear();
    inStr = "MemoryRead 0 10";
    serCamApi.CallFunc(inStr, outStr);
    printf("inStr:   %s\n", inStr.c_str());
    printf("outStr:  %s\n", outStr.c_str());
}

------------------ Example */

} // namespace mv


#endif // SerCamApiH
