# -*- coding: utf-8 -*-
from collections import namedtuple
from colour import Color
import datetime

breed_rule_list = {
    ('Plentiful', 'Plentiful'): (0.5, 0.5),
    ('Plentiful', 'Common'): (0.7, 0.3),
    ('Plentiful', 'Uncommon'): (0.85, 0.15),
    ('Plentiful', 'Limited'): (0.95, 0.05),
    ('Plentiful', 'Rare'): (0.99, 0.01),
    ('Common', 'Common'): (0.5, 0.5),
    ('Common', 'Uncommon'): (0.75, 0.25),
    ('Common', 'Limited'): (0.89, 0.11),
    ('Common', 'Rare'): (0.99, 0.01),
    ('Uncommon', 'Uncommon'): (0.5, 0.5),
    ('Uncommon', 'Limited'): (0.86, 0.14),
    ('Uncommon', 'Rare'): (0.98, 0.02),
    ('Limited', 'Limited'): (0.5, 0.5),
    ('Limited', 'Rare'): (0.97, 0.03),
    ('Rare', 'Rare'): (0.5, 0.5),
}
gene_rule_list = {
    ('Plentiful', 'Plentiful'): (0.5, 0.5),
    ('Plentiful', 'Common'): (0.7, 0.3),
    ('Plentiful', 'Uncommon'): (0.85, 0.15),
    ('Plentiful', 'Limited'): (0.95, 0.05),
    ('Plentiful', 'Rare'): (0.99, 0.01),
    ('Common', 'Common'): (0.5, 0.5),
    ('Common', 'Uncommon'): (0.75, 0.25),
    ('Common', 'Limited'): (0.92, 0.08),
    ('Common', 'Rare'): (0.99, 0.01),
    ('Uncommon', 'Uncommon'): (0.5, 0.5),
    ('Uncommon', 'Limited'): (0.85, 0.15),
    ('Uncommon', 'Rare'): (0.98, 0.02),
    ('Limited', 'Limited'): (0.5, 0.5),
    ('Limited', 'Rare'): (0.97, 0.03),
    ('Rare', 'Rare'): (0.5, 0.5),
}

odds_list = [
    ('Plentiful', '丰富'),
    ('Common', '常见'),
    ('Uncommon', '罕见'),
    ('Limited', '限定'),
    ('Rare', '稀有'),
]

gender_list = [
    ('Male', '雄性'),
    ('Female', '雌性'),
]

food_list = [
    ('Insects', '昆虫'),
    ('Meet', '肉类'),
    ('Seafood', '海鲜'),
    ('Plants', '植物'),
]

gene_type_list = [
    ('Primary', '第一基因'),
    ('Secondary', '第二基因'),
    ('Tertiary', '第三基因'),
]

element_list = [
    ('Arcane', '奥术'),
    ('Earth', '地'),
    ('Fire', '火'),
    ('Ice', '冰'),
    ('Light', '光'),
    ('Lightning', '电'),
    ('Nature', '自然'),
    ('Plague', '瘟疫'),
    ('Shadow', '影'),
    ('Water', '水'),
    ('Wind', '风'),
]

breed_odds_list = [
    ('Plentiful', 15),
    ('Common', 20),
    ('Uncommon', 25),
    ('Limited', 30),
    ('Rare', 35),
]

breed_list = [
    ('Fae', '精灵', 'Plentiful', ['Insects']),
    ('Guardian', '守卫', 'Plentiful', ['Insects', 'Meet', 'Seafood', 'Plants']),
    ('Tundra', '毛毛', 'Plentiful', ['Plants']),
    ('Mirror', '镜子', 'Plentiful', ['Meet', 'Seafood']),
    ('Pearlcatcher', '寻珠', 'Common', ['Insects', 'Plants']),
    ('Ridgeback', '脊背', 'Common', ['Seafood']),
    ('Snapper', '胖子', 'Common', ['Plants', 'Seafood']),
    ('Spiral', '圈圈', 'Common', ['Insects', 'Meet']),
    ('Skydancer', '天舞', 'Uncommon', ['Insects', 'Plants']),
    ('Imperial', '帝王', 'Limited', ['Insects', 'Meet', 'Seafood', 'Plants']),
    ('Nocturne', '夜曲', 'Limited', ['Meet', 'Insects']),
    ('Wildclaw', '野爪', 'Rare', ['Meet']),
    ('Coatl', '羽蛇', 'Rare', ['Seafood']),
]

