__author__ = 'CAM'

from win32com.client import CDispatch
import numpy

from IFikomObject import IFikomObject
from IAcilar.IKacmaDegerleri import IKacmaDegerleri
import vector3d
import math


class ITav20Er32(IFikomObject):
    def __init__(self, obj:CDispatch, sahip:IFikomObject=None):
        super(ITav20Er32, self).__init__(obj, sahip)
        self.sahip = sahip
        self.tipi = "ITav20Er32"
        self.ismi = "ITav20Er32"
        # --->Sabit Degiskenler
        self._Aktivite = sahip
        # self.Eksen = sahip.sahipBulTipiyle("IAktivite").po.eksen
        self.Eksen = self._Aktivite.sahip.po.eksen

    @property
    def xAcisi(self):
        Eksen = self.Eksen
        dPox = vector3d.Vector3d(Eksen.X[0], Eksen.X[1], Eksen.X[2])
        dPoz = vector3d.Vector3d(Eksen.Z[0], Eksen.Z[1], Eksen.Z[2])
        # --->
        TkmYon = self.sahipBulTipiyle("IAktivite").takimYonu
        dTool = vector3d.Vector3d(TkmYon.X, TkmYon.Y, TkmYon.Z)

        crossTool = vector3d.CrossProductVec(dPoz, dTool)
        rslt = vector3d.vec_dihedral(crossTool, dPoz, dPox)
        if math.isnan(rslt):
            rslt = 0.0

        return numpy.rad2deg(rslt)

    @property
    def altAci(self) -> float:
        MfgYon = self.sahipBulTipiyle("IAktivite").takimYonu
        EksenYon = self.Eksen
        dnn = numpy.arccos(float(EksenYon.Z[0]) * float(MfgYon.X) + float(EksenYon.Z[1]) * float(MfgYon.Y) + float(
            EksenYon.Z[2]) * float(MfgYon.Z) / math.sqrt(((float(EksenYon.Z[0]) * float(EksenYon.Z[0])) + (
            float(EksenYon.Z[1]) * float(EksenYon.Z[1])) + (float(EksenYon.Z[2]) * float(EksenYon.Z[2]) )) * (
                                                             (float(MfgYon.X) * float(MfgYon.X)) + (
                                                                 float(MfgYon.Y) * float(MfgYon.Y)) + (
                                                                 float(MfgYon.Z) * float(MfgYon.Z) ))))
        return numpy.rad2deg(dnn)


    @property
    def ustAci(self) -> float :
        ustAci = self.saltUstAci
        xAcisi = self.xAcisi
        sektor = self.sektor

        ustA = ustAci
        if sektor == 1:
            ustA = abs(xAcisi)
        if sektor == 2:
            ustA = abs(xAcisi)
        if sektor == 3:
            ustA = (180 - abs(ustAci)) + 90
        if sektor == 4:
            ustA = 360 - abs(xAcisi)
        if sektor == 5:
            ustA = 0.0
        if sektor == 6:
            ustA = 270.0
        if sektor == 7:
            ustA = 180
        if sektor == 8:
            ustA = 0
        if sektor == 9:
            ustA = 90.0

        return ustA


    @property
    def saltUstAci(self):
        Eksen = self.Eksen
        dPox = vector3d.Vector3d(Eksen.Y[0], Eksen.Y[1], Eksen.Y[2])
        dPoz = vector3d.Vector3d(Eksen.Z[0], Eksen.Z[1], Eksen.Z[2])
        # --->
        TkmYon = self.sahipBulTipiyle("IAktivite").takimYonu
        dTool = vector3d.Vector3d(TkmYon.X, TkmYon.Y, TkmYon.Z)
        # --->
        crossTool = vector3d.CrossProductVec(dPoz, dTool)
        rslt = vector3d.vec_dihedral(crossTool, dPoz, dPox)

        if math.isnan(rslt):
            rslt = 0.0
        return numpy.rad2deg(rslt)

    @property
    def sektor(self):
        UstAci = round(self.saltUstAci, 5)  # test
        XAcisi = round(self.xAcisi, 5)  # test
        sektor = 0

        if UstAci < 0 and XAcisi < 0:
            if not XAcisi == -0 and not UstAci == -90:
                sektor = 1
        if UstAci > 0 and XAcisi < 0:
            if not UstAci == -0 and not XAcisi == 90:  # x eksi
                if not UstAci == 180 and not XAcisi == -90:  # x eksi
                    sektor = 2
        if UstAci > 0 and XAcisi > 0:
            if not XAcisi == 180 and not UstAci == 90:
                sektor = 3
        if UstAci < 0 and XAcisi > 0:
            sektor = 4

        if sektor == 0:
            if UstAci == 0 and XAcisi == 0:  # dik
                sektor = 5

            if (UstAci == 0 and XAcisi == 90):  # x eksi
                sektor = 6
            if (UstAci == -0 and XAcisi == 90.0):  # x eksi
                sektor = 6
            if (UstAci == 180.0 and XAcisi == -90):  # x eksi
                sektor = 9

            if (XAcisi == 180 and UstAci == 90):  # y eksi
                sektor = 7

            if XAcisi == -0 and UstAci == -90:
                sektor = 8

        return sektor

    @property
    def kacmaDegerleri(self):
        return IKacmaDegerleri(self._Aktivite)

    def __call__(self):
        return {"UstAci": self.ustAci, "AltAci": self.altAci, "Kacma": self.kacmaDegerleri.kacmaDegerleri,
                "Takim": self.kacmaDegerleri.takim}

    def __str__(self):
        return repr({"UstAci": self.ustAci, "AltAci": self.altAci, "Kacma": self.kacmaDegerleri.kacmaDegerleri,
                     "Takim": self.kacmaDegerleri.takim})

    def __dict__(self):
        return {"U": self.ustAci, "A": self.altAci}
