from enum import Enum
import os
import inspect
import uuid

import typing
from win32com.client import CDispatch, Dispatch

from IFikomObject import IFikomObject
from IDokuman import IDokuman
from IPencere import IPencere
from IDokumanlar import IDokumanlar
from IPencereler import IPencereler
from ISistemKonfigurasyonu import ISistemKonfigurasyonu
from IFikoSistem.IFikoSistem import IFikoSistem

from pythoncom import (
  CreateBindCtx         as create_bind_context_com_interface,
  IID_IDispatch         as dispatch_com_interface_iid,
  GetRunningObjectTable as get_running_object_table_com_interface,
)

class IsAlanlari():
    PART_DESIGN = {"ismi":"Part Design", "id":"PrtCfg","Açıklama":"Katı Modelleme"}
    GENERATIVE_SHAPE_DESIGN = {"ismi":"Generative Shape Design", "id":"CATShapeDesignWorkbench","Açıklama":"Yüzey Modelleme"}
    SURFACE_MACHINING = {"ismi":"Surface Machining", "id":"M3xProgramWorkbench","Açıklama":"Yüzey İşleme"}
    PRISTMATIC_MACHINING = {"ismi":"Prismatic Machining", "id":"ManufacturingProgramWorkbench","Açıklama":"Yüzey İşleme"}


