import display, badge, buttons, time, samd, system, errno, math
from turtle_game.turtlegame import *

def play_sound(played_sound):
	sounds = ["treasure found",[4,1,0,1,4,1,4,1,0,1,4,1,4,1,0,1,4,1,4,1,0,1,5,1,6,1,0,1,5,1,6,1,0,1,5,1,6,1,0,1,5,1,6,1,0,1,5,1,4,2],
				"turn left",[1,1,0,1,1,1,0,1,1,1,0,1],
				"turn right",[3,1,0,1,5,1,0,1,4,1,0,1],
				"move ahead",[1,4,0,1,1,4,0,1],
				"fire laser",[3,4,2,3,1,2,0,1],
				"undo",[1,4,0,1],
				"menu",[1,1,0,1]]

	notes=sounds[sounds.index(played_sound)+1]
	i=0
	while i < len(notes)/2:
		fr = notes[i*2]
		t = notes[i*2+1]
		samd.buzzer(fr, t)
		time.sleep(t*0.0625)
		i = i + 1


def load_level_status():
	global level_status
	exc=int()
	try:
		myfile=open("/lib/turtle_game/levstat.txt")
	except OSError as exc:
		if exc.args[0]==errno.ENOENT:
			level_status=default_level_status
			save_level_status()
			return
	level_status=myfile.read().replace("[","").replace("]","").split(",")
	myfile.close()
	for i in range(0, len(level_status)): 
		level_status[i] = int(level_status[i]) 

def save_level_status():
	myfile=open("/lib/turtle_game/levstat.txt","w")
	myfile.write(str(level_status))
	myfile.close()

def set_theme(mytheme):
	global background_color, foreground_color, theme
	theme=mytheme
	if theme=="light":
		background_color=0xFFFFFF
		foreground_color=0
	else:
		background_color=0
		foreground_color=0xFFFFFF

def init_mywindow(mywindowname, mywidth, myheight, pos_x=0, pos_y=0, framed=False):
	try:
		display.windowCreate(mywindowname,mywidth,myheight)
	except ValueError as err:
		if err:
			pass
		else:
			print(err)
	display.drawFill(mywindowname, background_color)
	if framed:
		display.drawRect(mywindowname,0,0,mywidth,myheight,no_fill,foreground_color)
	display.windowMove(mywindowname,pos_x, pos_y)

