#!/usr/bin/env python

#------------------------------------------------------------------------------
#                 pyiCube - API Python bindings
#
# Copyright (c) 2018 by Net GmbH.
# All rights reserved.
#
# pyiCube is a lean wrapper implementation of Python function objects that
# represent iCube API functions. These bindings could be used as is.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#------------------------------------------------------------------------------

__author__     = "Net GmbH"
__copyright__  = "Copyright 2018, Net GmbH"
__maintainer__ = "Net GmbH"

import ctypes
import sys
try:
    import numpy as np
except:
    pass

# ----------------------------------------------------------------------------
# Global Defines
# ----------------------------------------------------------------------------

IC_SUCCESS = 0
IC_ERROR = 1

# Additional error codes

IC_IF_NOT_OPEN =               -1
IC_WRONG_PARAM =               -2
IC_OUT_OF_MEMORY =             -3
IC_ALREADY_DONE =              -4
IC_WRONG_CLOCK_VAL =           -5
IC_COM_LIB_INIT =              -6
IC_NOT_IF_STARTED =            -7
IC_WRONG_ROI_ID =              -8
IC_IF_NOT_ENABLED =            -9
IC_COLOR_CAM_ONLY =           -10
IC_DRIVER_VERSION =           -11
IC_D3D_INIT =                 -12
IC_BAD_POINTER =              -13
IC_ERROR_FILE_SIZE =          -14
IC_RECONNECTION_ACTIVE =      -15
IC_USB_REQUEST_FAIL =         -16   # usb communication with the camera failed
IC_RESOURCE_IN_USE =          -17      
IC_DEVICE_GONE =              -18   # camera is not accsessible  
IC_DLL_MISMATCH =             -19   # dll versions are not compatible
IC_WRONG_FW_VERSION =         -20   # feature not supported by this firmware version
IC_NO_RGB_CALLBACK =          -21   # SaveToFile() needs eihter a preview or rgb callback enabled
IC_NO_USB30_CAMERA =          -22   # feature not supported by usb2.0 cameras
IC_ERR_FIX_RELATION =         -23   # serial number of fix registered device does not match
IC_CRC_CONFIG_DATA =          -24   # crc of config data is corrupt
IC_CONFIG_DATA =              -25   # config data is corrupt
IC_ERR_START_PNP =            -26   
IC_INVALID_CAM_TYPE =         -27  
IC_NOT_IF_STREAMING =         -28   
IC_USB_STARTUP =              -29   

# Video Mode definitions
# (used with: ICubeSDK_SetMode,ICubeSDK_GetMode)

MODE_320x240 =                  0
MODE_640x480 =                  1
MODE_752x480 =                  2
MODE_800x600 =                  3
MODE_1024x768 =                 4
MODE_1280x1024 =                5
MODE_1600x1200 =                6
MODE_2048x1536 =                7
MODE_2592x1944 =                8
MODE_3840x2748 =                9
MODE_1920x1200 =               10

# BinSkip definitions
# (used with: ICubeSDK_SetBinSkip,ICubeSDK_GetBinSkip,ICubeSDK_GetBinSkipList)

MODE_SKIP =                     0
MODE_BIN =                      1
BIN_SKIP_OFF =                  0
BIN_SKIP_2ND_PIXEL =            1
BIN_SKIP_4TH_PIXEL =            2


# Parameter definitions 
# (used with: ICubeSDK_SetCamParameter,ICubeSDK_GetCamParameter,
# ICubeSDK_GetCamParameterRange,ICubeSDK_GetParamAuto,ICubeSDK_SetParamAuto,
# ICubeSDK_SetParamAutoDef,ICubeSDK_SetParamOnePush)

# Measure field definitions
# (used with REG_MEASURE_FIELD_AE)

MEASUREFIELD_100 =              2     # 100% (full frame,default)
MEASUREFIELD_60 =               1     # 60%
MEASUREFIELD_30 =               0     # 30%

# Shutter definitions
# (used with REG_SHUTTER)

SHUTTER_ROLLING =               0     # all models
SHUTTER_GLOBAL_RESET =          1     # (4133CU/BU,4133CU only)
SHUTTER_GLOBAL =                2     # (4133CU/BU (default),4133CU (default) only)

# Parameter ON||OFF definitions

OFF =                           0
ON =                            1

# Trigger invert definitions
# hardware trigger will be detected on the defined edge
# (used with REG_TRIGGER_INVERT)

FALLING_EDGE =                  0     # (default)
RISING_EDGE =                   1