class IFikatia(IFikomObject):
    """
        Catiaya Uyarlanmis Ana Sinif (IApplication)
        Catianin Tum Ozelliklerinin Bir Yere Toplamayi, Ek Ozellikler Saglamayi,
        Ekstra Hiz Ve Olabildigince Otomasyon Yapabilmeyi Dusundugum Ve Cogunu
        Tamamladigim Bir Sinif.
    """

    def __init__(self, obj=None, sahip=None):
        super(IFikatia, self).__init__(obj, sahip)
        # ---> Standart Degiskenler
        self.sahip = self
        self.tipi = "IFikatia"
        self.parent = obj
        self.anaProgram = self
        # --->
        self.scriptYolu = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
        #--->
        self.shell = Dispatch("WScript.Shell")
        self.uuid=str(uuid.uuid4())
        self.fikatialar:typing.List[IFikatia]=[]
        # self.acikCatialar()

    def scriptCalistir(self, ScriptIsmi:str, Parametreler:list=[]) -> CDispatch:
        sArgs = Parametreler
        libpath = os.path.join(self.scriptYolu,"Prg","CatScript","FikoScriptler.vba.catvba")
        sModule = "CatScriptler"
        sMacro = ScriptIsmi
        return self.catNesne.SystemService.ExecuteScript(libpath, 2, sModule, sMacro, sArgs)

    def eval(self, Script:str=None, Paramstr:str="", Params:list=[]) -> CDispatch:
        code = "Function return(" + Paramstr + ") \n"
        code = code + Script + "\n"
        code = code + "End Function"
        return self.catNesne.SystemService.Evaluate(code, 0, "return", Params)
    
    def acikCatialar(self):
        self.fikatialar.clear()
        running_object_table_com_interface = get_running_object_table_com_interface()
        bind_context_com_interface = create_bind_context_com_interface()
        excel_application_class_clsid = '{87FD6F40-E252-11D5-8040-0010B5FA1031}'
        excel_application_clsid = '{87FD6F40-E252-11D5-8040-0010B5FA1031}'
        excel_instance_com_objects = []
        for moniker_com_interface in running_object_table_com_interface:
            try:
                display_name = moniker_com_interface.GetDisplayName(bind_context_com_interface, None)
                # if excel_application_class_clsid not in display_name:
                #     continue
                unknown_com_interface = running_object_table_com_interface.GetObject(moniker_com_interface)
                dispatch_com_interface = unknown_com_interface.QueryInterface(dispatch_com_interface_iid)
                dispatch_clsid = str(object=dispatch_com_interface.GetTypeInfo().GetTypeAttr().iid)
                # print("Catia Class CLSID",display_name,"App Clsid",dispatch_clsid)
                # if dispatch_clsid != excel_application_clsid:
                #   continue
                print(dispatch_com_interface, dispatch_clsid, unknown_com_interface)   
                excel_instance_com_object = Dispatch(dispatch_com_interface)
                
                # excel_instance_com_object.Caption="asd"

                self.fikatialar.append(IFikatia(excel_instance_com_object,excel_instance_com_object))
            except:
                
                pass
        return self.fikatialar

    @property
    def aktifDokuman(self) -> IDokuman:
        return IDokuman(obj=self.catNesne.ActiveDocument, sahip=self)

    @property
    def aktifPencere(self) -> IPencere:
        return IPencere(obj=self.catNesne.ActiveWindow, sahip=self.aktifDokuman)

    @property
    def baslik(self) -> str:
        return self.catNesne.Caption

    @baslik.setter
    def baslik(self, value:str):
        self.catNesne.Caption = value

    @property
    def programYolu(self) -> str:
        return self.catNesne.FullName

    @property
    def programKlasoru(self) -> str:
        return self.catNesne.Path

    @property
    def hsoSenkronize(self) -> bool:
        return bool(self.catNesne.HSOSynchronized)

    @hsoSenkronize.setter
    def hsoSenkronize(self, value:bool):
        self.catNesne.HSOSynchronized = value

    @property
    def ekraniTazele(self) -> bool:
        return bool(self.catNesne.RefreshDisplay)

    @ekraniTazele.setter
    def ekraniTazele(self, value:bool):
        self.catNesne.RefreshDisplay = bool(value)

    @property
    def durumCubugu(self) -> str:
        return self.catNesne.StatusBar

    @durumCubugu.setter
    def durumCubugu(self, value:str):
        self.catNesne.StatusBar = value

    @property
    def gorunur(self) -> bool:
        return bool(self.catNesne.visible)

    @gorunur.setter
    def gorunur(self, value:bool):
        self.catNesne.visible = bool(value)

    @property
    def dosyaUyarilariniGoster(self) -> bool:
        return bool(self.catNesne.DisplayFileAlerts)

    @dosyaUyarilariniGoster.setter
    def dosyaUyarilariniGoster(self, value:bool):
        self.catNesne.DisplayFileAlerts = bool(value)

    @property
    def interaktif(self) -> bool:
        return bool(self.catNesne.Interactive)

    @interaktif.setter
    def interaktif(self, value:bool):
        self.catNesne.Interactive = bool(value)

    @property
    def sol(self) -> int:
        return int(self.catNesne.left)

    @sol.setter
    def sol(self, value:int):
        self.catNesne.left = value

    @property
    def ust(self) -> int:
        return int(self.catNesne.Top)

    @ust.setter
    def ust(self, value:int):
        self.catNesne.Top = value

    @property
    def genislik(self) -> int:
        return int(self.catNesne.Width)

    @genislik.setter
    def genislik(self, value:int):
        self.catNesne.Width = value

    @property
    def yukseklik(self) -> int:
        return int(self.catNesne.Height)

    @yukseklik.setter
    def yukseklik(self, value:int):
        self.catNesne.Height = value

    @property
    def dokumanlar(self) -> IDokumanlar:
        return IDokumanlar(obj=self.catNesne.Documents, sahip=self)

    @dokumanlar.setter
    def dokumanlar(self, value):
        pass

    @dokumanlar.deleter
    def dokumanlar(self):
        pass

    @property
    def pencereler(self) -> IPencereler:
        return IPencereler(obj=self.catNesne.Windows, sahip=self)

    @pencereler.setter
    def pencereler(self, value):
        pass

    @pencereler.deleter
    def pencereler(self):
        pass

    @property
    def isAlaniId(self) -> str:
        return str(self.catNesne.GetWorkbenchId())

    @isAlaniId.setter
    def isAlaniId(self, value:str):
        self.catNesne.StartWorkbench(value)

    def komut(self, komut:str):
        self.catNesne.StartCommand(komut)

    @property
    def sistemKonfigurasyonu(self) -> ISistemKonfigurasyonu:
        return ISistemKonfigurasyonu(obj=self.catNesne.SystemConfiguration, sahip=self)

    @property
    def fikoSistem(self) -> IFikoSistem:
        return IFikoSistem(self)

    def aktifEt(self):
        _baslik = self.baslik
        _tempBaslik = self.uuid
        self.baslik = _tempBaslik
        self.shell.AppActivate(_tempBaslik)
        self.baslik=_baslik

    def tusYolla(self, tus:str, val=1 ):
        self.shell.SendKeys(tus,val)

