# Path: magnate/ui/urwid/indexed_menu.py
# class IndexedMenuEnumerator(MutableMapping):
#     """
#     Generates new indexes for enumerating a menu and associates an index to
#     a vselection.
# 
#     A selection is used by calling code to tell which entry was selected via
#     a keypress
#     """
#     idx_names = [str(c) for c in itertools.chain(
#         range(1, 10),
#         [0],
#         (c for c in punctuation if c not in frozenset('(){}[]<>'))
#     )]
# 
#     def __init__(self):
#         self.association = {}
#         self.idx = 0
# 
#     def set_next(self, selection):
#         """
#         Adds a new selection to the IndexedMenuEnumerator, picking the new key
#         from the list of valid enumerations
# 
#         :arg selection: The value being set
#         :returns: The key that was picked
#         """
#         try:
#             key = self.idx_names[self.idx]
#         except IndexError:
#             raise IndexError('Not enough prefixes to enumerate all list entries')
#         self.idx += 1
#         self.association[key] = selection
#         return key
# 
#     def clear(self):
#         """
#         Clear the mapping
# 
#         In addition to normal dict behaviour, this also resets the next index back to the beginning
#         """
#         super().clear()
#         self.idx = 0
# 
#     def __setitem__(self, name, selection):
#         """Sets a key's value.
# 
#         :arg name: The key
#         :arg selection: The value
# 
#         .. warning:: Unlike dict, this cannot be used to set new keys.  Use
#             :meth:`set_next` instead.
#         """
#         if name not in self.association:
#             raise KeyError('Can only create new keys for an IndexedMenuEnumerator via set_next()')
#         self.association[name] = selection
# 
#     def __getitem__(self, name):
#         return self.association[name]
# 
#     def __delitem__(self, name):
#         del self.association[name]
# 
#     def __iter__(self):
#         return iter(self.association)
# 
#     def __len__(self):
#         return len(self.association)
# 
# class IndexedMenuButton(urwid.Button):
#     """A button without decorations"""
#     button_left = urwid.Text("")
#     button_right = urwid.Text("")


from functools import partial
from .indexed_menu import IndexedMenuEnumerator, IndexedMenuButton
import urwid



class TravelDisplay(urwid.WidgetWrap):
    """Widget that allows the user to select a new destination for the ship"""
    _selectable = True
    signals = ['close_travel_menu']

    def __init__(self, pubpen):
        self.pubpen = pubpen
        self.keypress_map = IndexedMenuEnumerator()
        self._ship_moved_sub_id = None

        self.listwalker = urwid.SimpleFocusListWalker([])
        box = urwid.ListBox(self.listwalker)
        outer_layout = urwid.LineBox(box, lline=None, blcorner='─',
                                     tlcorner='─', trcorner='\u252c',
                                     brcorner='\u2524')
        super().__init__(outer_layout)
        self.pubpen.subscribe('ship.destinations', self.handle_new_destinations)

    # pubpen event handlers

    def handle_new_destinations(self, locations):
        """Update the destination list when the ship can move to new places"""
        self.listwalker.clear()
        self.keypress_map = IndexedMenuEnumerator()
        #for idx, location in enumerate(locations):
        for location in locations:
            prefix = self.keypress_map.set_next(location)

# Path: magnate/ui/urwid/indexed_menu.py
# class IndexedMenuEnumerator(MutableMapping):
#     """
#     Generates new indexes for enumerating a menu and associates an index to
#     a vselection.
# 
#     A selection is used by calling code to tell which entry was selected via
#     a keypress
#     """
#     idx_names = [str(c) for c in itertools.chain(
#         range(1, 10),
#         [0],
#         (c for c in punctuation if c not in frozenset('(){}[]<>'))
#     )]
# 
#     def __init__(self):
#         self.association = {}
#         self.idx = 0
# 
#     def set_next(self, selection):
#         """
#         Adds a new selection to the IndexedMenuEnumerator, picking the new key
#         from the list of valid enumerations
# 
#         :arg selection: The value being set
#         :returns: The key that was picked
#         """
#         try:
#             key = self.idx_names[self.idx]
#         except IndexError:
#             raise IndexError('Not enough prefixes to enumerate all list entries')
#         self.idx += 1
#         self.association[key] = selection
#         return key
# 
#     def clear(self):
#         """
#         Clear the mapping
# 
#         In addition to normal dict behaviour, this also resets the next index back to the beginning
#         """
#         super().clear()
#         self.idx = 0
# 
#     def __setitem__(self, name, selection):
#         """Sets a key's value.
# 
#         :arg name: The key
#         :arg selection: The value
# 
#         .. warning:: Unlike dict, this cannot be used to set new keys.  Use
#             :meth:`set_next` instead.
#         """
#         if name not in self.association:
#             raise KeyError('Can only create new keys for an IndexedMenuEnumerator via set_next()')
#         self.association[name] = selection
# 
#     def __getitem__(self, name):
#         return self.association[name]
# 
#     def __delitem__(self, name):
#         del self.association[name]
# 
#     def __iter__(self):
#         return iter(self.association)
# 
#     def __len__(self):
#         return len(self.association)
# 
# class IndexedMenuButton(urwid.Button):
#     """A button without decorations"""
#     button_left = urwid.Text("")
#     button_right = urwid.Text("")


# Path: magnate/ui/urwid/travel_display.py
from functools import partial
from .indexed_menu import IndexedMenuEnumerator, IndexedMenuButton
import urwid




class TravelDisplay(urwid.WidgetWrap):
    """Widget that allows the user to select a new destination for the ship"""
    _selectable = True
    signals = ['close_travel_menu']

    def __init__(self, pubpen):
        self.pubpen = pubpen
        self.keypress_map = IndexedMenuEnumerator()
        self._ship_moved_sub_id = None

        self.listwalker = urwid.SimpleFocusListWalker([])
        box = urwid.ListBox(self.listwalker)
        outer_layout = urwid.LineBox(box, lline=None, blcorner='─',
                                     tlcorner='─', trcorner='\u252c',
                                     brcorner='\u2524')
        super().__init__(outer_layout)
        self.pubpen.subscribe('ship.destinations', self.handle_new_destinations)

    # pubpen event handlers

    def handle_new_destinations(self, locations):
        """Update the destination list when the ship can move to new places"""
        self.listwalker.clear()
        self.keypress_map = IndexedMenuEnumerator()
        #for idx, location in enumerate(locations):
        for location in locations:
            prefix = self.keypress_map.set_next(location)

            button = IndexedMenuButton('({}) {}'.format(prefix, location))