import configparser
import os
import sys



#PyInstaller packages everything up into a bundle directory, which mungs relative paths.  They think
#	this is a feature.  The normal workaround is to find it again.
MAIN_DIR = getattr( sys, "_MEIPASS", None )
if MAIN_DIR != None:
	#In PyInstaller build

	MAIN_DIR = MAIN_DIR.replace("\\","/")+"/"

	#Put these up next to the executable for ease of access to the user
	FILEPATH_CONFIG     = MAIN_DIR+"../config.ini"
	FILEPATH_HIGHSCORES = MAIN_DIR+"../highscores.txt"
else:
	MAIN_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
	MAIN_DIR = MAIN_DIR.replace("\\","/")+"/"

	FILEPATH_CONFIG     = MAIN_DIR+"config.ini"
	FILEPATH_HIGHSCORES = MAIN_DIR+"highscores.txt"
#print(f"Main directory: \"{MAIN_DIR}\"")

FILEPATH_ICON = MAIN_DIR+"data/icon.png"

#FILEPATH_FONTMAP = "data/_fontmap_autogen.png"

HIGHSCORES_COUNT = 10

CAPTION_MENU       = "Marble Madness"
CAPTION_PLAY       = "Marble Madness"
CAPTION_HIGHSCORES = "Marble Madness (Highscores)"
CAPTION_OPTIONS    = "Marble Madness (Options)"
CAPTION_INFO       = "Marble Madness (Info)"
CAPTION_LVLSELECT  = "Marble Madness (Level Select)"



window_res           = [ 1024, 768 ]
window_msaa_nspp     = 8
window_fullscreen    = False
window_swap_interval = 1

tk_gui_scale = 1.5



render_advanced = True

render_fps = True
render_shadows = True
#Shadow darkness (0.0=none, 1.0=black)
render_shadow_darkness = 0.5

renderbasic_shadows_particles = True

RENDERADV_DISPLAY_MODE = 0 #0=game, 1=vis normal
renderadv_gbuf_texaa = 4
renderadv_shadow_mode = 1 #0=shadow volume, 1=shadowmap
renderadv_smap_res = 4096
renderadv_smap_pcf_rt = 4

CAMERA_DEFAULT_AZI  = -90.0
CAMERA_DEFAULT_ELEV =  50.0
CAMERA_DEFAULT_RADIUS = 5.6
#Fraction camera converges to target position, per second
camera_converge = 0.95

camera_fov_deg = 45.0 # [°]
camera_near =   1.0
camera_far  = 100.0

detail_marble        = 20
detail_shadow_circle = 20
detail_particle      = 10

texture_anisotropic = 16.0

particle_num_explode = 50

FLOOR_RADIUS = 1000.0

MENU_ROTATE_TIME = 0.3



volume_fx    = 0.5
volume_music = 0.5 # (not used and not exposed in GUI)



level_max     = 1 # max unlocked (not exposed in GUI)
LEVEL_CURRENT = level_max
LEVELS_COUNT = 10

INITIAL_POINTS = 0
initial_lives = 3 # (not exposed in GUI)

health_self  =  0.5 # [damage-seconds] (not exposed in GUI)
health_hench =  1.0 # (not exposed in GUI)
health_king  = 10.0 # (not exposed in GUI)

radius_self  = 0.125 # (not exposed in GUI)
radius_hench = 0.125 # (not exposed in GUI)
radius_king  = 0.375 # (not exposed in GUI)

top_rot_speed_self  = 15.0 # [rad/s] (not exposed in GUI)
top_rot_speed_hench = 12.0 * radius_self/radius_hench # (not exposed in GUI)
top_rot_speed_king  = 12.0 * radius_self/radius_king  # (not exposed in GUI)

rot_accel_self       = 15.0 # [rad/s²] (not exposed in GUI)
rot_accel_self_brake =  7.5 # (not exposed in GUI)
rot_accel_evil       = 15.0 # (not exposed in GUI)
rot_accel_evil_brake =  7.5 # (not exposed in GUI)



is_debugging = False # (not exposed in GUI)



