from datetime import datetime


def deep_itemgetter(key):
    items = key.split('__')

    def g(obj):
        for name in items:
            obj = obj[name]
        return obj
    return g


class EventsBinder(object):

    def __init__(self, start_key, end_key, even=True):
        self.start_getter = deep_itemgetter(start_key)
        self.end_getter = deep_itemgetter(end_key)
        self.heap = []
        self.day_level_even = {}
        self.even = even

    def link_events(self, event1, event2):
        event1['relations'].add(event2['id'])
        event2['relations'].add(event1['id'])

    def bind(self, event):
        event['relations'] = set()
        lower_event = {'level': 0}
        for prev_event in self.heap:
            if self.end_getter(prev_event) > self.start_getter(event):
                self.link_events(prev_event, event)
                lower_event = prev_event
            else:
                break

        self.heap = self.heap[:lower_event['level']]
        self.heap.append(event)
        event['level'] = lower_event['level'] + 1

        if self.even:
            date = self.start_getter(event)
            if isinstance(date, datetime):
                date = date.date()
            day_level = date, event['level']
            self.day_level_even[day_level] = not self.day_level_even.get(day_level, False)
            event['is_even'] = self.day_level_even[day_level]