# Software trigger mode definitions
# (used with REG_SW_TRIG_MODE)

DELAYED_TRIGGER_RETURN =        0     # camera checks for frame arrival (default),
                                      # ICubeSDK_SetTrigger(..,TRIG_SW_DO) returns this status
IMMEDIATE_TRIGGER_RETURN =      1     # no camera check

# Data transmission definitions
# (used with REG_DATA_TRANSMISSION)

IS_8BIT =                       0     #(default)  
IS_16BIT =                      1           

#Bayer Conversion definitions
#(used with REG_BAYER_CONVERSION)

DE_BAYER_3x3 =                  0          
DE_BAYER_5x5 =                  1     # (default)           

# Gamma definitions
# (used with REG_GAMMA_MODE)

GAMMA_MODE_DEFAULT =            2     # (default)   
GAMMA_MODE_sRGB =               1
GAMMA_MODE_ITU709 =             0     # (HDTV)

# Graphic definitions 
# (used with REG_GRAPHIC_MODE)

DISPLAY_GDI =                   0
DISPLAY_D3D =                   1


# Camera parameters definitions

REG_BRIGHTNESS =                1     # write: only when REG_COLOR_PROCCESSING enabled, read: always
REG_CONTRAST =                  2     # write: only when REG_COLOR_PROCCESSING enabled, read: always
REG_GAMMA =                     3     # write: only when REG_GAMMA_ENABLE enabled, read: always
REG_FLIPPED_V =                 4     # (ON||OFF); OFF (default)
REG_FLIPPED_H =                 5     # (ON||OFF); OFF (default)
REG_WHITE_BALANCE =             6     # (one push)
REG_EXPOSURE_TIME =             7     # all models
REG_EXPOSURE_TARGET =           8     # sets the target-value for the auto exposure algorithm 
REG_RED =                       9     # only for color models; RGB Gain value
REG_GREEN =                    10     # only for color models
REG_BLUE =                     11     # only for color models
REG_BLACKLEVEL =               12     # sensor blacklevel
REG_GAIN =                     13     # sensor gain
REG_COLOR =                    14     # (ON||OFF) read: color || bw model
REG_PLL =                      15     # all models
REG_STROBE_LENGHT =            16     # length of strobe pulse output (msec)
REG_STROBE_DELAY =             17     # delay before strobe pulse is executed (msec)
REG_TRIGGER_DELAY =            18     # delay before hardware trigger is executed (msec)
REG_SATURATION =               19     # only for color models, when REG_COLOR_PROCCESSING enabled 
REG_COLOR_ENHANCE =            20     # obsolet
REG_TRIGGER_INVERT =           21     # (FALLING_EDGE (default) || RISING_EDGE)
REG_RECONNECTIONS =            22     # get the value of camera reconnections
REG_MEASURE_FIELD_AE =         23     # measure field for auto exposure
REG_AVI_STATE =                24     # get the avi stream save status (ON||OFF)
REG_FOCUS =                    25     # not implemented yet
REG_SHUTTER =                  26     # (4133CU/BU,4133CU)
REG_ROI_ID =                   27     # (4133CU/BU,4133CU,fpga board cameras)
REG_ROI_CYCLE =                28     # (4133CU/BU,4133CU) number of repetitions of the particular roi

REG_DEFECT_COR =               43     # (4133CU/BU,4133CU) DefectPixelCorrection (ON||OFF); OFF(default)

REG_BAD_FRAME =                81     # read bad frame count (also possible with ICubeSDK_GetBrokenFrames)
REG_GOOD_FRAME =               82     # read good frame count (also possible with ICubeSDK_GetGoodFrames)
REG_SW_TRIG_MODE =             94     # (DELAYED_TRIGGER_RETURN (default) || IMMEDIATE_TRIGGER_RETURN)
REG_ROI_FPGA_ONE_FRAME =       96     # (fpga board only) pseudo frame format (ON||OFF)
REG_CALLBACK_BR_FRAMES =       97     # Broken frames also triggering the callback function (ON||OFF); OFF(default)
REG_FGPA_VBLANKING =           98     # (fpga board only) output Frame blanking
REG_FGPA_HBLANKING =           99     # (fpga board only) output Frame blanking
REG_FGPA_CLK_DIVIDER =        100     # (fpga board only) output clock divider (ON||OFF)
REG_FGPA_ON_BOARD =           101     # check if camera has fpga board (ON||OFF)