SECTIONS = ( "window", "graphics", "audio", "game", "misc" )

def load():
	parser = configparser.ConfigParser()
	parser.read(FILEPATH_CONFIG)

	for name in SECTIONS:
		if not parser.has_section(name):
			parser.add_section(name)

	global window_res, window_msaa_nspp, window_fullscreen, window_swap_interval
	global tk_gui_scale
	wind = parser["window"]
	window_res = [
		wind.getint( "width" , window_res[0] ),
		wind.getint( "height", window_res[1] )
	]
	window_msaa_nspp = wind.getint( "msaa_samples", window_msaa_nspp )
	window_fullscreen = wind.getboolean( "fullscreen", window_fullscreen )
	window_swap_interval = wind.getint( "vsync_swap_interval", window_swap_interval )
	tk_gui_scale = wind.getfloat( "tk_gui_scale", tk_gui_scale )

	global render_advanced
	global render_fps, render_shadows, render_shadow_darkness
	global renderbasic_shadows_particles
	global renderadv_gbuf_texaa, renderadv_shadow_mode, renderadv_smap_res, renderadv_smap_pcf_rt
	global camera_converge, camera_fov_deg, camera_near,camera_far
	global detail_marble, detail_shadow_circle, detail_particle
	global texture_anisotropic
	global particle_num_explode
	grfx = parser["graphics"]
	render_advanced               = grfx.getboolean( "render_advanced", render_advanced )
	render_fps                    = grfx.getboolean( "render_fps", render_fps )
	render_shadows                = grfx.getboolean( "render_shadows", render_shadows )
	render_shadow_darkness        = 1.0 - grfx.getfloat( "render_shadow_level", 1.0-render_shadow_darkness )
	renderbasic_shadows_particles = grfx.getboolean( "renderbasic_shadows_particles", renderbasic_shadows_particles )
	renderadv_gbuf_texaa          = grfx.getint( "renderadv_gbuf_texaa", renderadv_gbuf_texaa )
	renderadv_shadow_mode         = grfx.getint( "renderadv_shadow_mode", renderadv_shadow_mode )
	renderadv_smap_res            = grfx.getint( "renderadv_smap_res", renderadv_smap_res )
	renderadv_smap_pcf_rt         = grfx.getint( "renderadv_smap_pcf_rt", renderadv_smap_pcf_rt )
	camera_converge               = grfx.getfloat( "camera_converge", camera_converge )
	camera_fov_deg                = grfx.getfloat( "camera_fov"     , camera_fov_deg )
	camera_near                   = grfx.getfloat( "camera_near"    , camera_near )
	camera_far                    = grfx.getfloat( "camera_far"     , camera_far      )
	detail_marble                 = grfx.getint( "detail_marble"       , detail_marble        )
	detail_shadow_circle          = grfx.getint( "detail_shadow_circle", detail_shadow_circle )
	detail_particle               = grfx.getint( "detail_particle"     , detail_particle      )
	texture_anisotropic           = grfx.getfloat( "texture_anisotropic", texture_anisotropic )
	particle_num_explode          = grfx.getint( "particle_num_explode", particle_num_explode )

	global volume_fx, volume_music
	aud = parser["audio"]
	volume_fx    = aud.getfloat( "volume_fx"   , volume_fx    )
	volume_music = aud.getfloat( "volume_music", volume_music )

	global level_max, initial_lives
	global health_self, health_hench, health_king
	global radius_self, radius_hench, radius_king
	global top_rot_speed_self, top_rot_speed_hench, top_rot_speed_king
	global rot_accel_self,rot_accel_self_brake, rot_accel_evil,rot_accel_evil_brake
	game = parser["game"]
	level_max = game.getint( "level_max", level_max )
	initial_lives = game.getint( "initial_lives", initial_lives )
	health_self  = game.getfloat( "health_self" , health_self  )
	health_hench = game.getfloat( "health_hench", health_hench )
	health_king  = game.getfloat( "health_king" , health_king  )
	radius_self  = game.getfloat( "radius_self" , radius_self  )
	radius_hench = game.getfloat( "radius_hench", radius_hench )
	radius_king  = game.getfloat( "radius_king" , radius_king  )
	top_rot_speed_self  = game.getfloat( "top_rot_speed_self" , top_rot_speed_self  )
	top_rot_speed_hench = game.getfloat( "top_rot_speed_hench", top_rot_speed_hench )
	top_rot_speed_king  = game.getfloat( "top_rot_speed_king" , top_rot_speed_king  )
	rot_accel_self       = game.getfloat( "rot_accel_self"      , rot_accel_self       )
	rot_accel_self_brake = game.getfloat( "rot_accel_self_brake", rot_accel_self_brake )
	rot_accel_evil       = game.getfloat( "rot_accel_evil"      , rot_accel_evil       )
	rot_accel_evil_brake = game.getfloat( "rot_accel_evil_brake", rot_accel_evil_brake )

	global is_debugging
	misc = parser["misc"]
	is_debugging = misc.getboolean( "debug", is_debugging )

