from __future__ import annotations
from typing import Protocol, Any, runtime_checkable, TYPE_CHECKING, List
from zempy.zosapi.enums.license_status import LicenseStatusType
from zempy.zosapi.enums.zosapi_mode import ZOSAPIMode
from zempy.zosapi.enums.update_status import UpdateStatus

if TYPE_CHECKING:
    from zempy.zosapi.system.protocols.i_optical_system import IOpticalSystem
    from zempy.zosapi.common.protocols.i_vector_data import IVectorData

@runtime_checkable
class IApplication(Protocol):
    def GetSystemAt(self, pos: int) -> IOpticalSystem: ...
    def CloseSystemAt(self, pos: int, saveIfNeeded: bool) -> bool: ...
    def LoadNewSystem(self, LensFile: str) -> IOpticalSystem: ...
    def CreateNewSystem(self, mode: Any) -> IOpticalSystem: ...
    def UpdateFileLists(self) -> None: ...
    def GetDate(self) -> str: ...
    def CloseApplication(self) -> None: ...
    def CheckForUpdates(self) -> None: ...
    def ClearMessageLog(self) -> None: ...
    def BeginMessageLogging(self) -> bool: ...
    def EndMessageLogging(self) -> bool: ...
    def RetrieveLogMessages(self) -> str: ...
    def LoadCCallback(self, cLib: str, callbackName: str, settings: Any) -> Any: ...
    def RegisterCOperandCallback(self, cLib: str, callbackName: str, settings: Any) -> Any: ...
    def LoadNETCallback(self, fromAssembly: str, typeName: str, settings: Any) -> Any: ...
    def RegisterNETOperandCallback(self, fromAssembly: str, typeName: str, settings: Any) -> Any: ...
    def CopySettingsData(self, from_: Any, to: Any) -> bool: ...
    def CreateSettings(self) -> Any: ...
    def CreateSettingsFromParent(self, parent: Any) -> Any: ...
    def OpenDataFile(self, fileName: str) -> Any: ...
    def CreateDataFile(self, fileName: str, type: Any, data1: int, data2: int) -> Any: ...
    def RunCommand(self, command: str) -> str: ...

    # ---------- Properties ----------
    @property
    def LicenseStatus(self) -> LicenseStatusType: ...
    @property
    def IsValidLicenseForAPI(self) -> bool: ...
    @property
    def InitializationErrors(self) -> str: ...
    @property
    def InitializationErrorCode(self) -> str: ...
    @property
    def Mode(self) -> ZOSAPIMode: ...
    @property
    def SerialCode(self) -> str: ...
    @property
    def OpticStudioVersion(self) -> int: ...
    @property
    def ExpirationYear(self) -> int: ...
    @property
    def ExpirationMonth(self) -> int: ...
    @property
    def ExpirationDay(self) -> int: ...
    @property
    def NumberOfOpticalSystems(self) -> int: ...
    @property
    def PrimarySystem(self) -> IOpticalSystem: ...
    @property
    def NumberOfCPUs(self) -> int: ...
    @property
    def ProgramDir(self) -> str: ...
    @property
    def LensDir(self) -> str: ...
    @property
    def ObjectsDir(self) -> str: ...
    @property
    def GlassDir(self) -> str: ...
    @property
    def ZPLDir(self) -> str: ...
    @property
    def CoatingDir(self) -> str: ...
    @property
    def POPDir(self) -> str: ...
    @property
    def ImagesDir(self) -> str: ...
    @property
    def SolidWorksFilesDir(self) -> str: ...
    @property
    def AutodeskInventorFilesDir(self) -> str: ...
    @property
    def CreoParametricFilesDir(self) -> str: ...
    @property
    def MATLABFilesDir(self) -> str: ...
    @property
    def ScatterDir(self) -> str: ...
    @property
    def UndoDir(self) -> str: ...
    @property
    def SamplesDir(self) -> str: ...
    @property
    def ZemaxDataDir(self) -> str: ...

    # Operand mode / analysis
    @property
    def OperandResults(self) -> IVectorData: ...
    @property
    def OperandArgument1(self) -> float: ...
    @property
    def OperandArgument2(self) -> float: ...
    @property
    def OperandArgument3(self) -> float: ...
    @property
    def OperandArgument4(self) -> float: ...
    @property
    def UserAnalysisData(self) -> Any: ...
    @property
    def TerminateRequested(self) -> bool: ...

    # Plugin / UI progress
    @property
    def ShowChangesInUI(self) -> bool: ...
    @ShowChangesInUI.setter
    def ShowChangesInUI(self, value: bool) -> None: ...
    @property
    def ProgressMessage(self) -> str: ...
    @ProgressMessage.setter
    def ProgressMessage(self, msg: str) -> None: ...
    @property
    def ProgressPercent(self) -> float: ...
    @ProgressPercent.setter
    def ProgressPercent(self, pct: float) -> None: ...

    # Updates status
    @property
    def CheckForUpdatesStatus(self) -> UpdateStatus: ...
    @property
    def CheckForUpdatesData(self) -> str: ...
    @property
    def CheckForUpdatesVersion(self) -> int: ...

    # Preferences / logging / versioning
    @property
    def Preferences(self) -> Any: ...
    @property
    def IsLoggingMessages(self) -> bool: ...
    @property
    def ZOSMajorVersion(self) -> int: ...
    @property
    def ZOSMinorVersion(self) -> int: ...
    @property
    def ZOSSPVersion(self) -> int: ...
    @property
    def IsSubscriptionLicense(self) -> bool: ...
    @property
    def IsSTARModuleEnabled(self) -> bool: ...
