from numbers import Number
import math
import operator
import warnings


__all__ = ["Vector"]


class Vector(tuple):

    """A math-like vector.

    Represents an n-dimensional numeric vector. ``Vector`` objects support
    vector addition and subtraction, scalar multiplication and division,
    negation, rounding, and comparison tests.
    """

    __slots__ = ()

    def __new__(cls, values, keep=False):
        if keep is not False:
            warnings.warn(
                "the 'keep' argument has been deprecated",
                DeprecationWarning,
            )
        if type(values) == Vector:
            # No need to create a new object
            return values
        return super().__new__(cls, values)

    def __repr__(self):
        return f"{self.__class__.__name__}({super().__repr__()})"

    def _vectorOp(self, other, op):
        if isinstance(other, Vector):
            assert len(self) == len(other)
            return self.__class__(op(a, b) for a, b in zip(self, other))
        if isinstance(other, Number):
            return self.__class__(op(v, other) for v in self)
        raise NotImplementedError()

    def _scalarOp(self, other, op):
        if isinstance(other, Number):
            return self.__class__(op(v, other) for v in self)
        raise NotImplementedError()

    def _unaryOp(self, op):
        return self.__class__(op(v) for v in self)

    def __add__(self, other):
        return self._vectorOp(other, operator.add)

    __radd__ = __add__

    def __sub__(self, other):
        return self._vectorOp(other, operator.sub)

    def __rsub__(self, other):
        return self._vectorOp(other, _operator_rsub)

    def __mul__(self, other):
        return self._scalarOp(other, operator.mul)

    __rmul__ = __mul__

    def __truediv__(self, other):
        return self._scalarOp(other, operator.truediv)

    def __rtruediv__(self, other):
        return self._scalarOp(other, _operator_rtruediv)

    def __pos__(self):
        return self._unaryOp(operator.pos)

    def __neg__(self):
        return self._unaryOp(operator.neg)

    def __round__(self, *, round=round):
        return self._unaryOp(round)

    def __eq__(self, other):
        if isinstance(other, list):
            # bw compat Vector([1, 2, 3]) == [1, 2, 3]
            other = tuple(other)
        return super().__eq__(other)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __bool__(self):
        return any(self)

    __nonzero__ = __bool__

    def __abs__(self):
        return math.sqrt(sum(x * x for x in self))

    def length(self):
        """Return the length of the vector. Equivalent to abs(vector)."""
        return abs(self)

    def normalized(self):
        """Return the normalized vector of the vector."""
        return self / abs(self)

    def dot(self, other):
        """Performs vector dot product, returning the sum of
        ``a[0] * b[0], a[1] * b[1], ...``"""
        assert len(self) == len(other)
        return sum(a * b for a, b in zip(self, other))

    # Deprecated methods/properties

    def toInt(self):
        warnings.warn(
            "the 'toInt' method has been deprecated, use round(vector) instead",
            DeprecationWarning,
        )
        return self.__round__()

    @property
    def values(self):
        warnings.warn(
            "the 'values' attribute has been deprecated, use "
            "the vector object itself instead",
            DeprecationWarning,
        )
        return list(self)

    @values.setter
    def values(self, values):
        raise AttributeError(
            "can't set attribute, the 'values' attribute has been deprecated",
        )


def _operator_rsub(a, b):
    return operator.sub(b, a)


def _operator_rtruediv(a, b):
    return operator.truediv(b, a)
