"""
Module for various shapes.
"""
from turtle import Turtle
from point import Point


class Square:
    """
    A Square shape that can draw itself, move, and report area and perimeter.

    === Attributes ===
    @type corners: list[Point]
       corners of this Square
    @type perimeter: float
       length to traverse corners
    @type area: float
        area of this Square
    """

    def __init__(self, corners):
        """ Create a new Square self with corners.

        Assume that the corners are traversed in order, that the sides are equal
        length, and the vertices are right angles.

        @type self: Square
        @type corners: list[Point]
        @rtype: None
        """
        self.corners = corners[:]
        self._turtle = Turtle()
        self._set_perimeter()
        self._set_area()

    def _set_perimeter(self):
        """ Set Square self's perimeter to the sum of the distances between
        corners.

        @type self: Square
        @rtype: None
        """
        distance_list = []
        for i in range(len(self.corners)):
            distance_list.append(self.corners[i].distance(self.corners[i-1]))
        self._perimeter = sum(distance_list)
        # self._perimeter = 4 * self.corners[0].distance(self.corners[1])

    def _set_area(self):
        """ Set the area of Square self to the square of its sides.

        @type self: Square
        @rtype: None
        """
        self._area = self.corners[0].distance(self.corners[1]) ** 2

    def _get_perimeter(self):
        """ Return the perimeter of this Square

        @type self: Square
        @rtype: float
        """
        return self._perimeter

    def _get_area(self):
        """ Return the area of this Square

        @type self: Square
        @rtype: float
        """
        return self._area

    perimeter = property(_get_perimeter, None)
    area = property(_get_area, None)

    def move_by(self, offset_point):
        """
        Move Square self to a new position by adding Point offset_point to
        each corner.

        @type self: Square
        @type offset_point: Point
        @rtype: None
        """
        self.corners = [c + offset_point for c in self.corners]
        # equivalent to...
        # new_corners = []
        # for c in self.corners:
        #    new_corners.append(c + offset_point)
        # self.corners = new_corners

    def draw(self):
        """
        Draw Square self.

        @type self: Square
        @rtype: None
        """
        self._turtle.penup()
        self._turtle.goto(self.corners[-1].x, self.corners[-1].y)
        self._turtle.pendown()
        for i in range(len(self.corners)):
            self._turtle.goto(self.corners[i].x, self.corners[i].y)
        self._turtle.penup()
        self._turtle.goto(0, 0)


class RightAngleTriangle:
    """
    A RightAngleTriangle shape that can draw itself, move, and report area and
    perimeter.

    === Attributes ===
    @type corners: list[Point]
       corners of this RightAngleTriangle
    @type perimeter: float
       length to traverse corners
    @type area: float
        area of this RightAngleTriangle
    """

    def __init__(self, corners):
        """ Create a new RightAngleTriangle self with corners.

        Assume that the corners are traversed in order, that the sides are equal
        and the sides are of equal length, and the vertices are right angles.

        @type self: RightAngleTriangle
        @type corners: list[Point]
        @rtype: None
        """
        self.corners = corners[:]
        self._turtle = Turtle()
        self._set_perimeter()
        self._set_area()

    def _set_perimeter(self):
        """ Set RightAngleTriangle self's perimeter to the sum of the distances
        between corners

        @type self: RightAngleTriangle
        @rtype: None
        """
        distance_list = []
        for i in range(len(self.corners)):
            distance_list.append(self.corners[i].distance(self.corners[i-1]))
        self._perimeter = sum(distance_list)

    def _set_area(self):
        """ Set the area of RightAngleTriangle self to the product of its legs,
         divided by 2.0

        @type self: RightAngleTriangle
        @rtype: None
        """
        leg1 = self.corners[-1].distance(self.corners[0])
        leg2 = self.corners[0].distance(self.corners[1])
        self._area = (leg1 * leg2) / 2.0

    def _get_perimeter(self):
        """ Return the perimeter of this RightAngleTriangle

        @type self: RightAngleTriangle
        @rtype: float
        """
        return self._perimeter

    def _get_area(self):
        """ Return the area of this RightAngleTriangle

        @type self: RightAngleTriangle
        @rtype: float
        """
        return self._area

    perimeter = property(_get_perimeter, None)
    area = property(_get_area, None)

    def move_by(self, offset_point):
        """
        Move RightAngleTriangle self to a new position by adding Point
        offset_point to each corner.

        @type self: RightAngleTriangle
        @type offset_point: Point
        @rtype: None
        """
        self.corners = [c + offset_point for c in self.corners]

    def draw(self):
        """
        Draw RightAngleTriangle self.

        @type self: RightAngleTriangle
        @rtype: None
        """
        self._turtle.penup()
        self._turtle.goto(self.corners[-1].x, self.corners[-1].y)
        self._turtle.pendown()
        for i in range(len(self.corners)):
            self._turtle.goto(self.corners[i].x, self.corners[i].y)
        self._turtle.penup()
        self._turtle.goto(0, 0)

if __name__ == '__main__':
    import doctest
    doctest.testmod()

    s = Square([Point(0, 0), Point(10, 0), Point(10, 10), Point(0, 10)])
    print(s.area)
    # s.area = 1000 # ==> will produce an exception - not allowed to set area
