import cv2
import numpy as np
import sys
import os

# Read inputs from command line
imageName, blurSize, circleDist, cannyThresh, accumThresh, maxRadius, angleStep, eyeType = sys.argv[1:]
blurSize = int(blurSize)
circleDist = int(circleDist)
cannyThresh = int(cannyThresh)
accumThresh = int(accumThresh)
maxRadius = int(maxRadius)
angleStep = int(angleStep)
eyePicNamesPos = [os.path.join(eyeType,fileName) for fileName in next(os.walk(eyeType))[2]]

# Read image
imgO = cv2.imread(imageName,1)
cv2.imshow("Original", imgO)

# Preprocessing and hough circle detection
imgGray = cv2.cvtColor(cv2.medianBlur(imgO, blurSize), cv2.COLOR_BGR2GRAY)
circles = cv2.HoughCircles(imgGray, cv2.cv.CV_HOUGH_GRADIENT, 1, circleDist, \
        param1=cannyThresh, param2=accumThresh, maxRadius=maxRadius, minRadius=2)
if circles is None:
    print "Parameters too restrictive. No circles found."
else:
    circles = np.int16(circles)

    eyePicNames = np.random.choice(eyePicNamesPos, circles.shape[1])
    eyeFrames = []
    # Rotation loop
    for angle in range(0,360,angleStep):
        img = imgO.copy()
        i = 0
        for circle in circles[0,:]:
            x, y, r = circle

            if x-r>=0 and y-r>=0 and y+r<=imgO.shape[0] and x+r<=imgO.shape[1]:
                # Get eye image and rotate
                eyeImg = cv2.imread(eyePicNames[i], 1)
                eyeImg = cv2.resize(eyeImg, (r*2, r*2))
                M = cv2.getRotationMatrix2D((r, r), angle, 1)
                eyeImg = cv2.warpAffine(eyeImg, M, (r*2, r*2))
                
                # Create mask from circle radius
                mask = np.zeros((r*2, r*2), np.uint8)
                cv2.circle(mask, (r, r), r, (255,255,255), -1)

                # Bitwise operations to put in new image
                eyeMasked = cv2.bitwise_and(eyeImg, eyeImg, mask = mask)
                section = img[y-r:y+r, x-r:x+r]
                section = cv2.bitwise_and(section, section, mask = cv2.bitwise_not(mask))
                section = section + eyeMasked
                img[y-r:y+r, x-r:x+r] = section

            i += 1
        eyeFrames.append(img)

    # Write output
    vidWrite = cv2.VideoWriter('output/video.avi', cv2.cv.CV_FOURCC(*'XVID'), 30, imgO.shape[1::-1], isColor=True)
    for _ in range(5):
        for im in eyeFrames:
            vidWrite.write(im)
    vidWrite.release()
    cv2.imwrite('output/image.jpg', eyeFrames[0])

    # Display loop
    loop = True
    i = 0
    while loop:
        cv2.imshow("Altered", eyeFrames[i])
        if cv2.waitKey(30) != -1:
            loop = False
        i = (i + 1) % len(eyeFrames)
    cv2.destroyAllWindows()