# shapes6.py
from Processing import *
import math

window(500, 500)

# Utilities

# Given shape points, compute bounding box
def boundingBox( pts ):
    minX, maxX = pts[0][0], pts[0][0]
    minY, maxY = pts[0][1], pts[0][1]
    for p in pts:
        if p[0] < minX:
            minX = p[0]
        elif p[0] > maxX:
            maxX = p[0]
        if p[1] < minY:
            minY = p[1]
        elif p[1] > maxY:
            maxY = p[1]
    return [minX, minY, maxX, maxY]

# Shared Shape class
class Shape:
    def __init__(self, pts):
        self.pts = pts
        self.strokeColor = color(32)
        self.fillColor = color(255, 128, 128)
        self.bbox = boundingBox(self.pts)
        self.width = self.bbox[2] - self.bbox[0]
        self.height = self.bbox[3] - self.bbox[1]
        self.centerX = 0.5 * (self.bbox[2] + self.bbox[0])
        self.centerY = 0.5 * (self.bbox[3] + self.bbox[1])

    def draw(self):
        fill( self.fillColor )
        stroke( self.strokeColor )
        self.drawShape()

    def drawShape(self):
        pass

    # Default implementation of containsPoint checks bounding box
    def containsPoint(self, x, y):
        if x < self.bbox[0]: return False
        if x > self.bbox[2]: return False
        if y < self.bbox[1]: return False
        if y > self.bbox[3]: return False
        return True

    def mouseMoved(self):
        x, y = mouseX(), mouseY()
        if self.containsPoint(x, y):
            self.strokeColor = color(255)
        else:
            self.strokeColor = color(32)

# Rectangle Class
class Rectangle(Shape):
    def __init__(self, pts):
        Shape.__init__(self, pts)

    def drawShape(self):
        rectMode(CORNER)
        rect(self.bbox[0], self.bbox[1], self.width, self.height)

# Ellipse Class
class Ellipse(Shape):
    def __init__(self, pts):
        Shape.__init__(self, pts)

    def drawShape(self):
        ellipseMode(CENTER)
        ellipse(self.centerX, self.centerY, self.width, self.height)

    def containsPoint(self, x, y):
        dx = x - self.centerX
        dy = y - self.centerY
        return 4.0*((dx*dx)/(self.width**2) + (dy*dy)/(self.height**2)) < 1.0

class Triangle(Shape):
    def __init__(self, pts):
        Shape.__init__(self, pts)

    # Draw the triangle
    def drawShape(self):
        triangle(self.pts[0][0], self.pts[0][1], self.pts[1][0], self.pts[1][1], self.pts[2][0], self.pts[2][1])

def mouseMoved(o, e):
    for s in shapes:
        s.mouseMoved()

onMouseMoved += mouseMoved

shapes = []
def draw(o, e):
  background(200)
  for s in shapes:
      s.draw()

frameRate(20)
onLoop += draw
loop()

shapes.append( Rectangle ( [[100, 200], [200, 250]] ) )
shapes.append( Ellipse( [[200, 100], [270, 160]] ) )
shapes.append( Triangle( [[300, 300], [270, 370], [400, 400]] ) )