def level_selection_menu():

	def disable_text(x,y):
		for j in range(64):
			for i in range(26):
				if (i%3!=0 and j%3!=1):
					display.drawPixel("menubar",x+i,y+j,background_color)


	def display_stars(level):
		best_score_percentage=level_status[(level-1)*3+1]/level_status[(level-1)*3+2]
		display.drawPng("menubar",32*(level-1)+3,28,"/lib/turtle_game/cf_12px_" + theme + ".png")
		if best_score_percentage>.75:
			display.drawPng("menubar",32*(level-1)+10,28,"/lib/turtle_game/cf_12px_" + theme + ".png")
		else:
			display.drawPng("menubar",32*(level-1)+10,28,"/lib/turtle_game/ce_12px_" + theme + ".png")
		if best_score_percentage>.95:
			display.drawPng("menubar",32*(level-1)+17,28,"/lib/turtle_game/cf_12px_" + theme + ".png")
		else:
			display.drawPng("menubar",32*(level-1)+17,28,"/lib/turtle_game/ce_12px_" + theme + ".png")

	def display_selection(current, previous):
		current_page=math.ceil(current/4)
		current_selection_on_page=(current-1)%4
		previous_page=math.ceil(previous/4)
		previous_selection_on_page=(previous-1)%4
		start_on_screen=(current_page-1)*128
		display.drawRect("menubar",start_on_screen+2+previous_selection_on_page*32,1,28,25,False,background_color)
		if current_page!=previous_page:
			display.windowMove("menubar",-1*start_on_screen,0)
		display.drawRect("menubar",start_on_screen+2+current_selection_on_page*32,1,28,25,False,foreground_color)
		display.flush()


	def draw_menu():
		nonlocal max_selectable_level
		for i in range(1,13):
			levelnumbertext=str(i)
			if i<10:
				if i%4==0:
					display.drawText("menubar",32*(i-1)+8,50,">>",foreground_color,"Roboto_Regular12")
				elif i>1 and i%4==1:
					display.drawText("menubar",32*(i-1)+8,50,"<<",foreground_color,"Roboto_Regular12")
				display.drawText("menubar",32*(i-1)+8,0,levelnumbertext,foreground_color,"Roboto_Regular22")
			else:
				display.drawText("menubar",32*(i-1)+1,0,levelnumbertext,foreground_color,"Roboto_Regular22")
			if i>1:
				if level_status[(i-2)*3+2]==0:
					disable_text(32*(i-1)+1,0)
				else:
					max_selectable_level=i
				if level_status[(i-2)*3+2]>0:
					display_stars(i-1)
				if i==12 and level_status[(i-1)*3+2]>0:
					display_stars(i)
			else:
				max_selectable_level=1
		if max_selectable_level==12 and level_status[(12-1)*3+2]>0:
			pass
		else:
			display.drawText("menubar",32*(max_selectable_level-1)+3,28,"New!",foreground_color,myfont)


	def level_selection_menu_action_right(pressed):
		nonlocal current_selection
		if not pressed:
			return
		badge.led(4,1,1,0)
		time.sleep(.1)
		if sound_on: play_sound("menu")
		badge.led(4,0,0,0)
		if current_selection<max_selectable_level:
			current_selection+=1
			display_selection(current_selection, current_selection-1)
	
	def level_selection_menu_action_left(pressed):
		nonlocal current_selection
		if not pressed:
			return
		badge.led(4,1,0,1)
		time.sleep(.1)
		if sound_on: play_sound("menu")
		badge.led(4,0,0,0)
		if current_selection>1:
			current_selection-=1
			display_selection(current_selection, current_selection+1)


	def level_selection_menu_action_down(pressed):
		nonlocal exit_from_selection_menu
		if not pressed:
			return
		badge.led(1,1,1,1)
		time.sleep(.1)
		if sound_on: play_sound("menu")
		badge.led(1,0,0,0)	
		detach_level_selection_menu_actions_from_buttons()
		display.windowHide("menubar")
		display.windowHide("back_sign")
		exit_from_selection_menu=True
		
	
	def level_selection_menu_action_enter(pressed):
		nonlocal selected_level
		if not pressed:
			return
		badge.led(3,1,0,0)
		time.sleep(.1)
		if sound_on: play_sound("menu")
		badge.led(3,0,0,0)
		detach_level_selection_menu_actions_from_buttons()
		selected_level=current_selection
		

	def detach_level_selection_menu_actions_from_buttons():
		buttons.detach(buttons.BTN_LEFT)
		buttons.detach(buttons.BTN_RIGHT)
		buttons.detach(buttons.BTN_DOWN)
		buttons.detach(buttons.BTN_OK)

	def attach_level_selection_menu_actions_to_buttons():
		buttons.attach(buttons.BTN_LEFT, level_selection_menu_action_left)
		buttons.attach(buttons.BTN_RIGHT, level_selection_menu_action_right)
		buttons.attach(buttons.BTN_DOWN, level_selection_menu_action_down)
		buttons.attach(buttons.BTN_OK, level_selection_menu_action_enter)

	def display_centered_message(window, text, pos_y, color, font):
		mytextwidth=display.getTextWidth(text,font)
		mywindowwidth=display.width(window)
		display.drawText(window,int((mywindowwidth-mytextwidth)/2),pos_y,text,color,font)

	display.drawFill("menubar", background_color)
	display.drawFill("back_sign", background_color)
	display.windowShow("menubar")
	display.windowShow("back_sign")
	display_centered_message("back_sign","Hit V for\r\nmain menu",7,foreground_color,"7x5")

	global level_status
	max_selectable_level=0
	current_selection=1
	selected_level=0
	level_completed_steps=0
	exit_from_selection_menu=False

	draw_menu()
	display_selection(current_selection, current_selection)
	attach_level_selection_menu_actions_to_buttons()
	while True:
		if selected_level>0:
			detach_level_selection_menu_actions_from_buttons()
			level_completed_steps=turtlegame.play_game(selected_level, theme,sound_on)
			if level_completed_steps>0:
				if level_status[(selected_level-1)*3+2]==0\
				or level_completed_steps<level_status[(selected_level-1)*3+2]:
					level_status[(selected_level-1)*3+2]=level_completed_steps
					save_level_status()
			draw_menu()
			display_selection(current_selection,current_selection)
			attach_level_selection_menu_actions_to_buttons()
			selected_level=0
		if exit_from_selection_menu:
			detach_level_selection_menu_actions_from_buttons()
			display.windowHide("menubar")
			display.windowHide("back_sign")
			break
	main_menu()
	
