/*! 
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright(c) 2010 Apogee Instruments, Inc. 
* \class GenTwoWinUSB 
* \brief USB IO class that communicates with the WinUSB driver 
* 
*/ 


#ifndef GENTWOWINUSB_INCLUDE_H__ 
#define GENTWOWINUSB_INCLUDE_H__ 

#include <windows.h>
#include <string>
#include <vector>

#include "IUsb.h"
#include "winusb.h"


#define APUSB_8051_REV_BYTE_COUNT	3

#define APUSB_CUSTOM_SN_DID_SUPPORT	0x0011
#define APUSB_8051_REV_DID_SUPPORT	0x0011
#define APUSB_CI_DID_SUPPORT		0x0011


class GenTwoWinUSB : public IUsb
{ 
    public: 
            enum Direction { In, Out };
    public: 
        GenTwoWinUSB( const uint16_t DeviceNum );
        virtual ~GenTwoWinUSB(); 

        uint16_t ReadReg(uint16_t FpgaReg);

        void WriteReg(uint16_t FpgaReg, 
            const uint16_t FpgaData );

        void GetVendorInfo(uint16_t & VendorId,
            uint16_t & ProductId, uint16_t  & DeviceId);

        void SetupSingleImgXfer(uint16_t Rows, 
            uint32_t Cols);

        void SetupSequenceImgXfer(uint16_t Rows,
            uint16_t Cols, uint16_t NumOfImages);

        void CancelImgXfer();

        void ReadImage(uint16_t * ImageData, 
            const uint32_t InSizeInBytes,
            uint32_t &OutSizeInBytes);

        void GetStatus(uint8_t * status, uint32_t NumBytes);

        void UsbRequestIn(uint8_t RequestCode,
            uint16_t	Index, uint16_t	Value,
            uint8_t * ioBuf, uint32_t BufSzInBytes);

        void UsbRequestOut(uint8_t RequestCode,
            uint16_t	Index, uint16_t	Value,
            const uint8_t * ioBuf, uint32_t BufSzInBytes);

        void GetSerialNumber(int8_t  * ioBuf, uint32_t BufSzInBytes);

        void GetUsbFirmwareVersion(int8_t  * ioBuf, uint32_t BufSzInBytes);

        std::string GetDriverVersion();

        bool IsError();

        uint16_t GetDeviceNum() { return m_DeviceNum; }

        void UsbReqOutWithExtendedTimeout(uint8_t RequestCode,
            uint16_t Index, uint16_t	Value,
            const uint8_t * ioBuf, uint32_t BufSzInBytes);

        void ReadSerialPort( uint16_t PortId, 
            uint8_t * ioBuf, uint16_t BufSzInBytes );

    protected:
        void VendorRequest( enum Direction,
            unsigned char bRequest,
            unsigned short wValue,
            unsigned short wIndex,
            unsigned char * Buffer = NULL,
            size_t BufferSize = 0
        );

    private:
        HANDLE m_device;
        WINUSB_INTERFACE_HANDLE m_winusb;
        USB_DEVICE_DESCRIPTOR m_Descriptor;
        std::string m_DeviceName;
        std::string m_DriverVersion;
        const std::string m_fileName;
        bool m_ReadImgError;
        bool m_IoError;
        uint16_t m_DeviceNum;
        
        //disabling the copy ctor and assignment operator
        //generated by the compiler - don't want them
        //Effective C++ Item 6
        GenTwoWinUSB(const GenTwoWinUSB&);
        GenTwoWinUSB& operator=(GenTwoWinUSB&);
}; 

#endif