def save():
	parser = configparser.ConfigParser()

	for name in SECTIONS:
		parser.add_section(name)

	wind = parser["window"]
	wind["width" ] = str(window_res[0])
	wind["height"] = str(window_res[1])
	wind["msaa_samples"] = str(window_msaa_nspp)
	wind["fullscreen"] = ["false","true"][int(window_fullscreen)]
	wind["vsync_swap_interval"] = str(window_swap_interval)
	wind["tk_gui_scale"] = str(tk_gui_scale)

	grfx = parser["graphics"]
	grfx["render_advanced"] = ["false","true"][int(render_advanced)]
	grfx["render_fps"]      = ["false","true"][int(render_fps)]
	grfx["render_shadows"]  = ["false","true"][int(render_shadows)]
	grfx["render_shadow_level"] = str( 1.0 - render_shadow_darkness )
	grfx["renderbasic_shadows_particles"] = ["false","true"][int(renderbasic_shadows_particles)]
	grfx["renderadv_gbuf_texaa"] = str(renderadv_gbuf_texaa)
	grfx["renderadv_shadow_mode"] = str(renderadv_shadow_mode)
	grfx["renderadv_smap_res"] = str(renderadv_smap_res)
	grfx["renderadv_smap_pcf_rt"] = str(renderadv_smap_pcf_rt)

	grfx["camera_converge"] = str(camera_converge)
	grfx["camera_fov"] = str(camera_fov_deg)
	grfx["camera_near"] = str(camera_near)
	grfx["camera_far" ] = str(camera_far )
	grfx["detail_marble"       ] = str(detail_marble       )
	grfx["detail_shadow_circle"] = str(detail_shadow_circle)
	grfx["detail_particle"     ] = str(detail_particle     )
	grfx["texture_anisotropic"] = str(texture_anisotropic)
	grfx["particle_num_explode"] = str(particle_num_explode)

	aud = parser["audio"]
	aud["volume_fx"   ] = str(volume_fx   )
	aud["volume_music"] = str(volume_music)

	game = parser["game"]
	game["level_max"] = str(level_max)
	game["initial_lives"] = str(initial_lives)
	game["health_self" ] = str(health_self )
	game["health_hench"] = str(health_hench)
	game["health_king" ] = str(health_king )
	game["radius_self" ] = str(radius_self )
	game["radius_hench"] = str(radius_hench)
	game["radius_king" ] = str(radius_king )
	game["top_rot_speed_self" ] = str(top_rot_speed_self )
	game["top_rot_speed_hench"] = str(top_rot_speed_hench)
	game["top_rot_speed_king" ] = str(top_rot_speed_king )
	game["rot_accel_self"      ] = str(rot_accel_self      )
	game["rot_accel_self_brake"] = str(rot_accel_self_brake)
	game["rot_accel_evil"      ] = str(rot_accel_evil      )
	game["rot_accel_evil_brake"] = str(rot_accel_evil_brake)

	misc = parser["misc"]
	misc["debug"] = ["false","true"][int(is_debugging)]

	with open( FILEPATH_CONFIG, "w" ) as cfg_file:
		parser.write(cfg_file)