primary_gene_list = [
    ('Basic', '基础', 'Plentiful'),
    ('Clown', '小丑', 'Common'),
    ('Piebald', '花斑', 'Common'),
    ('Speckle', '斑纹', 'Common'),
    ('Tiger', '虎纹', 'Common'),
    ('Bar', '条纹', 'Uncommon'),
    ('Cherub', '天使', 'Uncommon'),
    ('Ripple', '涟漪', 'Uncommon'),
    ('Vipera', '蛇纹', 'Uncommon'),
    ('Poison', '毒药', 'Limited'),
    ('Crystal', '水晶', 'Rare'),
    ('Iridescent', '渐变', 'Rare'),
]

secondary_gene_list = [
    ('Basic', '基础', 'Plentiful'),
    ('Current', '涌流', 'Common'),
    ('Daub', '', 'Common'),
    ('EyeSpots', '', 'Common'),
    ('Freckle', '雀斑', 'Common'),
    ('Paint', '', 'Common'),
    ('Peregrine', '', 'Common'),
    ('Stripes', '', 'Common'),
    ('Hypnotic', '', 'Uncommon'),
    ('Seraph', '', 'Uncommon'),
    ('Toxin', '毒雾', 'Limited'),
    ('Facet', '侧面', 'Rare'),
    ('Shimmer', '闪烁', 'Rare'),
]

tertiary_gene_list = [
    ('Basic', '基础', 'Plentiful'),
    ('Underbelly', '腹部', 'Common'),
    ('Crackle', '裂纹', 'Uncommon'),
    ('Okapi', '㺢㹢狓', 'Uncommon'),
    ('Smoke', '烟纹', 'Uncommon'),
    ('Gembond', '宝石', 'Limited'),
    ('Spines', '脊刺', 'Limited'),
    ('Circuit', '电路', 'Rare'),
    ('Glimmer', '闪光', 'Rare'),
]

color_list = [
    ('Maize', '玉米色', '#FFFDEA'),
    ('White', '白色', '#FFFFFF'),
    ('Ice', '冰蓝', '#F1F3FF'),
    ('Platinum', '银灰', '#C8BECE'),
    ('Silver', '银色', '#BBBABF'),
    ('Grey', '灰色', '#808080'),
    ('Charcoal', '炭灰', '#545454'),
    ('Coal', '煤黑', '#4B4946'),
    ('Black', '黑色', '#333333'),
    ('Obsidian', '黑曜', '#1D2224'),
    ('Midnight', '午夜黑', '#292B38'),
    ('Shadow', '黯色', '#392D43'),
    ('Mulberry', '紫红色', '#545454'),
    ('Thistle', '蓟紫', '#8F7C8B'),
    ('Lavender', '淡紫', '#CCA4E0'),
    ('Purple', '紫色', '#A261CF'),
    ('Violet', '紫罗兰', '#643F9C'),
    ('Royal', '宝蓝', '#4D2C89'),
    ('Storm', '风暴蓝', '#757ADB'),
    ('Navy', '藏青', '#212B5F'),
    ('Blue', '蓝色', '#324BA9'),
    ('Splash', '泼蓝', '#6394DD'),
    ('Sky', '天蓝', '#AEC8FF'),
    ('Stonewash', '石磨蓝', '#7895C1'),
    ('Steel', '钢青', '#556979'),
    ('Denim', '牛仔布蓝', '#2F4557'),
    ('Azure', '湛蓝', '#0A3D67'),
    ('Caribbean', '加勒比蓝', '#0086CE'),
    ('Teal', '鸭绿', '#2B768F'),
    ('Aqua', '水色', '#72C4C4'),
    ('Seafoam', '水蓝', '#B2E2BD'),
    ('Jade', '碧绿', '#61AB89'),
    ('Emerald', '翠绿', '#20603F'),
    ('Jungle', '丛林绿', '#1E361A'),
    ('Forest', '森林绿', '#425035'),
    ('Swamp', '沼泽绿', '#687F67'),
    ('Avocado', '鳄梨色', '#567C34'),
    ('Green', '绿色', '#629C3F'),
    ('Leaf', '叶绿', '#A5E32D'),
    ('Spring', '春绿', '#A9A032'),
    ('Goldenrod', '金桔色', '#BEA55D'),
    ('Lemon', '柠檬', '#FFE63B'),
    ('Banana', '蕉黄', '#FFEC80'),
    ('Ivory', '象牙', '#FFD297'),
    ('Gold', '金色', '#E8AF49'),
    ('Sunshine', '阳光色', '#FA912B'),
    ('Orange', '橘色', '#D5602B'),
    ('Fire', '火红', '#EF5C23'),
    ('Tangerine', '橙黄', '#FF7360'),
    ('Sand', '沙色', '#B27749'),
    ('Beige', '米色', '#CABBA2'),
    ('Stone', '石灰', '#827A64'),
    ('Slate', '岩灰', '#564D48'),
    ('Soil', '泥色', '#5A4534'),
    ('Brown', '褐色', '#8E5B3F'),
    ('Chocolate', '巧克力色', '#563012'),
    ('Rust', '锈红', '#8B3220'),
    ('Tomato', '蕃茄红', '#BA311C'),
    ('Crimson', '深茜红', '#850012'),
    ('Blood', '血色', '#451717'),
    ('Maroon', '栗色', '#652127'),
    ('Red', '红色', '#C1272D'),
    ('Carmine', '胭脂红', '#B13A3A'),
    ('Coral', '珊瑚红', '#CC6F6F'),
    ('Magenta', '洋红', '#E934AA'),
    ('Pink', '粉红', '#E77FBF'),
    ('Rose', '玫瑰色', '#FFD6F6'),
]

