import sys

import cv2
from keras.models import load_model
from keras.preprocessing import image
import numpy as np

#diccionari de generes
gender_dict = {-1:'Unknow', 0:'Dona', 1:'Home'}

def get_labels(dataset_name):
    if dataset_name == 'fer2013':
        return {0:'angry',1:'disgust',2:'fear',3:'happy',
                4:'sad',5:'surprise',6:'neutral'}
    elif dataset_name == 'imdb':
        return {0:'Dona', 1:'Home'}
    elif dataset_name == 'KDEF':
        return {0:'AN', 1:'DI', 2:'AF', 3:'HA', 4:'SA', 5:'SU', 6:'NE'}
    else:
        raise Exception('Invalid dataset name')
    
def preprocess_input(x, v2=True):
    x = x.astype('float32')
    x = x / 255.0
    if v2:
        x = x - 0.5
        x = x * 2.0
    return x
 
def load_image(image_path, grayscale=False, target_size=None):
    pil_image = image.load_img(image_path, grayscale, target_size)
    return image.img_to_array(pil_image)

def load_detection_model(model_path):
    detection_model = cv2.CascadeClassifier(model_path)
    return detection_model

def detect_faces(detection_model, gray_image_array):
    return detection_model.detectMultiScale(gray_image_array, 1.2, 5)

def draw_bounding_box(face_coordinates, image_array, color):
    x, y, w, h = face_coordinates
    cv2.rectangle(image_array, (x, y), (x + w, y + h), color, 2)

def apply_offsets(face_coordinates, offsets):
    x, y, width, height = face_coordinates
    x_off, y_off = offsets
    return (x - x_off, x + width + x_off, y - y_off, y + height + y_off)

def draw_text(coordinates, image_array, text, color, x_offset=0, y_offset=0,
                                                font_scale=2, thickness=2):
    x, y = coordinates[:2]
    cv2.putText(image_array, text, (x + x_offset, y + y_offset),
                cv2.FONT_HERSHEY_SIMPLEX, font_scale, color, thickness)
                #font_scale, color, thickness, cv2.LINE_AA)
                #font_scale, color, thickness)

def get_colors(num_classes):
    colors = plt.cm.hsv(np.linspace(0, 1, num_classes)).tolist()
    colors = np.asarray(colors) * 255
    return colors


def genderImage(image_path,output_path_image):
    detection_model_path = './haarcascades/haarcascade_frontalface_default.xml'
    gender_model_path = './gender_models/simple_CNN.81-0.96.hdf5'

    #gender_labels = get_labels('imdb')
    gender_labels = {0:'Dona', 1:'Home'}
    font = cv2.FONT_HERSHEY_SIMPLEX

    # hyper-parameters for bounding boxes shape
    gender_offsets = (30, 60)
    gender_offsets = (10, 10)


    # loading models
    face_detection = load_detection_model(detection_model_path)
    gender_classifier = load_model(gender_model_path, compile=False)

    # getting input model shapes for inference
    #gender_target_size = gender_classifier.input_shape[1:3]

    # loading images
    rgb_image = load_image(image_path, grayscale=False)
    gray_image = load_image(image_path, grayscale=True)
    gray_image = np.squeeze(gray_image)
    gray_image = gray_image.astype('uint8')

    faces = detect_faces(face_detection, gray_image)
    for face_coordinates in faces:
        x1, x2, y1, y2 = apply_offsets(face_coordinates, gender_offsets)
        rgb_face = rgb_image[y1:y2, x1:x2]

        #try:
        #    rgb_face = cv2.resize(rgb_face, (gender_target_size))
        #except:
        #    continue

        #rgb_face = preprocess_input(rgb_face, False)
        #rgb_face = np.expand_dims(rgb_face, 0)
        
        #gender_prediction = gender_classifier.predict(rgb_face)
        #gender_label_arg = np.argmax(gender_prediction)
        #gender_text = gender_labels[gender_label_arg]
        gender_text = gender_labels[getGender(rgb_face, gender_classifier)]
        
        if gender_text == gender_labels[0]:
            color = (0, 0, 255)
        else:
            color = (255, 0, 0)

        draw_bounding_box(face_coordinates, rgb_image, color)
        draw_text(face_coordinates, rgb_image, gender_text, color, 0, -10, 1, 2)

    bgr_image = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2BGR)
    cv2.imwrite('./images/'+output_path_image, bgr_image) 


def getGender(rgb_face, gender_classifier):
    # getting input model shapes for inference
    gender_target_size = gender_classifier.input_shape[1:3]
    
    try:
        rgb_face = cv2.resize(rgb_face, (gender_target_size))
    except:
        return None #Al no poder dimensionar imatge per reconeizament es descarta
        #continue
    
    rgb_face = preprocess_input(rgb_face, False)
    rgb_face = np.expand_dims(rgb_face, 0)
    
    gender_prediction = gender_classifier.predict(rgb_face)
    #gender_label_arg = np.argmax(gender_prediction)
    #gender_text = gender_labels[gender_label_arg]
    
    return np.argmax(gender_prediction) 

# parameters for loading data and images
#image_path_in = sys.argv[1]
#image_path_out = sys.argv[2]
#if len(sys.argv) == 3:
#    print image_path_in + ' salida -> ' + image_path_out
#    genderImage(image_path_in,image_path_out)
