# coding=utf-8
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import ugettext_lazy as _

ETNIAS = (
    ('afro', _(u'Africano')),
    ('arabe', _(u'Árabe')),
    ('brasil', _(u'Brasileño')),
    ('chino', _(u'Chino')),
    ('frances', _(u'Francés')),
    ('hispano', _(u'Hispano')),
    ('ingles', _(u'Inglés')),
    ('italiano', _(u'Italiano')),
    ('japones', _(u'Japonés')),
    ('nordico', _(u'Nórdico')),
    ('ruso', _(u'Ruso')),
    ('germano', _(u'Germano')),
    ('yankee', _(u'Yankee'))
)

PIEL = (
    ('negro', _(u'Negro')),
    ('caucasico', _(u'Caucásico')),
    ('moreno', _(u'Moreno')),
    ('indoamericano', _(u'Indoamericano')),
    ('sajon', _(u'Sajón / Nórdico')),
    ('oriental', _(u'Oriental')),
    ('mesopotamico', _(u'Mesopotámico')),
)

ETNIA_PIEL = {
    'afro': {
        'negro': 1
    },
    'arabe': {
        'mesopotamico': 0.97,
        'caucasico': 0.01,
        'negro': 0.02
    },
    'brasil': {
        'indoamericano': 0.45,
        'negro': 0.45,
        'caucasico': 0.1
    },
    'chino': {
        'oriental': 1
    },
    'japones': {
        'oriental': 1
    },
    'frances': {
        'caucasico': 0.9,
        'negro': 0.1
    },
    'hispano': {
        'caucasico': 0.2,
        'indoamericano': 0.3,
        'moreno': 0.3,
        'negro': 0.2
    },
    'ingles': {
        'sajon': 0.7,
        'caucasico': 0.3
    },
    'italiano': {
        'caucasico': 1
    },
    'nordico': {
        'sajon': 1
    },
    'ruso': {
        'sajon': 1
    },
    'germano': {
        'sajon': 0.9,
        'caucasico': 0.1
    },
    'yankee': {
        'oriental': 0.1,
        'moreno': 0.2,
        'sajon': 0.2,
        'indoamericano': 0.1,
        'caucasico': 0.2,
        'negro': 0.2
    }
}

GENDER = (
    ('m', _(u'Masculino')),
    ('f', _(u'Femenino'))
)

ALTURA = (
    (160, _(u'1.60m')),
    (165, _(u'1.65m')),
    (170, _(u'1.70m')),
    (175, _(u'1.75m')),
    (180, _(u'1.80m')),
    (185, _(u'1.85m')),
    (190, _(u'1.90m')),
    (195, _(u'1.95m')),
    (200, _(u'2.00m')),
    (205, _(u'2.05m')),
    (210, _(u'2.10m')),
)

ETNIA_ALTURA = {
    'afro': (
        175,
        180,
        185,
        190,
        200,
        205,
        210,
    ),
    'arabe': (
        160,
        165,
        170,
        175,
        180,
        185,
    ),
    'brasil': (
        170,
        175,
        180,
        185,
        190,
        200,
    ),
    'chino': (
        170,
        175,
        180,
        185,
    ),
    'japones': (
        170,
        175,
        180,
        185,
    ),
    'frances': (
        160,
        165,
        170,
        175,
        180,
        185,
        190,
        200,
        205,
        210,
    ),
    'hispano': (
        160,
        165,
        170,
        175,
        180,
        185,
        190,
    ),
    'ingles': {
        160,
        165,
        170,
        175,
        180,
        185,
        190,
    },
    'italiano': (
        160,
        165,
        170,
        175,
        180,
        185,
        190,
    ),
    'nordico': (
        170,
        175,
        180,
        185,
        190,
        195,
        200
    ),
    'ruso': (
        170,
        175,
        180,
        185,
        190,
        195,
        200
    ),
    'germano': (
        165,
        170,
        175,
        180,
        185,
        190,
        195,
        200
    ),
    'yankee': (
        160,
        165,
        170,
        175,
        180,
        185,
        190,
        195,
        200,
        205
    )
}

OJOS = (
    ('grises', _(u"Grises")),
    ('celestes', _(u"Celestes")),
    ('miel', _(u"Miel")),
    ('castanos', _(u"Castaños")),
    ('negros', _(u"Negros")),
    ('verdes', _(u"Negros")),
)

ETNIA_OJOS = {
    'afro': {
        'castanos': 0.5,
        'negros': 0.5
    },
    'arabe': {
        'castanos': 0.9,
        'negros': 0.05,
        'verdes': 0.05
    },
    'brasil': {
        'miel': 0.2,
        'verdes': 0.2,
        'celestes': 0.2,
        'castanos': 0.2,
        'negros': 0.2
    },
    'chino': {
        'negros': 1
    },
    'japones': {
        'negros': 1
    },
    'frances': {
        'celestes': 0.10,
        'verdes': 0.10,
        'castanos': 0.40,
        'negros': 0.10,
        'miel': 0.30
    },
    'hispano': {
        'castanos': 0.4,
        'miel': 0.3,
        'verdes': 0.3
    },
    'ingles': {
        'castanos': 0.25,
        'miel': 0.25,
        'verdes': 0.25,
        'celestes': 0.25
    },
    'italiano': {
        'castanos': 0.4,
        'miel': 0.3,
        'verdes': 0.3
    },
    'nordico': {
        'celestes': 0.4,
        'verdes': 0.4,
        'grises': 0.2
    },
    'ruso': {
        'celestes': 0.4,
        'verdes': 0.4,
        'grises': 0.2
    },
    'germano': {
        'celestes': 0.2,
        'verdes': 0.2,
        'grises': 0.2,
        'miel': 0.2,
        'castanos': 0.16,
        'negros': 0.04
    },
    'yankee': {
        'celestes': 0.2,
        'verdes': 0.2,
        'miel': 0.2,
        'castanos': 0.2,
        'negros': 0.2
    }
}

