import cv2
import numpy as np


class FindBalls:
    """
    An OpenCV pipeline generated by GRIP.
    """
    
    def __init__(self):
        """initializes all values to presets or None if need to be set
        """
        self.f = 1.0
        self.hue = [0.0, 61.74061433447099]
        self.sat = [73.38129496402877, 255.0]
        self.val = [215.55755395683454*self.f, 255.0*self.f]
        
        self.starthsv = (self.hue[0], self.sat[0], self.val[0])
        self.endhsv   = (self.hue[1], self.sat[1], self.val[1])

    def process(self, source0):
        """
        Runs the pipeline and sets all outputs to new values.
        """
        imagebw = cv2.cvtColor(source0, cv2.COLOR_BGR2GRAY)
        blurred = cv2.GaussianBlur(imagebw, (9, 9), 0)
        thresh1 = cv2.adaptiveThreshold(blurred, 255,
        cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 4)
        imagehsv = cv2.cvtColor(source0, cv2.COLOR_BGR2HSV)
        thresh2 = cv2.inRange(imagehsv, self.starthsv,  self.endhsv)
        threshmask = cv2.bitwise_and(thresh1, thresh1, mask = thresh2)
        (_, contours, _) = cv2.findContours(threshmask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
        
        contours_area = []

        # calculate area and filter into new array
        for con in contours:
                area = cv2.contourArea(con)
                if 35 < area:
                        contours_area.append(con)
        print(len(contours_area))      
        balls = source0

        for con in contours_area:
                (x,y),radius = cv2.minEnclosingCircle(con)
                center = (int(x),int(y))
                radius = int(radius)
                cv2.circle(balls,center,radius,(0,255,0),2)
                x,y,w,h = cv2.boundingRect(con)
                cv2.rectangle(balls,(x,y),(x+w,y+h),(255,0,0),2)
                rect = cv2.minAreaRect(con)
                box = cv2.boxPoints(rect)
                box = np.int0(box)
                cv2.drawContours(balls,[box],0,(0,0,255),2)
        
        return balls