REG_SET_GPIO =                102     # bit masked: XXXX X J3-7 J3-6 J3-5
REG_GET_GPIO =                103     # bit masked: XXXX X J3-7 J3-6 J3-5
REG_SET_GPIO_MODE =           104     # (0==Input || 1==Output),bit masked: XXXX X J3-7 J3-6 J3-5

REG_MASK_ROI_ID =             105     # roi_id masked in buffersize of callback 

REG_RED_OFFSET =              106     # only for color models; RGB offset value
REG_GREEN_OFFSET =            107     # only for color models
REG_BLUE_OFFSET =             108     # only for color models

REG_HUE =                     109     # only for color models; write: only when REG_COLOR_PROCCESSING enabled, read: always
REG_COLOR_CORRECTION =        110     # (ON||OFF) ColorCorrection matrix; OFF (default)
REG_GAMMA_ENABLE =            111     # (ON||OFF) en/disable gamma module to save CPU load; ON (default)
REG_GAMMA_MODE =              112     # only for color models ; write: only when REG_GAMMA_ENABLE enabled, read: always
REG_INVERT_PIXEL =            113     # (ON||OFF)  bw cams only
REG_TNR =                     115     # (ON||OFF)  only for color models, temporal noise reduction
REG_BAYER_CONVERSION =        116     # only for color models; choose different debayering
REG_COLOR_PROCESSING =        117     # (ON||OFF) en/disable color proc module module to save CPU load;  ON (default)
REG_USB_SPEED =               118     # 0: usb port is high speed, 1: usb port is super speed capable (useful for super speed camera)
REG_DEVICE_SPEED =            119     # 0: camera is high speed, 1: camera is super speed capable
REG_DATA_TRANSMISSION =       120     # 0: 8 bit per pixel, 1: 16 bit per pixel in raw mode
REG_SIGNIFICANT_BITS =        125     # number of significant bits in pixel 
REG_GRAPHIC_MODE =            126     # GDI (default)|| D3D 
REG_EDGE_ENHANCEMENT =        128     # (ON||OFF) edge enhancement; OFF (default)
REG_EDGE_ENHANCEMENT_GAIN =   129     # 0-128 (default 64)

REG_TRIG_TIMEOUT =            138
REG_PIPE_TIMEOUT_MODE =       139
REG_RESET_CAMERA =            140     # reset the camera
REG_DISCONNECTIONS =          141     # get the value of camera disconnections
REG_XACT_RECOVER_MODE =       142     # (superspeed camera only) recover transaction errors
REG_RESET_TO_DEFAULT =        143     # reset all camera parameters to default values

REG_SW_TRIG_WD_MODE =         146
REG_AQU_FRAMERATE =           147     # (2234CU/BU) get/set the framerate


# Parameter definitions
# (used with: ICubeSDK_GetCamParameterRange)

class PARAM_PROPERTY(ctypes.Structure):
       _fields_ = [
          ("bEnabled",ctypes.c_int),
          ("bAuto",   ctypes.c_int),
          ("bOnePush",ctypes.c_int),
          ("nDef",    ctypes.c_uint),
          ("nMin",    ctypes.c_uint),
          ("nMax",    ctypes.c_ulong),
       ];
       
DEFAULT_GAMMA =                64


# Parameter definitions (float value)
# (used with: ICubeSDK_GetExposureRange)
# values in [msec]

class PARAM_PROPERTY_f(ctypes.Structure):
       _fields_ = [
          ("bEnabled",ctypes.c_int),
          ("bAuto",   ctypes.c_int),
          ("bOnePush",ctypes.c_int),
          ("nDef",    ctypes.c_float),
          ("nMin",    ctypes.c_float),
          ("nMax",    ctypes.c_float),
       ];

# Roi definitions
# (used with: REG_ROI_ID)

# ROI ID: (4133CU/BU)
# SIMR: Single Integration Multiple Roi  (4133CU/BU only)
# 1, 2 or 4 areas of interest to be acquired within the same integrated image
# MIMR: Multible Integration Multiple Roi (4133CU/BU only)

ROI_ID_1_2 =                   0     # SIMR (4133CU/BU only)
ROI_ID_1_1 =                   1     # default mode for all models (1st roi)
ROI_ID_2 =                     2     # MIMR additonal (4133CU/BU only)
ROI_ID_3 =                     3
ROI_ID_4 =                     4

# ROI ID: (all cameras with fpga board)

ROI_ID_0 =                     0     # fpga input size
ROI_ID_1 =                     1     # fpga output size roi 1
ROI_ID_2 =                     2   
ROI_ID_3 =                     3
ROI_ID_4 =                     4
ROI_ID_5 =                     5

