import app.utils as utils


def char_width(char_matrix) -> int:
	"""Berechnung der Bits für die Zeichenbreite

	Args:
			char_matrix (int): Zeichen als Array[int]

	Returns:
			int: Anzahl Bits für die Zeichenbreite
	"""
	max_val = max(char_matrix)

	val = max_val
	cw = 0
	while 0xFFFFFFFF & val:
		"""rechts shiften, bis alles Nullen da sind"""
		val >>= 1
		cw += 1

	return cw


def font_height(font) -> int:
	"""Höhe in Pixeln eines Fonts

	Args:
			font ([int]): der Font für den die Höhe bestimmt wird

	Returns:
			int: Höhe in Pixeln
	"""

	# wir nehmen uns ein Zeichen des Fonts
	# die Anzahl der Werte entspricht der Höhe in Pixeln
	return len(font['a'])


def shift_letter_right(char, letter, debug=False) -> bool:
	"""Prüfe ob das Zeichen auch komplett nach rechts gezogen ist

	Args:
			letter (_type_): Array[0..nBytes]

	Returns:
			bool: _description_
	"""

	def isLetterRight(letter):
		def isByteRight(byte):
			return True if 1 & byte == 1 else False

		for byte in letter:
			if isByteRight(byte):
				return True

		return False

	def shiftLetterRight(letter):
		def shift(letter):
			return [byte >> 1 for byte in letter]

		shifted = letter
		for i in range(8):  # max 1 Bit's
			shifted = shift(shifted)
			if isLetterRight(shifted):
				break

		return shifted

	if isLetterRight(letter):
		return letter

	# letter is not right shifted
	shifted = shiftLetterRight(letter)

	if debug:
		print('origin:')
		utils.show_byte_matrix(char, letter)
		print('shifted')
		utils.show_byte_matrix(char, shifted)

	return shifted


def align_font(font, debug=False):
	chars = [char for char in font]
	print(chars)

	# Print the dictionary
	print('font_pretty = {')
	for char in sorted(font.keys()):
		shifted = shift_letter_right(char=char, letter=font[char], debug=debug)
		hex_values = [f'0x{val:02X}' for val in shifted]
		print(f"\t'{char}': [{', '.join(hex_values)}],")
	print('}')

	# return f'#keys: {len(list(font.keys()))}'
	return f'#keys: {len(font)}'


def screen_text(text: str, font, screen_height: int, screen_width: int):
	"""Text für einen Screen anpassen,
	Anzahl der Zeichen je Zeile begrenzen,
	ebenso wird die Höhe des Screen brücksichtigt


	Args:
			text (str): Text der ausgegeben werden soll
			font: Berechnungen für den Font
			height (int): Pixel
			width (int): Pixel
	"""

	def text_per_row(txt):
		pixs = 0
		visible_text = ''
		for a in txt:
			pixs += char_width(font[a]) + 1
			if pixs > screen_width:
				# Zeilenende erreicht
				break
			visible_text += a

		return visible_text

	f_height: int = font_height(font)
	# Ganzzahl Division
	max_visible_rows = screen_height // f_height
	print(f'rows_visible: {max_visible_rows}')

	text_left = text
	scn_txt = []
	for _ in range(max_visible_rows):
		visible_text = text_per_row(text_left)
		visible_text_len = len(visible_text)
		text_left = text_left[visible_text_len:]

		scn_txt.append(visible_text)

		if not text_left:
			break

	scr_txt_dict = {'visible': scn_txt, 'invisible': text_left}

	return scr_txt_dict
