import turtle

"""
Module containing a superclass Shape, with
two subclasses Rectangle and Circle.
OPTIONAL for students:
    Uses Python's turtle module to produce graphics.
    See https://docs.python.org/3.7/library/turtle.html

Author: Anne Bracy (awb93), Daisy Fan (kdf4)
Date:   April 2020
"""

class Shape():
    """
    An instance is a single shape located at
    coordinates x,y.
    """
    # Class Attribute
    NUM_SHAPES = 0

    # BUILT-IN METHODS
    def __init__(self, x,y):
        """
        Creates a new Shape, located at (x,y).

        x: initial x coordinate [float or int]
        y: initial y coordinate [float or int]
        """
        # Instance attributes
        self.x = x
        self.y = y
        Shape.NUM_SHAPES = Shape.NUM_SHAPES + 1

    def __str__(self):
        return "Shape @ ("+str(self.x)+", "+str(self.y)+")"

    def __eq__(self, other):
        """If position is the same, then they're equal as far as Shape knows"""
        return self.x == other.x and self.y == other.y

    # METHODS
    def draw(self):
        """
        No matter what shape you are, we want to pick up the
        pen, move to the location of the shape, put the pen
        down. Only the shape subclasses know how to do the
        actual drawing, though.
        """
        # OPTIONAL: do not worry about turle graphics commands
        turtle.penup()
        turtle.setx(self.x)
        turtle.sety(self.y)
        turtle.pendown()

class Circle(Shape):
    """
    An instance is a circle.
    """

    # Class Attribute
    NUM_CIRCLES = 0

    # BUILT-IN METHODS
    def __init__(self, x, y, radius):
        """
        Creates a new Circle located at x,y of size radius

        x: initial x coordinate [float or int]
        y: initial y coordinate [float or int]
        radius: radius of circle [positive float or int]
        """
        super().__init__(x, y)
        self.radius = radius
        Circle.NUM_CIRCLES = Circle.NUM_CIRCLES + 1

    def __str__(self):
        return "Circle: Radius="+str(self.radius)+" "+super().__str__()

    def __eq__(self, other):
        """If radii are equal, let super do the rest"""
        return self.radius == other.radius and super().__eq__(other)

    # METHODS
    def draw(self):
        # OPTIONAL: do not worry about turtle graphics commands
        super().draw()
        turtle.circle(self.radius)


class Rectangle(Shape):
    """
    An instance is a rectangle.
    """

    # BUILT-IN METHODS
    def __init__(self, x, y, ht, len):
        """
        Creates a new Rectangle located at x,y
        with height ht and length len

        x: initial x coordinate [float or int]
        y: initial y coordinate [float or int]
        ht: height of rectangle [positive float or int]
        len: length of rectangle [positive float or int]
        """
        self.height = ht
        self.length = len
        super().__init__(x,y)

    def __str__(self):
        return "Rectangle: "+str(self.height)+" x " +str(self.length)+" "+ \
            super().__str__()

    def __eq__(self, other):
        """If length and height are equal, let super do the rest"""
        return self.height == other.height and \
            self.length == other.length and \
            super().__eq__(other)

    # METHODS
    def draw(self):
        # OPTIONAL: do not worry about turtle graphics commands
        super().draw()
        for i in list(range(2)): #repeat twice
            turtle.forward(self.length) # draw a line
            turtle.left(90)             # turn 90 degrees
            turtle.forward(self.height) # draw a line
            turtle.left(90)             # turn 90 degrees

class Square(Rectangle):
    """
    An instance is a square.

    Square must have both sides of equal length.

    """

    # BUILT-IN METHODS
    def __init__(self, x, y, len):
        """
        Creates a new Square located at x,y
        with height and length len

        x: initial x coordinate [float or int]
        y: initial y coordinate [float or int]
        len: length of square [positive float or int]
        """
        # maintains class invariant that ht == len
        super().__init__(x, y, len, len)

    def __str__(self):
        return "Square: "+str(self.height)+" x " +str(self.length)+" "+ \
            super().__str__()

    def __eq__(self, other):
        """If the other guy is a square, then looks like we just need
        to check for attribute equality"""
        return isinstance(other, Square) and super().__eq__(other)