# ROI ID: (all cameras without fpga board,except 4133CU/BU)
# only one roi available (roi1)

# (used with: ICubeSDK_SetResolution, ICubeSDK_GetResolution)

class ROI_PROPERTY(ctypes.Structure):
    _fields_ = [
       ('bEnabled', ctypes.c_int),
       ('nXRes',    ctypes.c_int),
       ('nYRes',    ctypes.c_int),
       ('nXPos',    ctypes.c_int),
       ('nYPos',    ctypes.c_int)
    ];



# Due to usb packet size, the Region of interest size has limitations.
# The horizontal and vertical Roi-size must be dividable by 4. 

ROI_STEP_SIZE =                4

# (11000CU/BU only)
# Due to sensor limitations, 
# the horizontal and vertical Roi-size must be dividable by 8. 

ROI_STEP_SIZE_11000 =          8


# (used with: ICubeSDK_GetResolutionRange)

class ROI_RANGE_PROPERTY(ctypes.Structure):
    _fields_ = [
       ('nXMin', ctypes.c_int),
       ('nXMax', ctypes.c_int),
       ('nYMin', ctypes.c_int),
       ('nYMax', ctypes.c_int)
    ];


# Trigger definitions
# (used with: ICubeSDK_SetTrigger, ICubeSDK_GetTrigger)

TRIG_SW_START =              0     # start software trigger
TRIG_SW_DO =                 1     # do a software trigger pulse
TRIG_HW_START =              2     # start hardware trigger
TRIG_STOP =                  3     # stop software || hardware trigger
TRIG_SW_START_2 =            4     # GlobalResetRelease software trigger mode (1500CU/BU,1300CU,NET3_11000BU/CU)
TRIG_HW_START_2 =            5     # GlobalResetRelease hardware trigger mode (1500CU/BU,1300CU,,NET3_11000BU/CU)


# Versions definitions
# (used with: ICubeSDK_GetVersion)

DLL_VERSION =                0     # (ICubeSDK.dll)
API_VERSION =                1     # (NET_USB_CMO.dll)

# Callback definitions
# (used with: ICubeSDK_SetCallback)

CALLBACK_RAW =               0     # 8bit/pixel data is received
                                   # (if the camera is a color model data == raw bayer)
CALLBACK_RGB =               1     # 24bit/pixel data is received


# DisplayMode definitions (windows only)
# (used with: ICubeSDK_SetDisplayMode)

DISPLAY_NORMAL =             0     # frame is previewed in original size (default)
DISPLAY_FIT_TO_WINDOW =      1     # frame is previewed in resized mode (window size) 
DISPLAY_RECT =               2     # frame is previewed in resized mode (rect size)

class DISP_PROPERTY(ctypes.Structure):
    _fields_ = [
       ('left',  ctypes.c_int),
       ('top',   ctypes.c_int),
       ('right', ctypes.c_int),
       ('bottom',ctypes.c_int)
    ];
    
# AVI stream definitions
# (used with: ICubeSDK_SaveAvi)

AVI_DIB =                    0     # currently, only this avi mode is supported


# Name length definitions
# (used with: ICubeSDK_GetName,ICubeSDK_GetSerialNum,ICubeSDK_GetVersion,ICubeSDK_GetFWVersion)

NETCAM_NAME_LENGTH =         14    # length of the name string
NETCAM_SERIAL_LENGTH =       10    # length of the serial number string
NETCAM_VERSION_LENGTH =       9    # length of the version string


# IsOpen definitions
# (used with: ICubeSDK_IsOpen)

IS_CLOSED =                   0
IS_OPEN =                     1

# IsStarted definitions
# (used with: ICubeSDK_IsStarted)

IS_STOPPED =                  0
IS_STARTED =                  1

# event definitions
# (used with: ICubeSDK_SetCallbackEx)

EVENT_NEW_FRAME =             0
EVENT_DEV_DISCONNECTED =      1     # a camera is disconnected (windows only)
EVENT_DEV_RECONNECTED =       2     # a camera is reconnected (windows only)
EVENT_USB_TRANSFER_FAILED =   3     # an usb transaction error occured during streaming

# pipe timeout mode definitions
# (used with: REG_PIPE_TIMEOUT_MODE)

MODE_TIMEOUT_NONE =           0
MODE_TIMEOUT_ALL =            1
MODE_TIMEOUT_PART =           2

