# -*- coding: utf-8 -*-
"""
Clement Michard (c) 2015
"""

class Emotion:
    """Defines an emotion."""
    
    emotions = {} # name to emotion (str -> Emotion)
    
    def __init__(self, name, parent_name=None):
        """Initializes an Emotion object.
            name -- name of the emotion (str)
            parent_name -- name of the parent emotion (str)
        """
        
        self.name = name
        self.parent = None
        self.level = 0
        self.children = []
        
        if parent_name:
            self.parent = Emotion.emotions[parent_name] if parent_name else None
            self.parent.children.append(self)
            self.level = self.parent.level + 1
            
            
    def get_level(self, level):
        """Returns the parent of self at the given level.
            level -- level in the hierarchy (int)        
        """
        
        em = self
        while em.level > level and em.level >= 0:
            em = em.parent
        return em
    
    
    def __str__(self):
        """Returns the emotion string formatted."""
        
        return self.name
        
        
    def nb_children(self):
        """Returns the number of children of the emotion."""
        
        return sum(child.nb_children() for child in self.children) + 1
        
        
    @staticmethod
    def printTree(emotion=None, indent="", last='updown'):
        """Prints the hierarchy of emotions.
            emotion -- root emotion (Emotion)
        """
        
        if not emotion:
            emotion = Emotion.emotions["root"]

        size_branch = {child: child.nb_children() for child in emotion.children}
        leaves = sorted(emotion.children, key=lambda emotion: emotion.nb_children())
        up, down = [], []
        if leaves:
            while sum(size_branch[e] for e in down) < sum(size_branch[e] for e in leaves):
                down.append(leaves.pop())
            up = leaves

        for leaf in up:     
            next_last = 'up' if up.index(leaf) is 0 else ''
            next_indent = '{0}{1}{2}'.format(indent, ' ' if 'up' in last else '│', " " * len(emotion.name))
            Emotion.printTree(leaf, indent=next_indent, last=next_last)
        if last == 'up':
            start_shape = '┌'
        elif last == 'down':
            start_shape = '└'
        elif last == 'updown':
            start_shape = ' '
        else:
            start_shape = '├'
        if up:
            end_shape = '┤'
        elif down:
            end_shape = '┐'
        else:
            end_shape = ''
        print ('{0}{1}{2}{3}'.format(indent, start_shape, emotion.name, end_shape))
        for leaf in down:
            next_last = 'down' if down.index(leaf) is len(down) - 1 else ''
            next_indent = '{0}{1}{2}'.format(indent, ' ' if 'down' in last else '│', " " * len(emotion.name))
            Emotion.printTree(leaf, indent=next_indent, last=next_last)





