import math

import numpy
from win32com.client import CDispatch

from IFikoAcilar.IFikoAcilar import IFikoAcilar
from IFikomObject import IFikomObject
import vector3d


__author__ = 'CAM'


class IFikoSaltAci(IFikomObject):
    def __init__(self, obj:CDispatch, sahip:IFikoAcilar=None):
        super(IFikoSaltAci, self).__init__(obj, sahip)
        self.tipi = "IFikoSaltAcilar"
        # self.ismi = "IFikoSaltAcilar"
        # --->Sabit Degiskenler
        self.__aktivite = sahip
        self.__eksenVektor = None#self.__aktivite.eksenVektor

    @property
    def sahip(self) -> IFikoAcilar:
        return self.sahip

    @sahip.setter
    def sahip(self, value:IFikoAcilar):
        self.sahip = value

    @property
    def __xAcisi(self):
        if not self.__eksenVektor:
            self.__eksenVektor = self.__aktivite.eksenVektor
        Eksen = self.__eksenVektor
        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.__aktivite.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:
        if not self.__eksenVektor:
            self.__eksenVektor = self.__aktivite.eksenVektor
        MfgYon = self.__aktivite.takimYonu
        EksenYon = self.__eksenVektor
        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 __saltUstAci(self):
        if not self.__eksenVektor:
            self.__eksenVektor = self.__aktivite.eksenVektor
        Eksen = self.__eksenVektor
        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.__aktivite.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 __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 ustAci(self)->float:
        return self.__ustAci

    @ustAci.setter
    def ustAci(self, value):
        pass
    
    @property
    def altAci(self):
        return self.__altAci
    
    @altAci.setter
    def altAci(self, value):
        pass

    @property
    def sektor(self):
        return self.__sektor

    @sektor.setter
    def sektor(self, value):
        pass

    def aciDegistir(self, ust:float, alt:float):
        pass

    def __str__(self) -> str:
        return repr({"Üst Açı": self.ustAci, "Alt Açı":self.altAci, "Sektör":self.sektor })