#//////////////////////////////////////////////////////////////////////////////'
# wrapper function to copy callback data to numpy array

def get_data(buf,bufSize,heigth,width,bytes_per_pixel):

        mem = ctypes.create_string_buffer(bufSize)
        ctypes.memmove(mem,buf,bufSize)
        img = np.ndarray(buffer = mem,
        dtype = np.uint8,
        shape = (heigth,width,bytes_per_pixel))
        
        return img


#//////////////////////////////////////////////////////////////////////////////'
#//
#//         Load Library 
#//
#//////////////////////////////////////////////////////////////////////////////

is_windows = sys.platform.startswith('win')
if is_windows == True:
    is_64bits = sys.maxsize > 2**32
    if is_64bits == True:
        iCubeDll = ctypes.windll.LoadLibrary("C:\\Windows\\System32\\ICubeSDK64.dll") 
    else:
        iCubeDll = ctypes.windll.LoadLibrary("C:\\Windows\\System32\\ICubeSDK.dll")
else:
     iCubeDll = ctypes.cdll.LoadLibrary("/usr/lib/libNETUSBCAM.so")

#//////////////////////////////////////////////////////////////////////////////'
#//
#//          Camera control functions
#//
#//////////////////////////////////////////////////////////////////////////////

def ICube_Init():
       
    if is_windows == True:
        numDevices=iCubeDll.ICubeSDK_Init()
    else:
        numDevices=iCubeDll.NETUSBCAM_Init()
        
    return numDevices

def ICube_Open(cam):
       
    if is_windows == True:
        ret = iCubeDll.ICubeSDK_Open(cam)
    else:
        ret = iCubeDll.NETUSBCAM_Open(cam)
        
    return ret

def ICube_Close(cam):

    if is_windows == True:
        ret = iCubeDll.ICubeSDK_Close(cam)
    else:
        ret = iCubeDll.NETUSBCAM_Close(cam)
        
    return ret

def ICube_IsOpen(cam):
       
    if is_windows == True:
        ret = iCubeDll.ICubeSDK_IsOpen(cam)
    else:
        ret = iCubeDll.NETUSBCAM_IsOpen(cam)
        
    return ret

def ICube_SetCallback(cam,nMode,pCallback,pCBContext):
       
   if is_windows == True:
      CB_T = ctypes.WINFUNCTYPE(ctypes.c_long,ctypes.POINTER(ctypes.c_ubyte),ctypes.c_long,ctypes.c_void_p)
      cb_ptr = CB_T(pCallback)
      (ctypes.cast(cb_ptr, ctypes.POINTER(ctypes.c_int)))
      ret = iCubeDll.ICubeSDK_SetCallback(cam,nMode,cb_ptr,pCBContext)
   else:
       CB_T = ctypes.CFUNCTYPE(ctypes.c_int,ctypes.c_void_p,ctypes.c_uint,ctypes.c_void_p)
       ret = iCubeDll.NETUSBCAM_SetCallback(cam,nMode,CB_T(pCallback),pCBContext)
       
   return ret

def ICube_SetCallbackEx(cam,nMode,pCallback,pCBContext):
       
   if is_windows == True:
      CB_T = ctypes.WINFUNCTYPE(ctypes.c_long,ctypes.c_int,ctypes.POINTER(ctypes.c_ubyte),ctypes.c_long,ctypes.c_void_p)
      cb_ptr = CB_T(pCallback)
      ctypes.cast(cb_ptr, ctypes.POINTER(ctypes.c_int))
      ret = iCubeDll.ICubeSDK_SetCallbackEx(cam,nMode,cb_ptr,pCBContext)
   else:
      CB_T = ctypes.CFUNCTYPE(ctypes.c_int,ctypes.c_int,ctypes.c_void_p,ctypes.c_uint,ctypes.c_void_p)
      ret = iCubeDll.NETUSBCAM_SetCallbackEx(cam,nMode,CB_T(pCallback),pCBContext)
      
   return ret

def ICube_Start(cam,ImgHandle,Preview,Callback):
       
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_Start(cam,ImgHandle,Preview,Callback)
   else:
      ret = iCubeDll.NETUSBCAM_Start(cam)
        
   return ret

def ICube_IsStarted(cam):
       
    if is_windows == True:
       ret = iCubeDll.ICubeSDK_IsStarted(cam)
    else:
       ret = iCubeDll.NETUSBCAM_IsStarted(cam)
        
    return ret
    
