# -*- coding: utf-8 -*-

from math import dist
import numpy as np

from Model.Geometry.Point import Point

class PointXYZ(Point):
    def __init__(self, x:float = 0.0, y:float = 0.0, z:float = 0.0,
                 name:str = ""):
        super(PointXYZ, self).__init__(name=name)

        self._x = float(x)
        self._y = float(y)
        self._z = float(z)

    @classmethod
    def from_data(cls, header, data):
        point = None
        try:
            if len(header) == 0:
                point = cls(
                    *data
                )
            else:
                valid_header = {'name', 'x', 'y', 'z'}
                d = {}
                for i, v in enumerate(data):
                    h = header[i].strip().lower().split(' ')[0]
                    if h in valid_header:
                        d[h] = v

                point = cls(**d)
        except Exception as e:
            raise ClipboardFormatError(header, data)

        return point


    def __repr__(self):
        return f"({self._x}, {self._y}, {self._z}, {self._name})"

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = float(value)

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, value):
        self._y = float(value)

    @property
    def z(self):
        return self._z

    @z.setter
    def z(self, value):
        self._z = float(value)

    def is_nan(self):
        """
        Returns:
            True if at least one coordinate is as np.nan
        """
        return (np.isnan(self.x) or
                np.isnan(self.y) or
                np.isnan(self.z))

    def dist(self, p2):
        return PointXYZ.distance(self, p2)

    @staticmethod
    def distance(p1, p2):
        """Euclidean distance between p1 and p2.

        Args:
            p1: A XYZ Point
            p2: A XYZ Point

        Returns:
            Euclidean distance between the two points
        """
        return dist((p1.x, p1.y, p1.z), (p2.x, p2.y, p2.z))