import curses
from curses import panel

class BaseMenu:
    def __init__(self, stdscreen):
        self.window = stdscreen.subwin(0, 0)
        self.window.keypad(1)
        self.panel = panel.new_panel(self.window)
        self.panel.hide()
        panel.update_panels()

    def up(self):
        self.panel.top()
        self.panel.show()
        self.window.clear()
        
    def down(self):
        self.window.clear()
        self.panel.hide()
        panel.update_panels()
        curses.doupdate()

    def update(self):
        self.window.refresh()
        curses.doupdate()

class Menu(BaseMenu):
    def __init__(self, stdscreen, items):
        super().__init__(stdscreen)
        self.should_exit = False
        self.position = 0
        self.items = items
        self.items.append(('exit', self.exit))

    def exit(self):
        self.should_exit = True

    def navigate(self, offset):
        self.position += offset
        self.position %= len(self.items)

    def draw(self):
        for index, item in enumerate(self.items):
            text = '%d. %s' % (index + 1, item[0])
            text_mode = curses.A_REVERSE if index == self.position else curses.A_NORMAL
            self.window.addstr(index + 1, 1, text, text_mode)

    def get_selection(self, key):
        if key in [curses.KEY_ENTER, ord('\n')]:
            return self.items[self.position]
        elif (key - ord('0')) in range(1, len(self.items) + 1):
            return self.items[key - ord('0') - 1]
        else:
            return None

    def input(self):
        key = self.window.getch()
        selection = self.get_selection(key)

        if selection:
            selection[1]()

        if key == curses.KEY_UP:
            self.navigate(-1)
        elif key == curses.KEY_DOWN:
            self.navigate(1)

    def display(self):
        self.up()
        while not self.should_exit:
            self.update()
            self.draw()
            self.input()

        self.should_exit = False
        self.down()