def ICube_Stop(cam):
       
   if is_windows == True:
        ret = iCubeDll.ICubeSDK_Stop(cam)
   else:
        ret = iCubeDll.NETUSBCAM_Stop(cam)
        
   return ret

def ICube_GetSize(cam):
   
   _pnXRes = ctypes.c_int() 
   _pnYRes = ctypes.c_int()
    
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetSize(cam,ctypes.byref(_pnXRes),ctypes.byref(_pnYRes));
   else:
      ret = iCubeDll.NETUSBCAM_GetSize(cam,ctypes.byref(_pnXRes),ctypes.byref(_pnYRes));
      
   return _pnXRes.value, _pnYRes.value, ret

def ICube_GetName(cam):
   
   p = ctypes.create_string_buffer(15)
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetName(cam,ctypes.byref(p));
   else:
      ret = iCubeDll.NETUSBCAM_GetName(cam,ctypes.byref(p),15);
      
   return p.value, ret
   
def ICube_GetBrokenFrames(cam):
   
   _Value = ctypes.c_int()
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetBrokenFrames(cam,ctypes.byref(_Value));
   else:
      ret = iCubeDll.NETUSBCAM_GetBrokenFrames(cam,ctypes.byref(_Value));
   
   return _Value.value, ret
   
def ICube_GetGoodFrames(cam):
   
   _Value = ctypes.c_int()
    
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetGoodFrames(cam,ctypes.byref(_Value));
   else:
      ret = iCubeDll.NETUSBCAM_GetGoodFrames(cam,ctypes.byref(_Value));
      
   return _Value.value, ret

def ICube_SetDisplayMode(cam,nMode,_property):

   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SetDisplayMode(cam,nMode,_property)
   else:
      ret = IC_ERROR # not implemented
      
   return ret

def ICube_Destroy(cam):
   # linux only: used for cleanup: see ICubeEventSample
   if is_windows == True:
      ret = IC_ERROR # not implemented
   else:
      ret = iCubeDll.NETUSBCAM_Destroy(cam);
   
   return ret

#//////////////////////////////////////////////////////////////////////////////'
#//
#//          Version functions
#//
#//////////////////////////////////////////////////////////////////////////////

def ICube_GetVersion(nType):
   
   if is_windows == True:
      p = ctypes.create_string_buffer(NETCAM_VERSION_LENGTH)
      iCubeDll.ICubeSDK_GetVersion(nType,ctypes.byref(p)); 
   else:
      p = ctypes.create_string_buffer(6)
      iCubeDll.NETUSBCAM_GetApiVersion(ctypes.byref(p),6);
   
   return p.value

def ICube_GetFWVersion(cam):

   p = ctypes.create_string_buffer(NETCAM_VERSION_LENGTH)
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetFWVersion(cam,ctypes.byref(p));
   else:
      ret = iCubeDll.NETUSBCAM_GetFWVersion(cam,ctypes.byref(p),NETCAM_VERSION_LENGTH);
      
   return p.value, ret

def ICube_GetSerialNum(cam):

   p = ctypes.create_string_buffer(NETCAM_SERIAL_LENGTH)
    
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetSerialNum(cam,ctypes.byref(p));
   else:
      ret=iCubeDll.NETUSBCAM_GetSerialNum(cam,ctypes.byref(p),NETCAM_SERIAL_LENGTH);
       
   return p.value, ret

def ICube_GetFGPAVersion(cam):
       
   if is_windows == True:
      p = ctypes.create_string_buffer(NETCAM_VERSION_LENGTH)
      ret = iCubeDll.ICubeSDK_GetFGPAVersion(cam,ctypes.byref(p));
      return p.value, ret
   else:
      return 0, IC_ERROR # not implemented

#//////////////////////////////////////////////////////////////////////////////'
#//
#//          ROI functions
#//
#//////////////////////////////////////////////////////////////////////////////

def ICube_SetResolution(cam,_property):
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SetResolution(cam,ctypes.byref(_property));
   else:
      if _property.bEnabled == 1:
         ret = iCubeDll.NETUSBCAM_SetResolution(cam,_property.nXRes,_property.nYRes,_property.nXPos,_property.nYPos);
      else:
         ret=0 
   return ret

