import numpy as np
from PIL import Image,ImageDraw
from glibvision.numpy_utils import extruce_points,bulge_polygon


def minus_point(pt1,pt2):
    return [pt1[0]-pt2[0],pt1[1]-pt2[1]]

def lerp_point(pt1,pt2,pt2_ratio):
    return [int(pt1[0]*(1.0-pt2_ratio)+pt2[0]*pt2_ratio),pt1[1]*(1.0-pt2_ratio)+pt2[1]*pt2_ratio]

def mean_point(points):
    xs = 0
    ys = 0
    for pt in points:
        xs +=pt[0]
        ys +=pt[1]
    return [int(xs/len(points)),int(ys/len(points))]

def get_face_points(face_landmarks_list):
    contour_points=get_landmark_points(face_landmarks_list,PARTS_CONTOUR)
    left_eyebrow_points=get_landmark_points(face_landmarks_list,PARTS_LEFT_EYEBROW)

    right_eyebrow_points=get_landmark_points(face_landmarks_list,PARTS_RIGHT_EYEBROW)

    nose_points=get_landmark_points(face_landmarks_list,PARTS_NOSE_BRIDGE)
    
    diff_right = minus_point(contour_points[1],contour_points[0])
    right_minus_corner = minus_point(contour_points[0] , diff_right)
    right_contour = lerp_point(right_minus_corner,left_eyebrow_points[0],0.3)

    diff_left = minus_point(contour_points[15],contour_points[16])
    left_minus_corner = minus_point(contour_points[16] , diff_left)
    left_contour = lerp_point(left_minus_corner,right_eyebrow_points[-1],0.3)

    middle_face = mean_point([nose_points[0],right_eyebrow_points[0],left_eyebrow_points[-1]])
    return [right_contour]+list(contour_points)+[left_contour,middle_face]


def get_innner_mouth_points(face_landmarks_list):
    top_points=get_landmark_points(face_landmarks_list,PARTS_UPPER_LIP)
    bottom_points=get_landmark_points(face_landmarks_list,PARTS_LOWER_LIP)
    return top_points[7:]+bottom_points[7:]#[::-1]


PARTS_UPPER_LIP = "top_lip"
PARTS_LOWER_LIP = "bottom_lip"
PARTS_CONTOUR ="chin"
PARTS_LEFT_EYEBROW ="left_eyebrow"
PARTS_RIGHT_EYEBROW ="right_eyebrow"
PARTS_LEFT_EYE ="left_eye"
PARTS_RIGHT_EYE ="right_eye"
PARTS_NOSE_TIP ="nose_tip"
PARTS_NOSE_BRIDGE ="nose_bridge"

def get_landmark_points(face_landmarks_list,key):
    matching_landmark_points = []
    for face_landmarks in face_landmarks_list:
      for landmark_name, landmark_points in face_landmarks.items():
        matching_landmark_points = landmark_points.copy()
        if landmark_name ==key:
            return tuple(matching_landmark_points)
        
def get_left_upper_eyelid_points(face_landmarks_list,bulge_factor = 0.2):
    eye_points=get_landmark_points(face_landmarks_list,PARTS_LEFT_EYE)
    extruded_points=[]
   
    need_extrude =[0,1,2]
    for index in range(len(eye_points)):
        if index in need_extrude:
            ratio = 1.3
        else:
            ratio = 1.1
        ex_point=extruce_points(eye_points,index,ratio)
        extruded_points.append(ex_point)
    return extruded_points

def get_right_upper_eyelid_points(face_landmarks_list,bulge_factor = 0.2):
    eye_points=get_landmark_points(face_landmarks_list,PARTS_RIGHT_EYE)
    extruded_points=[]
   
    need_extrude =[1,2,3]
    for index in range(len(eye_points)):
        if index in need_extrude:
            ratio = 1.3
        else:
            ratio = 1.1
        ex_point=extruce_points(eye_points,index,ratio)
        extruded_points.append(ex_point)
    #return list(eye_points[0:4])+extruded_points
    return extruded_points

def get_bulged_eyes(face_landmarks_list,bulge_factor=0.2):
    points1=get_landmark_points(face_landmarks_list,PARTS_LEFT_EYE)
    points2=get_landmark_points(face_landmarks_list,PARTS_RIGHT_EYE)
    
    return bulge_polygon(points1, bulge_factor=bulge_factor),bulge_polygon(points2, bulge_factor=bulge_factor)


def get_lerp(point1,point2,ratio1=0.5):
    x = point1[0]*ratio1 + point2[0]*(1.0-ratio1)
    y = point1[1]*ratio1 + point2[1]*(1.0-ratio1)
    return [int(x),int(y)]

def get_close_eyelid_point(landmarks_list,bulge = 0.01):
    left = get_landmark_points(landmarks_list,PARTS_LEFT_EYE)
    left_points = [get_lerp(left[3],left[4],0.6)]+list(left[4:6])+[left[0]]
    right = get_landmark_points(landmarks_list,PARTS_RIGHT_EYE)
    right_points = [get_lerp(right[0],right[5],0.6)]+list(right[3:6][::-1])

    #print("right points")
    #print(right_points) 
    last2 = right_points[-2:]
    #print(last2[0])
    #print(last2[1])
    extra_dvidied = 10
    diff = ((last2[0][0]-last2[1][0])/extra_dvidied,(last2[0][1]-last2[1][1])/extra_dvidied)
    extra = [int(last2[1][0] - diff[0]),int(last2[1][1] - diff[1])]

    height = abs(right_points[0][1]-right_points[-1][1])
    print(f"height = {height}")
    move_down = int(height/5)
    print("diff")
    print(diff)
    print(right_points[-1])
    print(extra)
    right_points.append(extra)
    for pt in right_points:
        pt[1]+=move_down

    last2 = left_points[-2:]
    diff = ((last2[0][0]-last2[1][0])/extra_dvidied,(last2[0][1]-last2[1][1])/extra_dvidied)
    extra = [int(last2[1][0] - diff[0]),int(last2[1][1] - diff[1])]
    left_points.append(extra)
    for pt in left_points:
        pt[1]+=move_down

    print(right_points)
    if bulge:
        left_points = bulge_polygon(left_points,0.1,False).tolist()
        right_points = bulge_polygon(right_points,0.1,False).tolist()
     ###LEFT
    print("####RIGHT")
    # last 2 points
   
   
    return left_points,right_points