# This is a CamiTK python action
#
# Video acquisition using an external python script video_capture_device to detect 
# available cameras (see 'Acquire Image') and grab video image using OpenCV
# 
# This demonstrates how you can use a clean design in your action 
# by using an architecture where your independent code stays in your external script
# and is glued into CamiTK using a Python Extension to offer UI and interoperability.

import camitk
from PySide2.QtCore import QTimer
import cv2
from video_capture_device import VideoCaptureDevice

def capture_loop(self):
    rgb_frame = self.capture_device.capture()
    if rgb_frame is not None and self.image_component:
        self.image_component.replaceImageData(rgb_frame)

def init(self:camitk.Action):
    self.timer:QTimer = None
    self.image_component:camitk.ImageComponent = None
    self.capture_device:VideoCaptureDevice = None

    available_cameras = VideoCaptureDevice.list_available_cameras()
    
    if available_cameras:
        prop = camitk.Property("Video Capture Device", available_cameras[0], "Camera to use for image acquisition (0 is usually the PC webcam)", "")
        prop.setAttribute("enumNames", available_cameras);
        prop.setEnumTypeName(r'VideoCaptureDeviceId');
        self.addParameter(prop)
        self.setApplyButtonText("Start")
    else:
        print("No cameras found.")

def process(self:camitk.Action):  
    if not self.timer:
        self.timer = QTimer()
        connected = self.timer.timeout.connect(lambda: capture_loop(self))
        
    if not self.timer.isActive():
        # get the user choice
        selected_camera = self.getParameterValue("Video Capture Device")
        enumValues = self.getProperty("Video Capture Device").getAttribute("enumNames")   

        # instantiate the class defined in the external script
        self.capture_device = VideoCaptureDevice(int(enumValues[selected_camera]))
        self.capture_device.start()

        # first capture: create a new component
        rgb_frame = self.capture_device.capture()
        if rgb_frame is not None and not self.image_component:
            self.image_component = camitk.newImageComponentFromNumpy(rgb_frame, "Webcam Video")
            self.refreshApplication()
        
        # start acquisition timer
        self.setApplyButtonText("Stop")
        self.timer.start(10)
    else:      
        self.setApplyButtonText("Restart")
        self.timer.stop()
        # Release the camera
        self.capture_device.stop()
