import curses
from cursesmenu import CursesMenu
from cursesmenu.items import SelectionItem

'''
---------------------------------------------------------
Override cursesmenu.MenuItem.show to better suit
the menu options
---------------------------------------------------------
'''
def show( self, index ):
	return self.text


class MultiSelect(CursesMenu):
	"""
	A menu that simplifies item creation, just give it a list of strings and it builds the menu for you
	"""

	def __init__(self, strings, title=None, subtitle=None, show_exit_option=True):
		"""
		:ivar list[str] strings: The list of strings this menu should be built from
		"""
		super(MultiSelect, self).__init__(title, subtitle, show_exit_option)
		for index, item in enumerate(strings):
			self.append_item(SelectionItem(item, index, self))

	@classmethod
	def get_selection(cls, strings, title="Select an option", subtitle=None, exit_option=True, _menu=None):
		"""
		Single-method way of getting a selection out of a list of strings
		:param list[str] strings: the list of string used to build the menu
		:param list _menu: should probably only be used for testing, pass in a list and the created menu used \
		internally by the method will be appended to it
		"""
		menu = cls(strings, title, subtitle, exit_option)
		for item in menu.items:
			item.checked = False
			item.defaultText = item.text
			if item.defaultText != '← Return to Main Menu':
				item.text = '[ ] ' + item.defaultText
		if _menu is not None:
			_menu.append(menu)
		menu.show()
		menu.join()
		return menu.selected_option
	
	def draw(self):
		"""
		Redraws the menu and refreshes the screen. Should be called whenever something changes that needs to be redrawn.
		"""

		self.screen.border(0)
		if self.title is not None:
			self.screen.addstr(1, 2, self.title, curses.A_STANDOUT)
			buttonCount = "{0} Buttons Selected".format(len([ x.defaultText for x in self.items if x.checked ]))
			self.screen.addstr(1, len(self.title) + 4, "-", curses.A_BOLD)
			self.screen.addstr(1, len(self.title) + 7, buttonCount, curses.A_STANDOUT)
		if self.subtitle is not None:
			self.screen.addstr(2, 2, self.subtitle, curses.A_BOLD)
		
		instruction = ("[SPACEBAR]-Check/Uncheck Item "
							"[ENTER]-Continue")
		self.screen.addstr(3, 4, instruction, curses.A_BOLD)
		
		

		for index, item in enumerate(self.items):
			if self.current_option == index:
				text_style = self.highlight
			else:
				text_style = self.normal
			self.screen.addstr(5 + index, 4, item.show(index), text_style)

		screen_rows, screen_cols = CursesMenu.stdscr.getmaxyx()
		top_row = 0
		if 6 + len(self.items) > screen_rows:
			if screen_rows + self.current_option < 6 + len(self.items):
				top_row = self.current_option
			else:
				top_row = 6 + len(self.items) - screen_rows

		self.screen.refresh(top_row, 0, 0, 0, screen_rows - 1, screen_cols - 1)
		
	def select_many(self):
		"""
		Select multiple items
		"""
		
		if self.items[ self.current_option ].defaultText == '← Return to Main Menu':
			self.selected_option = [-1]
		else:
			self.selected_option = [ x.defaultText for x in self.items if x.checked ]
		self.selected_item.set_up()
		self.selected_item.action()
		self.selected_item.clean_up()
		self.returned_value = self.selected_item.get_return()
		self.should_exit = self.selected_item.should_exit

		if not self.should_exit:
			self.draw()
			
	def process_user_input(self):
		"""
		Gets the next single character and decides what to do with it
		"""
		user_input = self.get_input()

		go_to_max = ord("9") if len(self.items) >= 9 else ord(str(len(self.items)))

		if ord('1') <= user_input <= go_to_max:
			self.go_to(user_input - ord('0') - 1)
		elif user_input == curses.KEY_DOWN:
			self.go_down()
		elif user_input == curses.KEY_UP:
			self.go_up()
		elif user_input == ord(" "):
			if self.items[ self.current_option] .defaultText != '← Return to Main Menu':
				item = self.items[self.current_option]
				item.checked = not item.checked
				item.text = ('[X] ' if item.checked else '[ ] ') + item.defaultText
				self.items[self.current_option] = item
				self.draw()
		elif user_input in {curses.KEY_ENTER, 10, 13}:
			self.select_many()

		return user_input

	def append_string(self, string):
		self.append_item(SelectionItem(string))