#ifndef __FICAMERA__
#define __FICAMERA__

#include <initguid.h>

typedef HRESULT (*YuvToRgbCallback)(BYTE *, BITMAPINFOHEADER *, void*);

//-----------------------------------------------------------------------
#define FiFeatureControl_Flags_Auto        0X0001L
#define FiFeatureControl_Flags_Manual      0X0002L
#define FiFeatureControl_Flags_One_Push    0X0004L
#define FiFeatureControl_Flags_On          0X0008L
#define FiFeatureControl_Flags_Off         0X0010L

#define FiFeatureControl_Flags_Absolute    0X0020L
#define FiFeatureControl_Flags_Relative    0X0040L
//-----------------------------------------------------------------------

DEFINE_GUID(MEDIASUBTYPE_Y422,
0x32323459, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

//DEFINE_GUID(MEDIASUBTYPE_Y411,
//0x31313459, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

DEFINE_GUID(MEDIASUBTYPE_Y444,
0x34343459, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

DEFINE_GUID(MEDIASUBTYPE_Y800,
0x30303859, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

DEFINE_GUID(MEDIASUBTYPE_Y160,
0x30363159, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

DEFINE_GUID(MEDIASUBTYPE_RGB48,
0x34424752, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

DEFINE_GUID(MEDIASUBTYPE_SY16,
0x36315953, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

DEFINE_GUID(MEDIASUBTYPE_SRGB48,
0x42475253, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

DEFINE_GUID(MEDIASUBTYPE_RAW8,
0x38574152, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

DEFINE_GUID(MEDIASUBTYPE_RAW16,
0x31574152, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

// {32555949-0000-0010-8000-00AA00389B71}
DEFINE_GUID(ImagingClass,
0x6bdd1fc6, 0x810f, 0x11d0, 0xbe, 0xc7, 0x08, 0x00, 0x2b, 0xe2, 0x09, 0x2f);

#if !defined(FOURCC_Y444)
#define FOURCC_Y444 mmioFOURCC('Y','4','4','4')
#endif

#if !defined(FOURCC_Y411)
#define FOURCC_Y411 mmioFOURCC('Y','4','1','1')
#endif

#if !defined(FOURCC_Y422)
#define FOURCC_Y422 mmioFOURCC('Y','4','2','2')
#endif

#if !defined(FOURCC_Y800)
#define FOURCC_Y800 mmioFOURCC('Y','8','0','0')
#endif

#if !defined(FOURCC_Y160)
#define FOURCC_Y160 mmioFOURCC('Y','1','6','0')
#endif

#if !defined(FOURCC_RGB48)
#define FOURCC_RGB48 mmioFOURCC('R', 'G', 'B', '4')
#endif

#if !defined(FOURCC_SY16)
#define FOURCC_SY16  mmioFOURCC('S', 'Y', '1', '6')
#endif

#if !defined(FOURCC_SRGB48)
#define FOURCC_SRGB48 mmioFOURCC('S', 'R', 'G', 'B')
#endif

#if !defined(FOURCC_RAW8)
#define FOURCC_RAW8  mmioFOURCC('R', 'A', 'W', '8')
#endif

#if !defined(FOURCC_RAW16)
#define FOURCC_RAW16 mmioFOURCC('R', 'A', 'W', '1')
#endif

//-----------------------------------------------------------------------
typedef enum
{
    pixel_format_none = -1,
    Y_MONO = 0,
    YUV_411,
    YUV_422,
    YUV_444,
    RGB_24,
    Y_MONO_16,
    RGB_48,
    S_Y_MONO_16,
    S_RGB_48,
    RAW_8,
    RAW_16
}
FIREi_PIXEL_FORMAT, *PFIREi_PIXEL_FORMAT;

inline FIREi_PIXEL_FORMAT operator++( FIREi_PIXEL_FORMAT &rs, int )
{
    rs = (FIREi_PIXEL_FORMAT)(rs + 1);

    return rs;
}

typedef enum
{
    res_none = -1,
    res_160x120 = 0,
    res_320x240,
    res_640x480,
    res_800x600,
    res_1024x768,
    res_1280x960,
    res_1600x1200,
    res_variable,
    res_variable_1,
    res_variable_2,
    res_variable_3,
    res_variable_4,
    res_variable_5,
    res_variable_6,
    res_variable_7
} FIREi_RES, *PFIREi_RES;

inline FIREi_RES operator++( FIREi_RES &rs, int )
{
    rs = (FIREi_RES)(rs + 1);

    return rs;
}

typedef enum
{
    fps_none = -1,
    fps_1_875 = 0,
    fps_3_75,
    fps_7_5,
    fps_15,
    fps_30,
    fps_60,
    fps_120,
    fps_240
} FIREi_FPS, *PFIREi_FPS;

inline FIREi_FPS operator++( FIREi_FPS &rs, int )
{
    rs = (FIREi_FPS)(rs + 1);

    return rs;
}

typedef enum
{
    raw_mode_none,
    raw_mode_rggb,
    raw_mode_grbg,
    raw_mode_gbrg,
    raw_mode_bggr
}
FIREi_RAW_MODE, *PFIREi_RAW_MODE;

inline FIREi_RAW_MODE operator++( FIREi_RAW_MODE &rs, int )
{
    rs = (FIREi_RAW_MODE)(rs + 1);

    return rs;
}

typedef enum
{
    nearest_neighbour_replication,
    bilinear_interpolation
}
FIREi_RAW_MODE_CONVERSION, *PFIREi_RAW_MODE_CONVERSION;

inline FIREi_RAW_MODE_CONVERSION operator++( FIREi_RAW_MODE_CONVERSION &rs, int )
{
    rs = (FIREi_RAW_MODE_CONVERSION)(rs + 1);

    return rs;
}

typedef enum
{
    FormatRGB32=0,
    FormatY800,
    FormatY444,
    FormatY422,
    FormatY411,
    FormatY160
}PixelFormat;
//-----------------------------------------------------------------------
typedef enum
{
    FiExpoControl_Autoexp=0,
    FiExpoControl_Shutter,
    FiExpoControl_Gain,
    FiExpoControl_Iris
} FiExpoControlProperty;
//-----------------------------------------------------------------------
typedef enum
{
    FiColorControl_UB=0,
    FiColorControl_VR,
    FiColorControl_Hue,
    FiColorControl_Saturation
} FiColorControlProperty;
//-----------------------------------------------------------------------
typedef enum
{
    FiBasicControl_Focus=0,
    FiBasicControl_Zoom,
    FiBasicControl_Brightness,
    FiBasicControl_Sharpness,
    FiBasicControl_Gamma
} FiBasicControlProperty;

//-----------------------------------------------------------------------
typedef enum 
{
    LICENCE_TYPE_HASP_VGA,
    LICENCE_TYPE_HASP_PRO,
    LICENCE_TYPE_UB_ADAPTER,
    LICENCE_TYPE_UB_CAMERA,
    LICENCE_TYPE_PK,
    LICENCE_TYPE_OEM,
    LICENCE_TYPE_DEMO
}FIREi_LICENCE_TYPE;
//-----------------------------------------------------------------------

typedef struct
{
    UCHAR Bytes[8];
}FIREi_1394_GUID,*PFIREi_1394_GUID;

typedef struct
{
    UCHAR Bytes[8];
}CAMERA_GUID,*PCAMERA_GUID;

typedef struct 
{
    CAMERA_GUID CameraGuid;
    LONG    uCameraNodeID;
    char    szCameraVendor[64];
    char    szCameraModelName[64];
    LONG    uCameraSerial;
}
Fi_VENDOR_INFO,*PFi_VENDOR_INFO;

//-----------------------------------------------------------------------

typedef struct _Fi_VIDEO_FORMAT_INFO
{
    // A pointer to the media type of the stream format
    AM_MEDIA_TYPE              *pMediaType;

    // A structure describing extra configuration
    // capabilities of the stream format
    VIDEO_STREAM_CONFIG_CAPS    ConfigCaps;

    // A bitmask that lists all the supported frame rates for 
    // the current format
    ULONG                       SupportedFpsMask;

    // A rectangle describing the custom image 
    // position and dimensions. This is applicable
    // only to scalable formats.
    RECT                        CustomRect;
}
Fi_VIDEO_FORMAT_INFO,*PFi_VIDEO_FORMAT_INFO;

typedef struct _Fi_PACKET_INFO
{
    // Packet sizes can be units of this
    // This is also the minimum bytes per packet
    ULONG UnitPacketBytes;

    // The maximum bytes per packet for a format
    ULONG MaxPacketBytes;
}
Fi_PACKET_INFO,*PFi_PACKET_INFO;

typedef struct _FIREi_TRIGGER_INFO
{
    // A parameter to the trigger function.
    // This parameter is vendor specific
    ULONG TriggerParameter:12;

    // The mode of the trigger function
    ULONG TriggerMode:4;

    // The polarity of the trigger pulse. 
    // 0 for a low trigger pulse and 1 for a 
    // high trigger pulse.
    ULONG TriggerPolarity:1;

    // The trigger source.
    ULONG TriggerSource:3;

    // Read only value of the input raw signal.
    // 0 for a low trigger signal and 1 for a 
    // high trigger signal.
    ULONG TriggerValue:1;
}
FIREi_TRIGGER_INFO,*PFIREi_TRIGGER_INFO;

typedef enum
{
    TriggerMode0,
    TriggerMode1,
    TriggerMode2,
    TriggerMode3,
    TriggerMode4,
    TriggerMode5,
    TriggerMode14 = 14,
    TriggerMode15 = 15
}
FIREi_TRIGGER_MODE, *PFIREi_TRIGGER_MODE;

inline FIREi_TRIGGER_MODE operator++( FIREi_TRIGGER_MODE &rs, int )
{
    if(TriggerMode5 == rs)
        rs = (FIREi_TRIGGER_MODE)(rs + 9);
    else
        rs = (FIREi_TRIGGER_MODE)(rs + 1);

    return rs;
}

typedef enum
{
    TriggerSource0  = 0,
    TriggerSource1  = 1,
    TriggerSource2  = 2,
    TriggerSource3  = 3,
    TriggerSourceSW = 7,
}FIREi_TRIGGER_SOURCE, *PFIREi_TRIGGER_SOURCE;

inline FIREi_TRIGGER_SOURCE operator++( FIREi_TRIGGER_SOURCE &rs, int )
{
    if(TriggerSource3 == rs)
        rs = (FIREi_TRIGGER_SOURCE)(rs + 4);
    else
        rs = (FIREi_TRIGGER_SOURCE)(rs + 1);

    return rs;
}


typedef struct _FIREi_TRIGGER_CAPS
{
    // Bit mask indicating the trigger modes.
    // If a trigger mode is supported the bit 
    // corresponding to the trigger mode index
    // is set. The trigger mode index is the 
    // value of the corresponding trigger mode 
    // member of the FIREi_TRIGGER_MODE enumerated
    // type.
    ULONG TriggerModeMask;

    // Bit mask indicating the available trigger sources.
    // If a trigger source is supported the bit 
    // corresponding to the trigger source index
    // is set. The trigger source index is the 
    // value of the corresponding trigger source
    // member of the FIREi_TRIGGER_SOURCE enumarated
    // type.
    ULONG TriggerSourceMask;

    // The availability of trigger polarity setting.
    ULONG TriggerPolarity:1;
}FIREi_TRIGGER_CAPS,*PFIREi_TRIGGER_CAPS;

typedef enum
{
    Generic,
    SONY_DFW_V500,
    SONY_DFW_VL500,
    SONY_XCD_X700,
    SONY_DFW_V300,       
    SONY_DFW_X700,
    SONY_DFW_X710,
    SONY_XCD_SX900,
    SONY_DFW_SX900,
    SONY_DFW_SX910,
    SONY_XCD_X710,
    SONY_XCD_X710CR,
    SONY_XCD_SX910,
    SONY_XCD_SX910CR,
    SONY_XCD_V50,
    SONY_XCD_V50CR,

    Basler_A301b, 
    Basler_A302b, 
    Basler_A301f, 
    Basler_A302fs, 
    Basler_A101f,
    Basler_A102k,
    Basler_A102kc, 
    Basler_A102f,
    Basler_A102fc, 
    Basler_A311f,
    Basler_A311fc,
    Basler_A312f,
    Basler_A312fc, 
    Basler_A601f,
    Basler_A601fc,
    Basler_A602f,
    Basler_A602fc, 
    Basler_A622f,
    Basler_A631f,
    Basler_A631fc, 
    Basler_A641f,
    Basler_A641fc, 

    AVT_Dolphin_F145b,
    AVT_D1,
    AVT_D2,
    AVT_Marlin_F145C2,
    AVT_Marlin_F033B,
    AVT_Marlin_F033C,
    AVT_Marlin_F046B,
    AVT_Marlin_F046C,
    AVT_Marlin_F080B,
    AVT_Marlin_F080C,
    AVT_Dolphin_F201c,
    AVT_Marlin_F145B2,

    JVC_KYF75U,
    JVC_KYF1030,

    Hamamatsu_C8484_05G,
    Hamamatsu_C8484_15G,

    PointGrey_DragonFly,
    PointGrey_FireFly,
    PointGrey_Scorpion,

    Unibrain_Firei,
    Unibrain_Firei400,
    Unibrain_Firei_BBW,
    Unibrain_Firei_BCL,
    Unibrain_Firei_BCR,
    Unibrain_Firei_501c,
    Unibrain_Firei_501b,
    Unibrain_Firei_601c,
    Unibrain_Firei_601b,
    Unibrain_Firei_701c,
    Unibrain_Firei_701b,
    Unibrain_Firei_801c,
    Unibrain_Firei_801b,

    CCD_Direct_Micropix,

    Cohu7700,

    ISGCorp_CAC1030,

    Teli_CSB4000F,
    
    iRez_StealthFire,
    iRez_StealthFire2,

    OrangeMicro_IBot,

    Ads_Pyro,
    
    Apple_iSight,

    PixeLINK_A741,

    Hitachi_HVF31F,
    Hitachi_HVF22F,
    Hitachi_KP120F,

    IMI_IMC_50FT,
    IMI_IMC_70FT,
    IMI_IMC_42FT,
    IMI_IMC_35FT,
    IMI_IMC_36FT,
    IMI_IMC_40FT,
    IMI_IMC_80F,
    IMI_IMC_80FT,
    IMI_IMC_81FT,
    IMI_IMC_140F ,
    IMI_IMC_140FT,
    IMI_IMC_141FT,
    IMI_IMC_146FT,
    IMI_IMC_200FT,
    IMI_IMC_201FT,
    IMI_IMB_50FT,
    IMI_IMB_70FT,
    IMI_IMB_42FT,
    IMI_IMB_35FT,
    IMI_IMB_36FT,
    IMI_IMB_40FT,
    IMI_IMB_80FT,
    IMI_IMB_81FT,
    IMI_IMB_140FT,
    IMI_IMB_141FT,
    IMI_IMB_146FT,
    IMI_IMB_201FT,

    Foculus_FO113B,
    Foculus_FO114B,
    Foculus_FO124B,
    Foculus_FO134B,
    Foculus_FO234B,
    Foculus_FO322B,
    Foculus_FO323B,
    Foculus_FO430B,
    Foculus_FO432B,
    Foculus_FO442B,
    Foculus_FO531B,
    Foculus_FO113C,
    Foculus_FO114C,
    Foculus_FO124C,
    Foculus_FO134C,
    Foculus_FO234C,
    Foculus_FO322C,
    Foculus_FO323C,
    Foculus_FO430C,
    Foculus_FO432C,
    Foculus_FO442C,
    Foculus_FO531C,
    Foculus_FO113T,

} FIREi_CAMERA_MODEL;

typedef struct
{
    CHAR                Key[128];
    FIREi_CAMERA_MODEL  Model;
} FIREi_CAMERA_MODEL_ENTRY;

#include <string>

typedef enum
{
    ks,
    s,
    ms,
    us,
    ps
}FIREi_TIME_UNIT;

typedef enum
{
    TimeBase0,
    TimeBase1,
    TimeBase2,
    TimeBase3,
    TimeBase4,
    TimeBase5,
    TimeBase6,
    TimeBase7,
    TimeBase8,
    TimeBase9
}FIREi_TIMEBASE_ID;

#define FIREi_SAVE_FLAGS_RGB    0
#define FIREi_SAVE_FLAGS_JPEG   1
#define FIREi_SAVE_FLAGS_GIF    2
#define FIREi_SAVE_FLAGS_TIFF   3
#define FIREi_SAVE_FLAGS_PNG    4

#define FIREi_ISOCH_CYCLE_TIME  (1250)

typedef UCHAR FIREi_SPEED_CODE;

#define FIREi_SPEED_S100        ((FIREi_SPEED_CODE)0)
#define FIREi_SPEED_S200        ((FIREi_SPEED_CODE)1)
#define FIREi_SPEED_S400        ((FIREi_SPEED_CODE)2)
#define FIREi_SPEED_S800        ((FIREi_SPEED_CODE)3)
#define FIREi_SPEED_S1600       ((FIREi_SPEED_CODE)4)
#define FIREi_SPEED_S3200       ((FIREi_SPEED_CODE)5)

typedef enum
{
    FIREi_ADAPTER_PLATFORM_UBCORE,
    FIREi_ADAPTER_PLATFORM_MSSTACK,
}FIREi_ADAPTER_PLATFORM;

typedef struct 
{
    FIREi_1394_GUID        Guid;
    FIREi_SPEED_CODE       Speed;
    FIREi_ADAPTER_PLATFORM Platform;
    BOOL                   HasHardwareLicence;
}FIREi_ADAPTER_INFO, *PFIREi_ADAPTER_INFO;

#endif // __FICAMERA__
