from IFikoAcilar.IFikoAcilar import IFikoAcilar
import IProgram
from IFikoSistem.IFikoToDic import fiko2Dict, listOzellikler
from IMfgTakim.IMfgTakim import IMfgTakim
from .IMfgOperasyonlar.IMfgOperasyon import IMfgOperasyon

__author__ = 'PC'

from IFikomObject import IFikomObject
from win32com.client import CDispatch

from IYardimciSiniflar import XYZ
import IAcilar.IAciTespit as IAciTespit
import math
from IAktiviteler.__gecici__ import *


class IPartOperasyonu:
    pass



class IParametreler:
    pass


class IProgram:
    class IProgram:
        pass


class MachiningTime(object):
    def __init__(self, Akt):
        self.__Akt = Akt

    @property
    def toplamIslemeSuresi(self):  # sn
        return self.__Akt.CalculatedCycleTime

    @property
    def toplamGecisSuresi(self):  # sn
        return self.__Akt.CycleTime

    @property
    def islemeSuresi(self):  # sn
        return self.__Akt.MachiningTime * 60

    @property
    def toplamSure(self):  # sn
        return self.__Akt.TotalTime * 60


class IAktivite(IFikomObject):
    def __init__(self, obj: CDispatch, sahip: IFikomObject = None):
        super(IAktivite, self).__init__(obj, sahip)
        self.sahip = sahip
        self.tipi = "IAktivite"
        # --->Sabit Degiskenler
        self.__turu = obj.Type
        self.__gecersizTurler = ["ToolChange",
                                 "Start", "Stop", "Stop", "PPInstruction"]
        self.__gecerliTur = self.turu not in self.__gecersizTurler
        self.__ilerlemeIsleme = None

    @property
    def processID(self) -> str:
        return self.catNesne.ProcessID

    @property
    def ismi(self) -> str:
        return self.catNesne.Name

    @ismi.setter
    def ismi(self, value: str):
        self.catNesne.Name = value

    @property
    def turu(self) -> str:
        return self.__turu

    @property
    def gecerliTur(self) -> bool:
        if not self.__gecerliTur:
            self.__gecerliTur = self.turu not in self.__gecersizTurler
        return self.__gecerliTur

    @property
    def po(self) -> IPartOperasyonu:
        from IPartOperasyonlari import IPartOperasyonu
        try:
            poIndex = self.sahip.sahip.indexPo
            return self.sahip.sahip.processDokuman.partOperasyonlari[poIndex]
        except:
            return IPartOperasyonu.IPartOperasyonu(None) if not True else self.sahipBulTipiyle("IPartOperasyonu")
            # -->
            # poIndex = self.sahip.sahip.indexPo
            # return self.sahip.sahip.processDokuman.partOperasyonlari[poIndex]

    @property
    def program(self) -> IProgram.IProgram:
        return IProgram.IProgram(obj=self.sahip.sahip.catNesne, sahip=self.sahip.sahip.sahip)

    @property
    def aktif(self) -> bool:
        return bool(self.catNesne.Active)

    @aktif.setter
    def aktif(self, value: bool):
        self.catNesne.Active = value

    @property
    def aciklama(self) -> str:
        return self.catNesne.Description

    @aciklama.setter
    def aciklama(self, value: str):
        self.catNesne.Description = value

    def kilitle(self):
        return self.catNesne.LockActivty()

    def kilidiAc(self):
        self.catNesne.UnLockActivty()

    @property
    def takim(self) -> IMfgTakim:
        return IMfgTakim(obj=self.catNesne.Tool, sahip=self)

    @takim.setter
    def takim(self, value):
        self.catNesne.Tool = value

    @property
    def takimYonu(self) -> XYZ:
        EvalCode = """
			Dim dirc(2) As Double
			MFG.GetToolAxis dirc(0), dirc(1), dirc(2)
			return = dirc
		"""
        # try:
        #     rslt = self.anaProgram.eval(EvalCode, "MFG As Object", [self.catNesne])
        # except:
        #     rslt=[0,0,1]
        try:
            rslt = self.anaProgram.eval(
                EvalCode, "MFG As Object", [self.catNesne])
        except:
            return XYZ(-1, -1, -1)
        # --->
        # rslt = self.anaProgram.scriptCalistir("MFGIslemeYonu", [self.catNesne])
        return XYZ(rslt[0], rslt[1], rslt[2])

    @takimYonu.setter
    def takimYonu(self, value):
        evalCode = """
			Dim dirc(2) as Double
			dirc(0) = X
			dirc(1) = Y
			dirc(2) = Z
			Eksen.SetToolAxis X, Y, Z
			return = dirc
		"""
        if isinstance(value, XYZ):
            _X = value.X
            _Y = value.Y
            _Z = value.Z

        if isinstance(value, list):
            _X = value[0]
            _Y = value[1]
            _Z = value[2]
        
        self.anaProgram.eval(evalCode, "Eksen,X,Y,Z", [
                             self.catNesne, _X, _Y, _Z])
        self.catNesne.SetToolAxis(_X, _Y, _Z)

    @property
    def acilar(self):
        return IAciTespit.IAciTespit(obj=self.catNesne, sahip=self)

    @property
    def fikoAcilar(self):
        return IFikoAcilar(obj=self.catNesne, sahip=self)

    @property
    def dikMi(self) -> bool:
        if self.turu == "ToolChange":
            return True
        # --->
        # tkmyon = self.takimYonu
        # eksnYon = self.sahip.sahip.po.eksen.Z
        # print(tkmyon, eksnYon)
        # if tkmyon.X == eksnYon[0] and tkmyon.Y == eksnYon[1] and tkmyon.Z == eksnYon[2]:
        #     return True
        # else:
        #     return False
            # --->
        saltAci = self.fikoAcilar.saltAcilar.altAci
        if (saltAci == 0.0 or math.isnan(saltAci)):
            return True
        else:
            return False

    @property
    def hesaplatilmis(self) -> bool:
        if not self.catNesne.CalculatedCycleTime == 0:
            return True
        else:
            return False

    @property
    def islemeSuresi(self):
        # --->
        return MachiningTime(self.catNesne)

    @property
    def ikiBoyutluMu(self):
        return False if self.ucBoyutluMu or self.besEksenMi else True

    @property
    def ucBoyutluMu(self):
        return self.turu.upper().startswith("M3X")

    @property
    def besEksenMi(self):
        return self.turu.upper().startswith("MFG5AXIS")

    @property
    def devir(self) -> float:
        return float(self.parametreler["Machining spindle"].degeri)

    @devir.setter
    def devir(self, val: float) -> float:
        self.parametreler["Machining spindle"].degeri = val

    __ilerlemeIsleme = None

    @property
    def ilerlemeIsleme(self) -> float:
        try:
            if not self.__ilerlemeIsleme:
                self.__ilerlemeIsleme = float(
                    self.parametreler["Machining feedrate"].degeri)
            return self.__ilerlemeIsleme
        except:
            return 0.0

    @ilerlemeIsleme.setter
    def ilerlemeIsleme(self, val: float) -> float:
        self.parametreler["Machining feedrate"].degeri = val

    __ilerlemeYaklasma = None

    @property
    def ilerlemeYaklasma(self) -> float:
        try:
            if not self.__ilerlemeYaklasma:
                self.__ilerlemeYaklasma = float(
                    self.parametreler["Approach feedrate"].degeri)
            return self.__ilerlemeYaklasma
        except:
            return 0.0

    @ilerlemeYaklasma.setter
    def ilerlemeYaklasma(self, val: float) -> float:
        self.parametreler["Approach feedrate"].degeri = val

    __ilerlemeUzaklasma = None

    @property
    def ilerlemeUzaklasma(self) -> float:
        try:
            if not self.__ilerlemeUzaklasma:
                self.__ilerlemeUzaklasma = float(
                    self.parametreler["Retract feedrate"].degeri)
            return self.__ilerlemeUzaklasma
        except:
            return 0.0

    @ilerlemeUzaklasma.setter
    def ilerlemeUzaklasma(self, val: float) -> float:
        self.parametreler["Retract feedrate"].degeri = val

    __ilerlemeFinis = None

    @property
    def ilerlemeFinis(self) -> float:
        if not self.turu in ["Pocketing", "ProfileContouring", "Facing"]:
            self.__ilerlemeFinis = 0.0
            return 0.0
        if not self.__ilerlemeFinis:
            self.__ilerlemeFinis = float(
                self.parametreler["Finishing feedrate"].degeri)
        return self.__ilerlemeFinis

    @ilerlemeFinis.setter
    def ilerlemeFinis(self, val: float) -> float:
        self.parametreler["Finishing feedrate"].degeri = val

    @property
    def ilerlemeGecisAktif(self) -> bool:
        return bool(self.parametreler["MFG_FEED_SELECT_TRANSITION"].degeri)

    @ilerlemeGecisAktif.setter
    def ilerlemeGecisAktif(self, val: bool) -> bool:
        self.parametreler["MFG_FEED_SELECT_TRANSITION"].degeri = val

    @property
    def ilerlemeGecisModu(self) -> IlerlemeGecisModu:
        rslt = self.parametreler["MFG_FEED_TYPE_TRANSITION"].degeriStr
        return IlerlemeGecisModu(rslt)

    @ilerlemeGecisModu.setter
    def ilerlemeGecisModu(self, val) -> IlerlemeGecisModu:
        if isinstance(val, str):
            self.parametreler["MFG_FEED_TYPE_TRANSITION"].degeri = IlerlemeGecisModu(
                val).value
        if isinstance(val, IlerlemeGecisModu):
            self.parametreler["MFG_FEED_TYPE_TRANSITION"].degeriStr = str(
                val.value)

    @property
    def ilerlemeGecis(self) -> float:
        if self.parametreler.parametreVarmi("MFG_LOCAL_FEED_TRANSITION_VALUE"):
            return float(self.parametreler["MFG_LOCAL_FEED_TRANSITION_VALUE"].degeri)
        else:
            return -0.0

    @property
    def takimBoyu(self):
        EvalCode = """
            Dim takim(1) as Double
            takim(0)=-1.0
            takim(1)=-1.0
            On Error Resume Next
            Aktivite.GetToolGage takim(0),takim(1)

            return = takim
        """
        rslt = self.anaProgram.eval(
            EvalCode, "Aktivite as ManufacturingOperation", [self.catNesne])

        return rslt

    @property
    def hatve(self) -> IParametre:
        # return globals()[self.turu + "_hatve"](self)
        rslt = None
        if self.turu not in self.__gecersizTurler:
            mod = __import__('IAktiviteler.IMfgOperasyonlar.' +
                             self.turu, fromlist=[''])
            rslt = mod.hatve(self)
        if not rslt:
            rslt = None
        return rslt

    @property
    def cevreOffset(self) -> IParametre:
        # return globals()[self.turu + "_cevreOffset"](self)
        if not self.ikiBoyutluMu:
            return None
        # --_>
        rslt = None
        if self.turu not in self.__gecersizTurler:
            mod = __import__('IAktiviteler.IMfgOperasyonlar.' +
                             self.turu, fromlist=[''])
            rslt = mod.cevreOffset(self)
        if not rslt:
            rslt = None
        return rslt

    @property
    def yuzeyOffset(self) -> IParametre:
        # return globals()[self.turu + "_cevreOffset"](self)
        if self.ikiBoyutluMu:
            return None
        # --_>
        rslt = None
        if self.turu not in self.__gecersizTurler:
            mod = __import__('IAktiviteler.IMfgOperasyonlar.' +
                             self.turu, fromlist=[''])
            rslt = mod.yuzeyOffset(self)
        if not rslt:
            rslt = None
        return rslt

    @property
    def yanalAdim(self) -> IParametre:
        rslt = None
        if self.turu not in self.__gecersizTurler:
            try:
                mod = __import__(
                    'IAktiviteler.IMfgOperasyonlar.' + self.turu, fromlist=[''])
                rslt = mod.yanalAdim(self)
            except:
                rslt = None
        if not rslt:
            rslt = None
        return rslt

    @property
    def fikoGlParametreler(self) -> IParametre:
        rslt = None
        try:
            mod = __import__('IAktiviteler.IMfgOperasyonlar.' +
                             self.turu, fromlist=[''])
            rslt = mod.fikoGlParametreler(self)
        except Exception as hata:
            print(hata)
            rslt = None
        if not rslt:
            rslt = None
        return rslt

    @property
    def parametreler(self):
        from IParametreler import IParametreler
        return IParametreler(self.catNesne.Parameters, self)

    @property
    def asOperasyon(self) -> IMfgOperasyon:
        return IMfgOperasyon(obj=self.catNesne, sahip=self)

    @property
    def toDict(self):
        return fiko2Dict(self)

    @property
    def listeOzellikler(self) -> list:
        return listOzellikler(self).metodlar

    @property
    def tahminCesit(self) -> object:
        pass

    def __str__(self) -> str:
        return repr(self.ismi)

    def __repr__(self):
        return self.__str__()
