# This is a CamiTK python action
#
# Video acquisition using OpenCV. It continuously replaces the image data of the selected
# component using the video feed.
# This action uses a timer to refresh the image.
# Note that you need to run the "Acquire Image" action first in order to get an image
# component with the proper dimensions.

import camitk
from PySide2.QtCore import QTimer
import cv2

def capture(self):
    ret, frame = self.capture_device.read()

    if not ret:
        camitk.warning("Error: Could not read frame.")
        return None
    else:
        # Convert the image from BGR to RGB
        rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        return rgb_frame

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

    self.setParameterValue("Video Frame", self.getParameterValue("Video Frame")+1)
    
    # uncomment the next line to update the GUI
    self.saveState()
    self.updateWidget()

def init(self:camitk.Action):
    self.timer = None
    self.camera_index = 0

def process(self:camitk.Action):  
    # create the timer
    if not self.timer:
        self.timer = QTimer()
        connected = self.timer.timeout.connect(lambda: capture_loop(self))
        self.image_component = self.getTargets()[-1]
    
    # if the acquisition is paused
    if not self.timer.isActive():
        self.setParameterValue("Video Frame", 0)
        
        # open the camera
        self.capture_device = cv2.VideoCapture(self.camera_index)
        if not self.capture_device.isOpened():
            camitk.warning(f"error: Could not open capturing device #{self.camera_index}.")
            return
        
        camitk.info("Starting Image Acquisition")
        self.timer.start(10)
    else:
        camitk.info("Stopping Image acquisition")
        self.timer.stop()
        # Release the camera
        self.capture_device.release()

    # Note: if camitk.refresh() or self.refreshApplication() is called before the
    # end of the method (e.g. just before the "self.timer.start(10)"), the python objects are
    # lost → self.timer is NoneType...
    #
    # → call refresh only when everything is in place
    # self.refreshApplication()
    # camitk.refresh()