from abc import ABCMeta
from math import sin, cos


class Location:
    __metaclass__ = ABCMeta


class Coor(Location):
    def __init__(self, x, y, time=0.0):
        self.x = x
        self.y = y
        self.time = time

    def __str__(self):
        return "({0},{1},{2})".format(self.x, self.y, self.time)

    def __add__(self, other):
        # addition of coordinates
        x = self.x + other.x
        y = self.y + other.y
        time = self.time + other.time

        return Coor(x, y, time)

    def IsZero(self):
        if self.x == 0 and self.y == 0 and self.time == 0:
            return True
        else:
            return False

    def __sub__(self, other):
        # subtraction of coordinates
        x = self.x - other.x
        y = self.y - other.y
        time = self.time - other.time

        return Coor(x, y, time)

    @staticmethod
    def rotate( coor, origin, angle):
        """ rotate coordinates around 'origin' (in spatial dimensions only)
            angle: rotation angle in rad"""
        if angle == 0.0:
            return coor

        x_trans = coor.x - origin.x
        y_trans = coor.y - origin.y

        return Coor(cos(angle) * x_trans - sin(angle) * y_trans + origin.x,
                    sin(angle) * x_trans + cos(angle) * y_trans + origin.y,
                    coor.time)


class Domain(Location):
    """An imutable class definning type Domain"""

    __slots__ = ["position", "extend", "angle"]

    def __init__(self, position, extend, angle):
        """Constructor"""
        super(Domain, self).__setattr__("position", position)
        super(Domain, self).__setattr__("extend", extend)
        super(Domain, self).__setattr__("angle", angle)

    def __setattr__(self, name, value):
        """"""
        msg = "'%s' has no attribute %s" % (self.__class__,
                                            name)
        raise AttributeError(msg)