def ICube_GetResolution(cam):
   
   _property = ROI_PROPERTY() 
  
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetResolution(cam,ctypes.byref(_property));
   else:
      _pnXRes,_pnYRes = ctypes.c_int() ,ctypes.c_int()
      _pnXPos,_pnYPos = ctypes.c_int() ,ctypes.c_int()
         
      ret = iCubeDll.NETUSBCAM_GetResolution(cam,ctypes.byref(_pnXRes),ctypes.byref(_pnYRes),ctypes.byref(_pnXPos),ctypes.byref(_pnYPos));
       
      _property.nXRes = _pnXRes
      _property.nYRes = _pnYRes
      _property.nXPos = _pnXPos
      _property.nYPos = _pnYPos
      
   return _property, ret
   
def ICube_GetResolutionRange(cam):
   
   _property = ROI_RANGE_PROPERTY() 
    
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetResolutionRange(cam,ctypes.byref(_property));
   else:
      ret = iCubeDll.NETUSBCAM_GetResolutionRange(cam,ctypes.byref(_property));
      
   return _property, ret

def ICube_SetResolutionParam(cam,ImgHandle,Preview,Callback):
    
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SetResolutionParam(cam,ImgHandle,Preview,Callback);
   else:
      ret = IC_ERROR # not implemented
      
   return ret

def ICube_UnsetResolution(cam): 
   # linux only: used with 4133CU/BU,4203CU/BU mult roi mode (see MultiROITest sample)
   if is_windows == True:
      ret = IC_ERROR # not implemented
   else:
      ret = iCubeDll.NETUSBCAM_UnsetResolution(cam);
      
   return ret
   
#//////////////////////////////////////////////////////////////////////////////'
#//
#//          Mode functions
#//
#//////////////////////////////////////////////////////////////////////////////

def ICube_SetMode(cam,nMode):
       
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SetMode(cam,nMode)
   else:
      ret = iCubeDll.NETUSBCAM_SetMode(cam,nMode)
      
   return ret

def ICube_GetMode(cam):
   
   _pnMode = ctypes.c_int()
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetMode(cam,ctypes.byref(_pnMode))
   else:
      ret = iCubeDll.NETUSBCAM_GetMode(cam,ctypes.byref(_pnMode))
        
   return _pnMode.value, ret    
   
def ICube_GetModeList(cam):

   _pnLength = ctypes.c_int()
   _pnModes = (ctypes.c_int*10)()
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetModeList(cam,ctypes.byref(_pnLength),ctypes.byref(_pnModes))
   else:
      ret = iCubeDll.NETUSBCAM_GetModeList(cam,ctypes.byref(_pnLength),ctypes.byref(_pnModes))
       
   return _pnLength.value, _pnModes, ret           

#//////////////////////////////////////////////////////////////////////////////'
#//
#//          Bin Skip functions
#//
#//////////////////////////////////////////////////////////////////////////////

def ICube_SetBinSkip(cam,nParameter,nMode):
    
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SetBinSkip(cam,nParameter,nMode)
   else:
      ret = iCubeDll.NETUSBCAM_SetBinSkip(cam,nParameter,nMode)
      
   return ret

def ICube_GetBinSkip(cam,nMode):

   _pnParameter = ctypes.c_int()
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetBinSkip(cam,ctypes.byref(_pnParameter),nMode)
      return _pnParameter.value, nMode, ret    
   else:
      _pnMode = ctypes.c_int()
      ret = iCubeDll.NETUSBCAM_GetBinSkip(cam,ctypes.byref(_pnParameter),ctypes.byref(_pnMode))
      return _pnParameter.value, _pnMode.value, ret    
   
def ICube_GetBinSkipList(cam,nMode):

   _pnLength = ctypes.c_int()
   
   if is_windows == True:
      _pnList = (ctypes.c_int*3)()
      ret = iCubeDll.ICubeSDK_GetBinSkipList(cam,nMode,ctypes.byref(_pnLength),ctypes.byref(_pnList))
   else:
      _pnList = (ctypes.c_int*2)()          
      ret = iCubeDll.NETUSBCAM_GetBinSkipList(cam,nMode,ctypes.byref(_pnLength),ctypes.byref(_pnList))
        
   return _pnLength.value, _pnList, ret    

#//////////////////////////////////////////////////////////////////////////////'
#//
#//          Save functions
#//
#//////////////////////////////////////////////////////////////////////////////

def ICube_SaveToFile(cam,nFileName):

   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SaveToFile(cam,nFileName)
   else:
      ret = iCubeDll.NETUSBCAM_SaveToFile(cam,nFileName)
      
   return ret
   
def ICube_SaveAvi(cam,nFileName,nMode,nTimeInSecs):

   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SaveAvi(cam,nFileName,nMode,nTimeInSecs)
   else:
      ret = IC_ERROR # not implemented
      
   return ret   