dragon_list = [
    (18543145, 'YouTi', 'Male', '2015/11/19', 'Mirror', 'Ice', 'Basic', 'Basic', 'Basic', 'Sky', 'Black', 'Maize'),
    (18543146, 'FanNa', 'Female', '2015/11/19', 'Fae', 'Ice', 'Basic', 'Basic', 'Basic', 'Crimson', 'Mulberry', 'Denim'),

    (18686818, 'HeiJingZi', 'Female', '2015/11/24', 'Mirror', 'Ice', 'Basic', 'Basic', 'Basic', 'Navy', 'Shadow', 'Black'),

    (18581573, 'ZhangSan', 'Male', '2015/11/20', 'Ridgeback', 'Lightning', 'Iridescent', 'Shimmer', 'Smoke', 'Silver', 'Teal', 'Steel'),
    (18574362, 'LiSi', 'Female', '2015/11/20', 'Pearlcatcher', 'Fire', 'Crystal', 'Current', 'Basic', 'Fire', 'Rose', 'Ivory'),

    (18614948, 'TiYi', 'Female', '2015/11/21', 'Tundra', 'Light', 'Iridescent', 'Shimmer', 'Crackle', 'Royal', 'Coal', 'Platinum'),
    (18701932, 'TiYiBan', 'Male', '2015/11/24', 'Pearlcatcher', 'Water', 'Speckle', 'Freckle', 'Crackle', 'Navy', 'White', 'Maize'),
    (18674452, 'TiYiSan', 'Male', '2015/11/23', 'Guardian', 'Nature', 'Crystal', 'Shimmer', 'Crackle', 'Navy', 'White', 'Maize'),

    (18589819, 'Carboxyl', 'Male', '2015/11/20', 'Guardian', 'Light', 'Basic', 'Basic', 'Basic', 'Tomato', 'Banana', 'Coal'),
    (18579831, 'Sulfo', 'Female', '2015/11/20', 'Coatl', 'Shadow', 'Ripple', 'EyeSpots', 'Smoke', 'Teal', 'Forest', 'Thistle'),
    (18549072, 'Oxhydryl', 'Male', '2015/11/19', 'Nocturne', 'Nature', 'Basic', 'Paint', 'Underbelly', 'Steel', 'Royal', 'Lemon'),
    (18635729, 'Chlor', 'Female', '2015/11/21', 'Skydancer', 'Earth', 'Piebald', 'Paint', 'Underbelly', 'Pink', 'Maroon', 'Banana'),
    (18598076, 'Nitryl', 'Male', '2015/11/20', 'Imperial', 'Nature', 'Crystal', 'Facet', 'Spines', 'Coral', 'Purple', 'Lavender'),

    (18687225, 'CaoQuan', 'Male', '2015/11/24', 'Spiral', 'Light', 'Iridescent', 'Shimmer', 'Gembond', 'Thistle', 'Midnight', 'Thistle'),

    (18503930, 'Orpheus', 'Male', '2015/11/18', 'Fae', 'Light', 'Basic', 'Basic', 'Basic', 'Maize', 'Lemon', 'Leaf'),
    (18503930, 'Citrus', 'Female', '2015/11/18', 'Tundra', 'Light', 'Basic', 'Basic', 'Basic', 'Fire', 'Leaf', 'Emerald'),
]