COLOR_PELO = (
    ('castclaro', _(u"Castaño Claro")),
    ('castoscuro', _(u"Castaño Oscuro")),
    ('rojo', _(u"Rojo")),
    ('rubioclaro', _(u"Rubio Claro")),
    ('rubiooscuro', _(u"Rubio Oscuro")),
    ('negro', _(u"Negro")),
    ('gris', _(u"Gris")),
)

ETNIA_COLOR_PELO = {
    'afro': {
        'castoscuro': 0.5,
        'negro': 0.5
    },
    'arabe': {
        'castoscuro': 0.6,
        'negro': 0.4,
    },
    'brasil': {
        'castclaro': 0.2,
        'castoscuro': 0.2,
        'rubioclaro': 0.2,
        'rubiooscuro': 0.2,
        'negro': 0.2
    },
    'chino': {
        'negro': 1
    },
    'japones': {
        'negro': 0.8,
        'rojo': 0.2
    },
    'frances': {
        'castclaro': 0.2,
        'castoscuro': 0.2,
        'rubioclaro': 0.2,
        'rubiooscuro': 0.2,
        'rojo': 0.2
    },
    'hispano': {
        'castclaro': 0.2,
        'castoscuro': 0.2,
        'rubioclaro': 0.2,
        'rubiooscuro': 0.2,
        'rojo': 0.2
    },
    'ingles': {
        'castclaro': 0.25,
        'castoscuro': 0.125,
        'rubioclaro': 0.25,
        'rubiooscuro': 0.125,
        'rojo': 0.25
    },
    'italiano': {
        'castclaro': 0.2,
        'castoscuro': 0.2,
        'rubioclaro': 0.2,
        'rubiooscuro': 0.2,
        'rojo': 0.2
    },
    'nordico': {
        'rubioclaro': 0.5,
        'rojo': 0.4,
        'gris': 0.1
    },
    'ruso': {
        'rubioclaro': 0.5,
        'castclaro': 0.4,
        'gris': 0.1
    },
    'germano': {
        'rubioclaro': 0.5,
        'castclaro': 0.2,
        'rojo': 0.2,
        'negro': 0.1
    },
    'yankee': {
        'castclaro': 0.17,
        'castoscuro': 0.16,
        'rubioclaro': 0.17,
        'rubiooscuro': 0.16,
        'rojo': 0.17,
        'negro': 0.17,
    }
}

LARGO_PELO = (
    ('calvo', _(u'Calvo')),
    ('corto', _(u'Corto')),
    ('medio', _(u'Medio')),
    ('largo', _(u'Largo')),
)


def valid_middle_initial(l):
    if l not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
        raise ValidationError(_(u'Inicial no válida'))


def valid_optional_middle_initial(l):
    return not l or valid_middle_initial(l)


class EthnicNames(models.Model):
    ethnicity = models.CharField(max_length=8, null=False, choices=ETNIAS, db_index=True)
    name = models.CharField(max_length=20, null=False, db_index=True)
    gender = models.CharField(max_length=1, null=False, choices=GENDER)

    class Meta:
        unique_together = (('ethnicity', 'name', 'gender'),)


class EthnicSurnames(models.Model):
    ethnicity = models.CharField(max_length=8, null=False, choices=ETNIAS)
    surname = models.CharField(max_length=20, null=False)


class IdentityTraits(models.Model):
    ethnicity = models.CharField(max_length=8, null=False, choices=ETNIAS)
    skin = models.CharField(max_length=13, null=False, choices=PIEL)
    eyes_color = models.CharField(max_length=8, null=False, choices=OJOS)
    hair_color = models.CharField(max_length=11, null=False, choices=COLOR_PELO)
    hair_length = models.CharField(max_length=5, null=False, choices=LARGO_PELO)
    height = models.PositiveSmallIntegerField(null=False, choices=ALTURA)
    name = models.ForeignKey(EthnicNames, null=False)
    middle_initial = models.CharField(max_length=1, null=False, blank=True,
                                      validators=[valid_optional_middle_initial], db_index=True)
    surname = models.ForeignKey(EthnicSurnames, null=False)
    gender = models.CharField(max_length=1, null=False, choices=GENDER)

    def clean(self):
        if self.name.ethnicity != self.ethnicity or self.surname.ethnicity != self.ethnicity:
            raise ValidationError(_(u"El nombre y apellido deben ser de la etnia elegida"))

        if self.skin not in ETNIA_PIEL.get(self.ethnicity, {}):
            raise ValidationError(_(u"La estetica debe estar disponible para la etnia elegida"))

        if self.height not in ETNIA_ALTURA.get(self.ethnicity, ()):
            raise ValidationError(_(u"La altura debe estar disponible para la etnia elegida"))

        if self.eyes_color not in ETNIA_OJOS.get(self.ethnicity, ()):
            raise ValidationError(_(u"El color de ojos debe estar disponible para la etnia elegida"))

        if self.hair_color not in ETNIA_COLOR_PELO.get(self.ethnicity, ()):
            raise ValidationError(_(u"El color de pelo debe estar disponible para la etnia elegida"))

        if self.gender != self.name.gender:
            raise ValidationError(_(u"El género de la persona debe coincidir con el del nombre"))