def settings_menu():
	
	def display_settings_menu():
		display.drawFill("settings_menu",background_color)
		for i in range(len(menuitems)):
			display_settings_menuitem(i, False)

	def display_settings_menuitem(index, selected):
		if selected:
			display.drawRect("settings_menu",0,0+index*15,127,15,fill,foreground_color)
			display.drawText("settings_menu",0,0+index*15,menuitems[index][0],background_color,myfont)
			display.drawText("settings_menu",50,0+index*15,menuitems[index][1],background_color,myfont)
			display.drawText("settings_menu",90,0+index*15,menuitems[index][2],background_color,myfont)
		else:
			display.drawRect("settings_menu",0,0+index*15,127,15,fill,background_color)
			display.drawText("settings_menu",0,0+index*15,menuitems[index][0],foreground_color,myfont)
			display.drawText("settings_menu",50,0+index*15,menuitems[index][1],foreground_color,myfont)
			display.drawText("settings_menu",90,0+index*15,menuitems[index][2],foreground_color,myfont)
		display.flush()
		
	def settings_menu_action_up(pressed):
		nonlocal current_settings_selection
		if not pressed:
			return
		badge.led(1,1,1,0)
		time.sleep(.1)
		if sound_on: play_sound("menu")
		badge.led(1,0,0,0)
		if current_settings_selection>0:
			display_settings_menuitem(current_settings_selection,False)
			current_settings_selection-=1
			display_settings_menuitem(current_settings_selection,True)
			
	def settings_menu_action_down(pressed):
		nonlocal current_settings_selection
		if not pressed:
			return
		badge.led(1,1,0,1)
		time.sleep(.1) 
		if sound_on: play_sound("menu")
		badge.led(1,0,0,0)
		if current_settings_selection<len(menuitems)-1:
			display_settings_menuitem(current_settings_selection,False)
			current_settings_selection+=1
			display_settings_menuitem(current_settings_selection,True)

	def settings_menu_action_enter(pressed):
		global sound_on, level_status
		nonlocal exit_to_main_menu
		if not pressed:
			return
		badge.led(3,1,0,0)
		time.sleep(.1)
		if sound_on: play_sound("menu")
		badge.led(3,0,0,0)

		if current_settings_selection<2:
			if menuitems[current_settings_selection][3]:
				menuitems[current_settings_selection][1]=menuitems[current_settings_selection][1].lower()
				menuitems[current_settings_selection][2]=menuitems[current_settings_selection][2].upper()
			else:
				menuitems[current_settings_selection][1]=menuitems[current_settings_selection][1].upper()
				menuitems[current_settings_selection][2]=menuitems[current_settings_selection][2].lower()
			if current_settings_selection==0:
				sound_on=not sound_on
			if current_settings_selection==1:
				if theme=="dark":
					set_theme("light")
				else:
					set_theme("dark")
				display_settings_menu()
			menuitems[current_settings_selection][3]=not menuitems[current_settings_selection][3]
			display_settings_menuitem(current_settings_selection, True)
		elif current_settings_selection==2:
			for i in range(len(level_status)):
				level_status[i]=default_level_status[i]
			save_level_status()
			display.drawFill("settings_menu",background_color)
			display.drawText("settings_menu",15,30,"Level stats reset!",foreground_color,myfont)
			display.flush()
			time.sleep(2)
			display_settings_menu()
			display_settings_menuitem(current_settings_selection, True)
		elif current_settings_selection==3:
			exit_to_main_menu=True

	def detach_settings_menu_actions_from_buttons():
		buttons.detach(buttons.BTN_UP)
		buttons.detach(buttons.BTN_DOWN)
		buttons.detach(buttons.BTN_OK)

	def attach_settings_menu_actions_to_buttons():
		buttons.attach(buttons.BTN_UP, settings_menu_action_up)
		buttons.attach(buttons.BTN_DOWN, settings_menu_action_down)
		buttons.attach(buttons.BTN_OK, settings_menu_action_enter)

	menuitems=[["Sound:","on","off",False],["Theme:","light","dark",False],["Reset levels:","","yes",False],["Return to main menu","","",False]]
	if sound_on:
		menuitems[0][1]=menuitems[0][1].upper()
	else:
		menuitems[0][2]=menuitems[0][2].upper()
	menuitems[0][3]=sound_on
	if theme=="light":
		menuitems[1][1]=menuitems[1][1].upper()
		menuitems[1][3]=True
	else:
		menuitems[1][2]=menuitems[1][2].upper()
		menuitems[1][3]=False
	
	attach_settings_menu_actions_to_buttons()
	display.windowShow("settings_menu")
	display_settings_menu()
	current_settings_selection=3
	exit_to_main_menu=False
	display_settings_menuitem(current_settings_selection, True)
	while not exit_to_main_menu:
		pass
	display.windowHide("settings_menu")
	detach_settings_menu_actions_from_buttons()
	return