class Item(object):

    def __init__(self, name, name_zh):
        self.name = name
        self.name_zh = name_zh

    def __str__(self):
        return '%s' % self.name_zh if self.name_zh else self.name


class Odds(Item):
    pass


class Gender(Item):
    pass


class GeneType(Item):
    pass


class Element(Item):
    pass


class Food(Item):
    pass


class BreedOdds(Odds):

    def __init__(self, odds, cooldown):
        super(self.__class__, self).__init__(odds.name, odds.name_zh)
        self.cooldown = cooldown


class Breed(Item):

    def __init__(self, name, name_zh, odds, diet):
        super(self.__class__, self).__init__(name, name_zh)
        self.odds = odds
        self.diet = diet


class Gene(Item):

    def __init__(self, name, name_zh, odds, type):
        super(Gene, self).__init__(name, name_zh)
        self.odds = odds
        self.type = type


class PrimaryGene(Gene):

    def __init__(self, name, name_zh, odds):
        super(self.__class__, self).__init__(
            name, name_zh, odds, GeneType.Primary)


class SecondaryGene(Gene):

    def __init__(self, name, name_zh, odds):
        super(self.__class__, self).__init__(
            name, name_zh, odds, GeneType.Secondary)


class TertiaryGene(Gene):

    def __init__(self, name, name_zh, odds):
        super(self.__class__, self).__init__(
            name, name_zh, odds, GeneType.Tertiary)


class DragonColor(Item):
    Colors = []

    def __init__(self, name, name_zh, color):
        super(self.__class__, self).__init__(name, name_zh)
        self.color = color
        DragonColor.Colors.append(self)

    @staticmethod
    def Count():
        return len(DragonColor.Colors)

    @property
    def id(self):
        return DragonColor.Colors.index(self) + 1


class Role(object):
    BreedRoles = {}
    GeneRoles = {}


class Dragon(object):
    Dragons = []

    def __init__(self,
                 id=0,
                 name=None,
                 gender=None,
                 hachday=None,
                 breed=None,
                 element=None,
                 primaryGene=None,
                 secondaryGene=None,
                 tertiaryGene=None,
                 primaryColor=None,
                 secondaryColor=None,
                 tertiaryColor=None):
        self.id = id
        self.name = name
        self.gender = gender
        self.hachday = hachday
        self.breed = breed
        self.element = element
        self.primaryGene = primaryGene
        self.secondaryGene = secondaryGene
        self.tertiaryGene = tertiaryGene
        self.primaryColor = primaryColor
        self.secondaryColor = secondaryColor
        self.tertiaryColor = tertiaryColor
        Dragon.Dragons.append(self)

    @staticmethod
    def Count():
        return len(DragonColor.Colors)

    def __str__(self):
        return ''' %s %s
 #%s
 %s %s龙
----------
 %s\t%s
 %s\t%s
 %s\t%s
''' % (self.name, self.gender_icon, self.id,  self.breed.name_zh, self.element.name_zh,
            self.primaryGene, self.primaryColor.name_zh,
            self.secondaryGene, self.secondaryColor.name_zh,
            self.tertiaryGene, self.tertiaryColor.name_zh)

    @property
    def gender_icon(self):
        return '♂' if self.gender is Gender.Male else '♀'


for name, name_zh in odds_list:
    setattr(Odds, name, Odds(name, name_zh))

for name, name_zh in gender_list:
    setattr(Gender, name, Gender(name, name_zh))

for name, name_zh in gene_type_list:
    setattr(GeneType, name, GeneType(name, name_zh))

