import uvc
from pupil_detector_plugins.detector_base_plugin import PupilDetectorPlugin

# LPT dependency
from ctypes import windll

class TTLTrigger(PupilDetectorPlugin):
    order = 0.0001  # as close to the video backend as possible
    # LPT_Initialized = 0


    def __init__(self, g_pool):
        # super().__init__(g_pool)  # do NOT run include this line
        self.g_pool = g_pool
        self._recording = False

        # Init the parallel port object
        if self.g_pool.eye_id == 0:
            self.LPT_Adress = 0x378 # Moll Eyetracker
            # self.LPT_Adress = 0x3FD8 # EEG Eyetracker
            # ParP = windll.inpout32
            self.ParP = windll.inpoutx64
            # ParP.Inp32(self.LPT_Adress, 0)
            self.ParP.Out32(self.LPT_Adress, 0) #all low on port
            self.LPT_Initialized = True
            
        self._stop_Pye3DPlugin_pupil_detectors()


    def _stop_Pye3DPlugin_pupil_detectors(self):
        plugin_list = self.g_pool.plugins

        # Deactivate other PupilDetectorPlugin instances
        for plugin in plugin_list:
            if isinstance(plugin, PupilDetectorPlugin):
                print("-------------- This never executes --------------")
                if plugin.label == "Pye3D":
                    plugin.alive = False
                    print("-------------- 3D Plugin Stopped --------------")
        # Force Plugin_List to remove deactivated plugins
        plugin_list.clean()


    def init_ui(self):
        pass  # overwrites detector ui


    def deinit_ui(self):
        pass  # overwrites detector ui
        

    def recent_events(self, event):
        frame = event.get("frame", None)
        if frame is not None:
            # only for eye 0 camera
            if (self.g_pool.eye_id == 0 and self.LPT_Initialized):
                if self._recording:
                    # set Bit 0 to HIGH while we record
                    self.ParP.Out32(self.LPT_Adress, self.ParP.Inp32(self.LPT_Adress) | (1 << 0))
                    # Toggle Bit 1 each received Frame
                    self.ParP.Out32(self.LPT_Adress, self.ParP.Inp32(self.LPT_Adress) ^ 1 << 1)
                else:
                    # set Bit 0 and 1 to LOW when we stop recording
                    self.ParP.Out32(self.LPT_Adress, self.ParP.Inp32(self.LPT_Adress) & ~(1 << 0) & ~(1 << 1))
            now = uvc.get_time_monotonic()
            # adjust for possible time sync
            now -= self.g_pool.timebase.value
            delay = now - frame.timestamp
            # print(f"eyeid={self.g_pool.eye_id}: {delay} seconds delay")


    def on_notify(self, notification):
        if notification["subject"] == "recording.started":
            self._recording = True
        elif notification["subject"] == "recording.stopped":
            self._recording = False


    def cleanup(self):
        # TODO: do necessary cleanup
        pass