#!/usr/bin/env python

#------------------------------------------------------------------------------
#                            icube example 
#
# Copyright (c) 2018 by Net GmbH.
# All rights reserved.
#
# 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.
#------------------------------------------------------------------------------

import sys
import icube

WITH_CV2 = 1

try:
    import cv2
except:
    WITH_CV2 = 0
    pass
try:
    import numpy as np
except:
    pass
import threading

#------------------------------------------------------------------------------
# DEFINES

WITH_SAVE_RAW = 0
WITH_LIVE_VIEW = 1

#------------------------------------------------------------------------------
# GLOBALS

BadFrames = 0   # statistics
GoodFrames = 0  # statistics

NewFrame = 0
cb_img = 0
width = 0
heigth = 0
colormodel = 0

def pause():
    ver = sys.version_info
    if ver.major > 2:
        input()         # continue with ENTER
    else:
        raw_input()     # continue with ENTER

class cvThread (threading.Thread): 
        def __init__(self, index):
            threading.Thread.__init__(self)
            self.running = True
        def run(self):
           global NewFrame
           global cb_img
           while self.running:
              if NewFrame == 1:
                 gray = cv2.cvtColor(cb_img,cv2.COLOR_BGR2GRAY)
                 edges = cv2.Canny(gray,100,200,apertureSize = 3)
                 
                 if colormodel == 0:
                    vis = cb_img.copy()
                 else:   
                    # convert to RGB
                    vis = cv2.cvtColor(cb_img,cv2.COLOR_BGR2RGB)
                    
                 vis = np.uint8(vis/2.)
                 vis[edges != 0] = (0, 255, 0)
                 NewFrame = 0
                  
                 cv2.imshow('pyicube live view + edge detection', vis)                 
                 cv2.waitKey(25) # msec
           
           cv2.destroyAllWindows()
           
        def stop(self):
            self.running = False
 
def MyCallbackFunc(pBuffer,lBufferSize,pContext):
    
     global GoodFrames
     global BadFrames
     global NewFrame
     global cb_img
     
     if lBufferSize == 0:
        BadFrames = BadFrames + 1
     else:
        GoodFrames = GoodFrames + 1
        
        if WITH_CV2 == 1:
           if NewFrame == 0:
              cb_img = icube.get_data(pBuffer,lBufferSize,heigth,width,3)   
              NewFrame = 1
         
        if WITH_SAVE_RAW == 1:
            if GoodFrames == 10:   # save the 10th frame
                print("---> SAVE TO FILE")
                f = open("icube.raw","wb")
                f.write(cb_img)      
                f.close()   
                        
     print("Img Ev GoodFr:",GoodFrames,"BadFr:",BadFrames,"Size:",lBufferSize)
     return 42

def main():

        global width
        global heigth
        global colormodel
        
        print("iCube python (1.0.0.1)")
        
        numDevices=icube.ICube_Init()
        if numDevices == 0:
           print("No Devices!")
        else:    
           print (numDevices,"Devices found")

           stat=icube.ICube_Open(0)
           if stat != icube.IC_SUCCESS:
              print("Error ICube_Open")
              
           colormodel, stat=icube.ICube_GetCamParameter(0,icube.REG_COLOR)
           if stat != icube.IC_SUCCESS:
              print("Error ICube_SetCamParameter")
                   
           stat=icube.ICube_SetMode(0,icube.MODE_640x480)
           if stat != icube.IC_SUCCESS:
              print("Error ICube_SetMode")

           stat=icube.ICube_SetCamParameter(0,icube.REG_CALLBACK_BR_FRAMES,1)
           if stat != icube.IC_SUCCESS:
              print("Error ICube_SetCamParameter")
    
           stat=icube.ICube_SetCallback(0,icube.CALLBACK_RGB,MyCallbackFunc,None)
           if stat != icube.IC_SUCCESS:
              print("Error ICube_SetCallback")
                
           width, heigth, stat=icube.ICube_GetSize(0)
           if stat != icube.IC_SUCCESS:
              print("-!-> Error ICube_GetSize")               
                     
           print("---> START STREAMING (Quit with 'ENTER')")         
           
           stat=icube.ICube_Start(0,None,False,True)
           if stat != icube.IC_SUCCESS:
              print("Error ICube_Start")

           if (WITH_LIVE_VIEW == 1)and(WITH_CV2 == 1):
              thread0 = cvThread(0)
              thread0.start()
          
           pause()
             
           print("---> CLEANUP") 
                         
           if (WITH_LIVE_VIEW == 1)and(WITH_CV2 == 1):
              thread0.stop()
              thread0.join()
          
           stat=icube.ICube_Stop(0)
           if stat != icube.IC_SUCCESS:
              print("Error ICube_Stop")

           stat=icube.ICube_Close(0)
           if stat != icube.IC_SUCCESS:
              print("Error ICube_Close")
             
if __name__ == "__main__":
    main()