for name, name_zh in element_list:
    setattr(Element, name, Element(name, name_zh))

for name, name_zh in food_list:
    setattr(Food, name, Food(name, name_zh))

for name, cooldown in breed_odds_list:
    setattr(BreedOdds, name, BreedOdds(getattr(Odds, name), cooldown))

for name, name_zh, odds, diet_list in breed_list:
    diet = [getattr(Food, food) for food in diet_list]
    setattr(Breed, name, Breed(name, name_zh, getattr(BreedOdds, odds), diet))

for name, name_zh, odds in primary_gene_list:
    setattr(PrimaryGene, name, PrimaryGene(name, name_zh, getattr(Odds, odds)))

for name, name_zh, odds in secondary_gene_list:
    setattr(SecondaryGene, name, SecondaryGene(
        name, name_zh, getattr(Odds, odds)))

for name, name_zh, odds in tertiary_gene_list:
    setattr(TertiaryGene, name, TertiaryGene(
        name, name_zh, getattr(Odds, odds)))

for name, name_zh, color in color_list:
    setattr(DragonColor, name, DragonColor(name, name_zh, Color(color)))


for key, value in breed_rule_list.items():
    key1, key2 = key
    odds1, odds2 = getattr(BreedOdds, key1), getattr(BreedOdds, key2)
    value1, value2 = value
    if not (odds1, odds2) in Role.BreedRoles:
        Role.BreedRoles[(odds1, odds2)] = (value1, value2)
    if not (odds2, odds1) in Role.BreedRoles:
        Role.BreedRoles[(odds2, odds1)] = (value2, value1)

for key, value in gene_rule_list.items():
    key1, key2 = key
    odds1, odds2 = getattr(Odds, key1), getattr(Odds, key2)
    value1, value2 = value
    if not (odds1, odds2) in Role.GeneRoles:
        Role.GeneRoles[(odds1, odds2)] = (value1, value2)
    if not (odds2, odds1) in Role.GeneRoles:
        Role.GeneRoles[(odds2, odds1)] = (value2, value1)

for id, name, gender, hachday_str, breed, element, primaryGene, secondaryGene, tertiaryGene, primaryColor, secondaryColor, tertiaryColor in dragon_list:
    year, month, day = hachday_str.split('/')
    setattr(Dragon, name, Dragon(
        id=id,
        name=name,
        gender=getattr(Gender, gender),
        hachday=datetime.datetime(int(year), int(month), int(day)),
        breed=getattr(Breed, breed),
        element=getattr(Element, element),
        primaryGene=getattr(PrimaryGene, primaryGene),
        secondaryGene=getattr(SecondaryGene, secondaryGene),
        tertiaryGene=getattr(TertiaryGene, tertiaryGene),
        primaryColor=getattr(DragonColor, primaryColor),
        secondaryColor=getattr(DragonColor, secondaryColor),
        tertiaryColor=getattr(DragonColor, tertiaryColor),
    ))


def GetColorRange(color1, color2):
    if isinstance(color1, DragonColor) and isinstance(color2, DragonColor):
        if color1 is color2:
            return [color1]
        small, big = (color1, color2) if color1.id < color2.id else (
            color2, color1)
        left, center, right = DragonColor.Colors[0:small.id - 1], DragonColor.Colors[
            small.id: big.id - 1], DragonColor.Colors[big.id:]

        if big.id - small.id < DragonColor.Count() / 2.0:
            return [small] + center + [big]
        else:
            return [big] + right + left + [small]
    else:
        return None


def GetBreedRate(breed1, breed2):
    if isinstance(breed1, Breed) and isinstance(breed2, Breed):
        if breed1 is breed2:
            return {
                breed1: 1
            }
        if (breed1.odds, breed2.odds) in Role.BreedRoles:
            rate1, rate2 = Role.BreedRoles[breed1.odds, breed2.odds]
            return {
                breed1: rate1,
                breed2: rate2
            }
    return None


def GetGeneRate(gene1, gene2):
    if type(gene1) is type(gene2) and isinstance(gene1, Gene):
        if gene1 is gene2:
            return {
                gene1: 1
            }
        if (gene1.odds, gene2.odds) in Role.GeneRoles:
            rate1, rate2 = Role.GeneRoles[gene1.odds, gene2.odds]
            return {
                gene1: rate1,
                gene2: rate2
            }
    return None


