#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：AsynchronousScanningEventInterface.py
@Description：
@Author：XSH
@Time：2025/11/15 11:34
@Department：研发部
@Copyright：©2025 乐辰生物
"""
from PyQt5                                                  import Qt
from abc                                                    import abstractmethod
from AppInterfaces.utils                                    import *
from AppUtils import AppUtils
from AppInterfaces.AppEventInterfaces.AppEventInterface     import AppEventInterface

class AsynchronousScanningEventInterface(AppEventInterface):
    _IOLocker   : Qt.QReadWriteLock = Qt.QReadWriteLock()
    _args       : tuple
    _kwargs     : dict
    _callback   : object
    _result     : object
    _running    : bool

    def Start(self, target=None, args=None, kwargs=None, result=None):
        if self.isRunning():
            return
        self._running = False
        self.initValue(target, args, kwargs, result)
        self.start(Qt.QThread.HighPriority)
        return self.waitForRunning()


    def run(self) -> None:
        if self.has_callback:
            self._running = True
            try:
                if self.has_args:
                    if self.has_kwargs:
                        self._result = self._callback(*self.args, **self._kwargs)
                    else:
                        self._result = self._callback(*self.args)
                else:
                    if self.has_kwargs:
                        self._result = self._callback(**self._kwargs)
                    else:
                        self._result = self._callback()
            except Exception as e:
                AppUtils.print_Exception(e)
            self._running = False
        return

    def waitForFinishing(self) -> bool:
        while self.running:
            AppTimeLoop.processGlobalEvents(1000)
        return self.isRunning()


    def waitForRunning(self) -> bool:
        while not self.running:
            AppTimeLoop.processGlobalEvents(1000)
        return self.isRunning()

    @property
    @abstractmethod
    def isAvailable(self) -> bool:
        pass

    @abstractmethod
    def SendEvent(self, value, **args):
        pass

    @abstractmethod
    def StartWork(self):
        pass

    @abstractmethod
    def StopWork(self):
        pass

    @abstractmethod
    def ResetWork(self):
        pass

    @abstractmethod
    def appendItem(self, item, *args, **kwargs):
        pass

    @abstractmethod
    def WaitDone(self, item, *args, **kwargs):
        pass

    @abstractmethod
    def ReSet(self, **args):
        pass

    @abstractmethod
    def initPools(self):
        pass

    @abstractmethod
    def delePools(self):
        pass


    @abstractmethod
    def initValue(self):
        pass

    @abstractmethod
    def initConnect(self):
        pass


    @property
    def has_args(self) -> bool:
        return hasattr(self, '_args') and isinstance(self._args, (tuple, list))

    @property
    def has_kwargs(self) -> bool:
        return hasattr(self, '_kwargs') and isinstance(self._kwargs, dict)

    @property
    def has_callback(self) -> bool:
        return hasattr(self, '_callback') and self._callback is not None

    @property
    def has_result(self) -> bool:
        return hasattr(self, '_result') and self._result is not None

    @property
    def has_running(self) -> bool:
        return hasattr(self, '_running') and isinstance(self._running, (bool, int))

    @property
    def result(self):
        return self._result if self.has_result else None

    @result.setter
    def result(self, value):
        self._result = value

    @property
    def running(self) -> bool:
        return self._running if self.has_running else False

    @running.setter
    def running(self, value: (bool, int)):
        self._running = True if isinstance(value, (bool, int)) and value else False

    @property
    def callback(self):
        return self._callback if self.has_callback else None

    @callback.setter
    def callback(self, value):
        self._callback = value

    @property
    def args(self):
        return self._args if self.has_args else None

    @args.setter
    def args(self, value):
        self._args = value

    @property
    def kwargs(self):
        return self._kwargs if self.has_kwargs else None

    @kwargs.setter
    def kwargs(self, value):
        self._kwargs = value