def main_menu():

	def display_main_menuitem(index, selected):
		if selected:
			display.drawRect("main_menu",0,0+index*15,63,15,fill,foreground_color)
			display.drawText("main_menu",0,0+index*15,menuitems[index],background_color,myfont)
			display.drawRect("main_menu",64,0,64,64,fill,background_color)
			display.drawPng("main_menu",64,0,"/lib/turtle_game/"+ menu_decoration[index] + "_" + theme + ".png")
		else:
			display.drawRect("main_menu",0,0+index*15,63,15,fill,background_color)
			display.drawText("main_menu",0,0+index*15,menuitems[index],foreground_color,myfont)
		display.flush()
		
	def main_menu_action_up(pressed):
		nonlocal current_selection
		if not pressed:
			return
		badge.led(1,1,1,0)
		time.sleep(.1)
		if sound_on: play_sound("menu")
		badge.led(1,0,0,0)
		if current_selection>0:
			display_main_menuitem(current_selection,False)
			current_selection-=1
			display_main_menuitem(current_selection,True)
			
	def main_menu_action_down(pressed):
		nonlocal current_selection
		if not pressed:
			return
		badge.led(1,1,0,1)
		time.sleep(.1) 
		if sound_on: play_sound("menu")
		badge.led(1,0,0,0)
		if current_selection<len(menuitems)-1:
			display_main_menuitem(current_selection,False)
			current_selection+=1
			display_main_menuitem(current_selection,True)
	
	def main_menu_action_enter(pressed):
		nonlocal start_game, enter_settings_menu, exit_game
		if not pressed:
			return
		badge.led(3,1,0,0)
		time.sleep(.1)
		if sound_on: play_sound("menu")
		badge.led(3,0,0,0)
		if current_selection==0:
			start_game=True
		if current_selection==1:
			enter_settings_menu=True
		if current_selection<3:
			pass
		elif current_selection==3:
			exit_game=True

	def detach_main_menu_actions_from_buttons():
		buttons.detach(buttons.BTN_UP)
		buttons.detach(buttons.BTN_DOWN)
		buttons.detach(buttons.BTN_OK)

	def attach_main_menu_actions_to_buttons():
		buttons.attach(buttons.BTN_UP, main_menu_action_up)
		buttons.attach(buttons.BTN_DOWN, main_menu_action_down)
		buttons.attach(buttons.BTN_OK, main_menu_action_enter)

	def display_main_menu():
		display.windowShow("main_menu")
		display.drawFill("main_menu", background_color)
		for i in range(len(menuitems)):
			display_main_menuitem(i, False)
		display_main_menuitem(current_selection, True)

	menuitems=["Play game!", "Settings","Help", "Exit game"]
	menu_decoration=["playgame","gears","turtle_game_qr","exitgame"]
	current_selection=0
	start_game=enter_settings_menu=exit_game=False
	display_main_menu()
	attach_main_menu_actions_to_buttons()
	
	while True:
		if start_game:
			start_game=False
			display.windowHide("main_menu")
			detach_main_menu_actions_from_buttons()
			level_selection_menu()
			display_main_menu()
			attach_main_menu_actions_to_buttons()
		if enter_settings_menu:
			enter_settings_menu=False
			display.windowHide("main_menu")
			detach_main_menu_actions_from_buttons()
			settings_menu()
			display_main_menu()
			attach_main_menu_actions_to_buttons()
		if exit_game:
			detach_main_menu_actions_from_buttons()
			system.home()

theme="light"
no_fill=False
fill=True
myfont="pixelade13"
sound_on=False
max_selectable_level=1
foreground_color=background_color=int()


default_level_status=[1,30,0,2,43,0,3,49,0,4,52,0,5,55,0,6,56,0,7,60,0,8,66,0,9,72,0,10,73,0,11,76,0,12,78,0] # level_no, par, best_scores reset
level_status=[1,30,0,2,43,0,3,49,0,4,52,0,5,55,0,6,56,0,7,60,0,8,66,0,9,72,0,10,73,0,11,76,0,12,78,0]
set_theme("light")

init_mywindow("menubar",384,64)
init_mywindow("main_menu",128,64)
init_mywindow("settings_menu",128,64)
init_mywindow("back_sign",64,24,32,40,False)
load_level_status()
main_menu()