def GetBreed(dragon1, dragon2):
    if isinstance(dragon1, Dragon) and isinstance(dragon2, Dragon):
        if dragon1.gender is dragon2.gender:
            return False, '同性恋是不会下蛋的！'
        result = {
            'dragons': [dragon1, dragon2],
            'breed': GetBreedRate(dragon1.breed, dragon2.breed),
            'primaryColor': GetColorRange(dragon1.primaryColor, dragon2.primaryColor),
            'secondaryColor': GetColorRange(dragon1.secondaryColor, dragon2.secondaryColor),
            'tertiaryColor': GetColorRange(dragon1.tertiaryColor, dragon2.tertiaryColor),
            'primaryGene': GetGeneRate(dragon1.primaryGene, dragon2.primaryGene),
            'secondaryGene': GetGeneRate(dragon1.secondaryGene, dragon2.secondaryGene),
            'tertiaryGene': GetGeneRate(dragon1.tertiaryGene, dragon2.tertiaryGene),
        }
        return True, result
    return False, '这里面有东西不是龙吧！'


def printBreedResult(result):
    for dragon in result['dragons']:
        print dragon.name, dragon.gender_icon, '\t',
    print
    print '=====品种====='
    for breed, rate in result['breed'].items():
        print breed, rate * 100, '%',
    print
    print '====第一基因===='
    for primaryGene, rate in result['primaryGene'].items():
        print primaryGene, rate * 100, '%',
    print
    for color in result['primaryColor']:
        print color,
    print
    print '====第二基因===='
    for secondaryGene, rate in result['secondaryGene'].items():
        print secondaryGene, rate * 100, '%',
    print
    for color in result['secondaryColor']:
        print color,
    print
    print '====第三基因===='
    for tertiaryGene, rate in result['tertiaryGene'].items():
        print tertiaryGene, rate * 100, '%',
    print
    for color in result['tertiaryColor']:
        print color,
    print


def calRate(result, target):
    rate = 1.0
    if 'gender' in target:
        rate *= 0.5
    if 'breed' in target:
        if target['breed'] in result['breed']:
            rate *= result['breed'][target['breed']]
        else:
            return 0
    if 'primaryColor' in target:
        if target['primaryColor'] in result['primaryColor']:
            rate /= len(result['primaryColor'])
        else:
            return 0
    if 'secondaryColor' in target:
        if target['secondaryColor'] in result['secondaryColor']:
            rate /= len(result['secondaryColor'])
        else:
            return 0
    if 'tertiaryColor' in target:
        if target['tertiaryColor'] in result['tertiaryColor']:
            rate /= len(result['tertiaryColor'])
        else:
            return 0
    if 'primaryGene' in target:
        if target['primaryGene'] in result['primaryGene']:
            rate *= result['primaryGene'][target['primaryGene']]
        else:
            return 0
    if 'secondaryGene' in target:
        if target['secondaryGene'] in result['secondaryGene']:
            rate *= result['secondaryGene'][target['secondaryGene']]
        else:
            return 0
    if 'tertiaryGene' in target:
        if target['tertiaryGene'] in result['tertiaryGene']:
            rate *= result['tertiaryGene'][target['tertiaryGene']]
        else:
            return 0
    return rate


status, result = GetBreed(Dragon.TiYi, Dragon.TiYiBan)
status1, result1 = GetBreed(Dragon.TiYi, Dragon.TiYiSan)

target = {
    'gender': Gender.Female,
    'breed': Breed.Tundra,
    'tertiaryGene': TertiaryGene.Crackle,
    'primaryColor': DragonColor.Navy,
    'secondaryColor': DragonColor.White,
    'tertiaryColor': DragonColor.Ice
}
# print Dragon.TiYi
# print Dragon.TiYiBan
# print Dragon.TiYiSan

# if status:
#     printBreedResult(result)
#     print '几率：%s' % (calRate(result, target) * 100), '%'
#     print

# if status1:
#     printBreedResult(result1)
#     print '几率：%s' % (calRate(result1, target) * 100), '%'

status, result = GetBreed(Dragon.Oxhydryl, Dragon.Sulfo)
if status:
    printBreedResult(result)
else:
    print result