#//////////////////////////////////////////////////////////////////////////////'
#//
#//          Trigger functions
#//
#//////////////////////////////////////////////////////////////////////////////

def ICube_SetTrigger(cam,nMode):
    
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SetTrigger(cam,nMode);
   else:
      ret = iCubeDll.NETUSBCAM_SetTrigger(cam,nMode);
       
   return ret
    
def ICube_GetTrigger(cam):

   _pnMode = ctypes.c_int()
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetTrigger(cam,ctypes.byref(_pnMode));
   else:
      ret = iCubeDll.NETUSBCAM_GetTrigger(cam,ctypes.byref(_pnMode));
      
   return _pnMode.value, ret      
    
#//////////////////////////////////////////////////////////////////////////////'
#//
#//          Parameter functions 
#//
#//////////////////////////////////////////////////////////////////////////////

def ICube_SetCamParameter(cam,Type,Value):
    
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SetCamParameter(cam,Type,Value);
   else:
      ret = iCubeDll.NETUSBCAM_SetCamParameter(cam,Type,Value);
       
   return ret
   
def ICube_GetCamParameter(cam,Type):

   _pnValue = ctypes.c_int()
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetCamParameter(cam,Type,ctypes.byref(_pnValue));
   else:
      ret = iCubeDll.NETUSBCAM_GetCamParameter(cam,Type,ctypes.byref(_pnValue));
      
   return _pnValue.value, ret      

def ICube_GetCamParameterRange(cam,Type):

   _param = PARAM_PROPERTY()  
    
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetCamParameterRange(cam,Type,ctypes.byref(_param));
   else:
      ret = iCubeDll.NETUSBCAM_GetCamParameterRange(cam,Type,ctypes.byref(_param));
      
   return _param, ret
    
#//////////////////////////////////////////////////////////////////////////////'
#//
#//          Exposure functions 
#//          This functions can be used alternativly to parameter functions,
#//          for manipulating exposure only. Parameter Value is in milli-seconds.
#//          Be aware that every change of clock
#//          and width will lead to different exposure values
#//
#//////////////////////////////////////////////////////////////////////////////

def ICube_SetExposure(cam,Value):

   _pnValue = ctypes.c_float()
   _pnValue.value = Value
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SetExposure(cam,_pnValue);
   else:
      ret = iCubeDll.NETUSBCAM_SetExposure(cam,_pnValue);
       
   return ret
    
def ICube_GetExposure(cam):

   _pnValue = ctypes.c_float()
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetExposure(cam,ctypes.byref(_pnValue));
   else:
      ret = iCubeDll.NETUSBCAM_GetExposure(cam,ctypes.byref(_pnValue));
      
   return _pnValue.value, ret      

def ICube_GetExposureRange(cam):

   _param_f = PARAM_PROPERTY_f()
    
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetExposureRange(cam,ctypes.byref(_param_f));
   else:
      ret = iCubeDll.NETUSBCAM_GetExposureRange(cam,ctypes.byref(_param_f));
      
   return _param_f, ret  
    
#//////////////////////////////////////////////////////////////////////////////'
#//
#//       for Parameter functions and Exposure functions (auto||manual,one-push)
#//
#//////////////////////////////////////////////////////////////////////////////

def ICube_GetParamAuto(cam,Type):

   _pnAuto = ctypes.c_int()
   
   if is_windows == True:
      ret = iCubeDll.ICubeSDK_GetParamAuto(cam,Type,ctypes.byref(_pnAuto));
   else:
      ret = iCubeDll.NETUSBCAM_GetParamAuto(cam,Type,ctypes.byref(_pnAuto));
      
   return _pnAuto.value, ret      

def ICube_SetParamAuto(cam,Type,bAuto):

   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SetParamAuto(cam,Type,bAuto);
   else:
      ret = iCubeDll.NETUSBCAM_SetParamAuto(cam,Type,bAuto);
      
   return ret      

def ICube_SetParamAutoDef(cam,Type):

   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SetParamAutoDef(cam,Type,bAuto);
   else:
      ret = iCubeDll.NETUSBCAM_SetParamAutoDef(cam,Type,bAuto);
      
   return ret 
    
def ICube_SetParamOnePush(cam,Type):

   if is_windows == True:
      ret = iCubeDll.ICubeSDK_SetParamOnePush(cam,Type,bAuto);
   else:
      ret = iCubeDll.NETUSBCAM_SetParamOnePush(cam,Type,bAuto);
      
   return ret 

#EOF
