import time
import subprocess,re,datetime,time,os,platform,json,PySimpleGUI as sg; from subprocess import Popen; from make_real_readme import main

# mkdir
import os
cd = CD = os.path.dirname(os.path.abspath(__file__))
dir_name = os.path.join(cd, 'output')
if not os.path.exists(dir_name): os.mkdir(dir_name)
else: print(f'Такая папка уже есть: "{dir_name}"')



sg.theme('Dark2')
cd = os.path.dirname(os.path.abspath(__file__))

def readfile(filename):
	with open(filename, 'r', encoding='utf-8') as ff: return ff.read()
def writefile(fpath, content):
	with open(fpath, 'w', encoding='utf-8') as ff: ff.write(content)
def writejson(a_path:str, a_dict:dict) -> None:
	with open(a_path, 'w', encoding='utf-8') as output_file: json.dump(a_dict, output_file, ensure_ascii=False, indent=2)
def readjson(a_path:str) -> dict:
	with open(a_path, 'r', encoding='utf-8') as f: return json.load(f)


def openfile(a_path):
	# File exists?
	if not os.path.exists(a_path): return sg.Popup(f"Error! This file doesn't exists: {a_path}")

	# check: OS
	if 'Windows' in platform.system():
		os.startfile(a_path)

	elif 'Linux' in platform.system():
		Popen(f'exo-open "{a_path}"', shell=True)

def opendir(a_path):
	# Folder exists?
	if not os.path.exists(a_path): return sg.Popup(f"Error! This directory doesn't exists: {a_path}")

	try:
		# check: OS
		if 'Windows' in platform.system():
			os.startfile(a_path)
		elif 'Linux' in platform.system():
			Popen(f'exo-open --launch FileManager --working-directory "{a_path}"', shell=True)
	except Exception as e:
		sg.Popen(f"Error, can't open a file: '{e}'")


########################################################################
#                              __ _            _                       #
#                             / _(_)          | |                      #
#    __   __   ___ ___  _ __ | |_ _  __ _     | |__   ___ _ __ ___     #
#    \ \ / /  / __/ _ \| '_ \|  _| |/ _` |    | '_ \ / _ \ '__/ _ \    #
#     \ V /  | (_| (_) | | | | | | | (_| |    | | | |  __/ | |  __/    #
#      \_/    \___\___/|_| |_|_| |_|\__, |    |_| |_|\___|_|  \___|    #
#                                    __/ |                             #
#                                   |___/                              #
########################################################################
def load_configs(): return readjson(os.path.join(cd, 'app_configs.json'))
def save_configs(a_config:dict): writejson(os.path.join(cd, 'app_configs.json'), a_config)



APP_CONFIGS = load_configs()
README_OFILENAME = APP_CONFIGS['README_OFILE']
CALL_REFERENCE_OFILENAME = APP_CONFIGS['CALL_REF_OFILE']

##-#-#-# ##-#-#-#
# Post-process logic
##-#-#-# ##-#-#-#
insert_md_section_for__class_methods = False
remove_repeated_sections_classmethods = False

import time
def timeit(f):
	def wrapper(*args, **kwargs):
		start = time.time()
		res = f(*args, **kwargs)
		end = time.time()
		# print('\nНачало в    : ', start)
		# print('\n ({}) Начало в    : '.format(f.__name__, start))
		# print('Окончено в  : ', end)
		# print('Длительность: ', end - start)
		# print('')
		return res
	return wrapper

class BESTLOG(object):
	def __init__(self, filename):
		# my_file = logging.FileHandler(filename, mode='w')
		# my_file.setLevel(logging.DEBUG)
		# my_file.setFormatter(logging.Formatter('%(asctime)s>%(levelname)s: %(message)s'))
		# logger = logging.getLogger(__name__)
		# logger.setLevel(logging.DEBUG)
		# logger.addHandler(my_file)
		self.filename = filename
		self.json_name = filename + '.json'
		self.error_list = []
		self.warning_list = []
		self.info_list = []
		self.debug_list = []
		self.tick_amount=1
		self.names = self.messages_names = 'error warning info debug'.split(' ')

	def tick(self):
		self.tick_amount+=1
		return self.tick_amount

	#######################################################################
	#      __             _                             _ _               #
	#     / _|           | |                           (_) |              #
	#    | |_ ___  _ __  | |_ _ __ __ _ _ __  ___ _ __  _| | ___ _ __     #
	#    |  _/ _ \| '__| | __| '__/ _` | '_ \/ __| '_ \| | |/ _ \ '__|    #
	#    | || (_) | |    | |_| | | (_| | | | \__ \ |_) | | |  __/ |       #
	#    |_| \___/|_|     \__|_|  \__,_|_| |_|___/ .__/|_|_|\___|_|       #
	#                                            | |                      #
	#                                            |_|                      #
	#######################################################################
	def error(self, m, metadata={}):
		self.error_list.append([self.tick(), m, metadata])
	def warning(self, m, metadata={}):
		self.warning_list.append([self.tick(), m, metadata])
	def info(self, m, metadata={}):
		self.info_list.append([self.tick(), m, metadata])
	def debug(self, m, metadata={}):
		self.debug_list.append([self.tick(), m, metadata])

	##########################################
	#      __                                #
	#     / _|                               #
	#    | |_ ___  _ __   _ __ ___   ___     #
	#    |  _/ _ \| '__| | '_ ` _ \ / _ \    #
	#    | || (_) | |    | | | | | |  __/    #
	#    |_| \___/|_|    |_| |_| |_|\___|    #
	#                                        #
	#                                        #
	##########################################
	def tolist(self):    return zip([self.error_list, self.warning_list, self.info_list, self.debug_list], self.names)
	def todict(self):    return {'error' : self.error_list, 'warning' : self.warning_list, 'info' : self.info_list, 'debug' : self.debug_list}
	@timeit
	def save(self):
		'''
		{
			'message_type' : message_type,
			'message_text' : m_text,
			'message_time' : m_time,
			'message_metadata' : m_metadata
		}
		'''
		all_messages_list = []
		for messages, message_type in self.tolist():
			results_ = [{'message_type' : message_type,
						'message_text' : m_text,
						'message_time' : m_time,
						'message_metadata' : m_metadata}
						for m_time, m_text, m_metadata in messages]
			all_messages_list.extend(results_)

		# sort messages on time
		all_messages_list = sorted(all_messages_list,
							key=lambda x: x['message_time'])
		
		# convert time
		# for i in all_messages_list: i['message_time'] = i['message_time'].strftime('%Y-%m-%d %H:%M:%S.%f')

		writejson(self.json_name, all_messages_list)
	@timeit
	def load(self, **kw):
		'''
			return dict with messages
			
			kw = {
				use_psg_color : bool
				show_time : bool
			}
		'''

		# plan:
		# read json, convert time

		# read
		all_messages_list = readjson(self.json_name)
		# convert time
		# for i in all_messages_list: i['message_time'] = datetime.datetime.strptime(i['message_time'], '%Y-%m-%d %H:%M:%S.%f')

		def format_message(message):
			if kw['show_time']:
				return str(message['message_time']) + ':' + message['message_text'] 
			else:
				return message['message_text']


		#=========#
		# 4 lists #
		#=========#
		error_list =   [i for i in all_messages_list if i['message_type'] == 'error']
		warning_list = [i for i in all_messages_list if i['message_type'] == 'warning']
		info_list =    [i for i in all_messages_list if i['message_type'] == 'info']
		debug_list =   [i for i in all_messages_list if i['message_type'] == 'debug']


		#=================#
		# and 1 more list #
		#=================#
		# colors = {'warning' : 'magenta', 'info' : 'black'}
		colors = {'warning' : 'blue', 'info' : 'black'}
		warning_info_ = []
		for message in sorted(warning_list + info_list, key=lambda x: x['message_time']):
			if kw['use_psg_color']:
				warning_info_.append([   format_message(message),
										colors.get(message['message_type'])   ])
			else:
				warning_info_.append(format_message(message))

		error_list = [format_message(i) for i in error_list]
		warning_list = [format_message(i) for i in warning_list]
		info_list = [format_message(i) for i in info_list]
		debug_list = [format_message(i) for i in debug_list]

		return error_list, warning_list, info_list, debug_list, warning_info_
	@timeit
	def load_to_listbox(self):
		'''
		read .json
		'''
		return sorted(readjson(self.json_name),
					  key=lambda x: x['message_time'])

@timeit
def compile_call_ref(output_filename='LoG_call_ref', **kw):
	''' Compile a "5_call_reference.md" file'''

	log_obj = BESTLOG(os.path.join(cd, output_filename))
	
	main(logger=log_obj,
		 main_md_file='markdown input files/5_call_reference.md',
		 insert_md_section_for__class_methods=insert_md_section_for__class_methods,
		 remove_repeated_sections_classmethods=remove_repeated_sections_classmethods,
		 files_to_include=[],
		 output_name=CALL_REFERENCE_OFILENAME,
		 delete_html_comments=True)
	log_obj.save()
	return log_obj.load(**kw), log_obj.load_to_listbox()


@timeit
def compile_readme(output_filename='LoG', **kw):
	''' Compile a "2_readme.md" file'''
	log_obj = BESTLOG(os.path.join(cd, output_filename))
	main(logger=log_obj,
		 insert_md_section_for__class_methods=insert_md_section_for__class_methods,
		 remove_repeated_sections_classmethods=remove_repeated_sections_classmethods,
		 files_to_include=[0, 1, 2, 3],
		 output_name=README_OFILENAME,
		 delete_html_comments=True)
	log_obj.save()
	return log_obj.load(**kw), log_obj.load_to_listbox()

def compile_all_stuff(**kw):
	'''
		Compile a "2_ and 5_" .md filess
		return output from them
	'''
	return compile_readme(**kw), compile_call_ref(**kw)


########################################
#     _____                            #
#    |  __ \                           #
#    | |__) |__  _ __  _   _ _ __      #
#    |  ___/ _ \| '_ \| | | | '_ \     #
#    | |  | (_) | |_) | |_| | |_) |    #
#    |_|   \___/| .__/ \__,_| .__/     #
#               | |         | |        #
#               |_|         |_|        #
########################################


def md2psg(target_text):
	r'''
		ib<space>color
		i italic
		b bold
		color = can be word   can be color
				red             #ff00111
				green
				blue
		i?b?\s?\w+?


		usage
		  *i*a**            italic
		  *b*a**            bold
		  *ib*a**           italic bold
		  *ib red*a**       italic bold red
		  *b green*a**      bold green
		
		'This was *I*special** message from *B*him**. And from *Igreen*this** to *Ired*this**'
	'''

	# format
	# ======
	font_norm   = ('Mono 12 ')           # (*sg.DEFAULT_FONT, 'italic')
	font_bold   = ('Mono 12 italic')     # (*sg.DEFAULT_FONT, 'italic')
	font_italic = ('Mono 12 bold')       # (*sg.DEFAULT_FONT, 'bold')

	list_of_Ts = []
	parts = [i for i in re.compile(r'(\*I?B?[a-z]*?\*[\d\D]*?\*\*)', flags=re.M|re.DOTALL).split(target_text) if i is not None]
	for index, text in enumerate(parts):
		if index % 2 == 0:
			# Normal text
			
			T_text = text
			T = sg.T(T_text, size=(len(T_text), 1), pad=(0,0), font=font_norm)
		else:
			# SPECIAL format
			T_parameters = {
				'font': font_norm
			}


			my_format = text[1:].split('*')[0]

			# ::: italic
			if 'I' in my_format: T_parameters['font'] = font_italic
			# ::: bold
			if 'B' in my_format: T_parameters['font'] = font_bold

			# ::: colors
			color_left = my_format.replace('I', '').replace('B', '')
			if color_left: T_parameters['text_color'] = color_left

			# making psg element
			T_text = '*'.join(text.split('*')[2:-2])
			T = sg.T(T_text, size=(len(T_text), 1), pad=(0,0), **T_parameters)

		list_of_Ts.append(T)

	return list_of_Ts

def mini_GUI():
	my_font = ("Helvetica", 12)
	my_font2 = ("Helvetica", 12, "bold")
	my_font3 = ("Helvetica", 15, "bold")
	my_font4 = ("Mono", 18, "bold")

	def make_tab(word):

		def tabs(*layouts):
			return sg.TabGroup( 
				[[ sg.Tab(title, lay, key=f'-tab-{word_}-{index}-')
					for index, (title, word_, lay) in enumerate(layouts)
				]]
			)

		return [[
			sg.Column(layout=[
				[sg.T('debug', font=my_font, text_color='grey')],
				[sg.ML(size=(50-15, 15), key=f'-{word}-debug-')],
				[sg.T('error', font=my_font, text_color='red')],
				[sg.ML(size=(50-15, 15), key=f'-{word}-error-')],
			], pad=(0, 0)),
			sg.T('    '),
			sg.Column(layout=[
				[sg.T('warning', font=my_font2)],
				[sg.ML(size=(70-12, 15), key=f'-{word}-warning-')],
				[sg.T('info', font=my_font2)],
				[sg.ML(size=(70-12, 15), key=f'-{word}-info-')],
			], pad=(0, 0)),

			tabs(
				('Text', word, [
					[sg.T('warning info', font=my_font3)]
					,[sg.ML(size=(110, 30), key=f'-{word}-warning_info-')]
				]),
				('Listbox', word, [
					[sg.T('warning info listbox', font=my_font3)]
					,[sg.Listbox([], size=(110, 30-1), key=f'-{word}-listbox-', enable_events=True, background_color='#ffccaa')]
				])
			)
		]]

	settings_layout = [
		[sg.CB('Toggle progressbar', False, enable_events=True, key='toggle_progressbar')],

		[
		 sg.Frame('Text editor',   [[ sg.Combo(['pycharm', 'subl'], default_value='subl', enable_events=True, key='_text_editor_combo_')   ]] ),
		 sg.Frame('Pycharm path:', [[ sg.I('', size=(40, 1), enable_events=True, key='_PyCharm_path_')                                     ]] )
		],

		[
		 sg.Frame('⅀∉ Filter "empty tables"', [
				[sg.T('''This is for filtering stirng, like:''')],
				[sg.T('''Warning =======    We got empty md_table for "EasyPrintClose"''', font='Mono 8')],
				[sg.CB('enable', True, key='checkbox_enable_empty_tables_filter', enable_events=True)],
				[sg.ML('PrintClose\nEasyPrintClose\nmain\ntheme\nRead',
						size=(30,10), enable_events=True, key='_filter_empty_tables_ml_')]]),
		 sg.Frame('⅀∉ Filter "tkinter class methods"', [
				[sg.T('''This is for filtering stirng, like:''')],
				[sg.T('''Please, fix ':return:' in 'SetFocus'                  IF you want to see 'return' row in 'signature table' ''', font='Mono 8')],
				[sg.CB('enable', True, enable_events=True, key='checkbox_enable_filter_tkinter_class_methods')],
				[sg.ML('SetFocus\nSetTooltip\nUpdate\n__init__\nbind\nexpand\nset_cursor\nset_size',
						size=(30,10), enable_events=True, key='_filter_tkinter_class_methods_')]], visible=not True)
		]
	]
	layout = [[sg.TabGroup([[
			sg.Tab('readme logs', 			make_tab('README')),
			sg.Tab('Call reference logs', 	make_tab('CALL_REF')),
			sg.Tab('General settings', 		settings_layout)
	]])]]

	# ░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░
	# ░▒▒▓▓▓ progress bar ▓▓▓▒▒░
	# ░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░
	from time import sleep; from math import pi, sin; from itertools import count
	def next_star():
		middle = 100/2
		for i in (int(sin(i*pi/middle)*middle + middle) for i in count()): yield i

	psg_module_path = str(sg).split("' from '")[1][:-2]
	star_bar = 	sg.Col([
			[sg.ProgressBar(max_value=100, orientation='h',
							key='_star_bar1_', size=(50,5), bar_color=('blue', 'yellow'))],
			[sg.ProgressBar(max_value=100, orientation='h',
							key='_star_bar2_', size=(50,5), bar_color=('yellow', 'blue'))],
	])
	# guia
	def empty_line(fontsize=12): return [sg.T('', font=('Mono '+str(fontsize)))]



	window = sg.Window('We are live! Again! --- ' + 'Completed making            {}, {}'.format(os.path.basename(README_OFILENAME), os.path.basename(CALL_REFERENCE_OFILENAME)), [
		[sg.T(size=(30,1), key='-compile-time-'), star_bar],
		empty_line(),
		[*md2psg(f'The *Bmagenta*PySimpleGUI** module being processed is *Imagenta*"{psg_module_path}"**'), sg.B('< open (__init__.py)', key='open_init_file'), sg.B('< open (psg.py)', key='open_psg_file')],
		# [sg.T(f'The **PySimpleGUI** module being processed is *"{psg_module_path}"*')],
		empty_line(),
		[
			sg.B('Run again (F1)', key='-run-')
			,sg.Col([
					[sg.CB('show time in logs (F2)', False, enable_events=True, key='show_time')],
					[sg.CB('Logs with Color (F3)', True, enable_events=True, key='use_psg_color')],
			])
			,sg.Col([
					empty_line(5),
					[sg.B('open "db folder"', key='-open_db_folder-')],
			])

			,sg.Frame('', [[
				sg.Col([
						[*md2psg('markdown outputFileName *I*FOR** *B*readme  **: ')
							,sg.I(README_OFILENAME, key='README_OFILE', size=(25, 1))
							,sg.B('open in explorer', key='open in explorer_readme')
							,sg.B('open in text editor', key='open file - readme')
						]
						
						,[*md2psg('markdown outputFileName *I*FOR** *B*call ref**: ')
							,sg.I(CALL_REFERENCE_OFILENAME, key='CALL_REF_OFILE', size=(25, 1))
							,sg.B('open in explorer', key='open in explorer_calref')
							,sg.B('open in text editor', key='open file - calref')
						]
					])
			]], relief=sg.RELIEF_SUNKEN, border_width=4)
		]
		,*layout
	], resizable=True, finalize=True, location=(0,0), return_keyboard_events = True)
	
	def update_time_in_GUI():
		window['-compile-time-'](datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S.%f'))

	def update_compilation_in_psg(values):

		#
		# ░▒▒▓▓▓▓▓◘ compile ◘▓▓▓▓▓▒▒░
		#
		result_readme__for_txt_n_listbox, result_call_ref__for_txt_n_listbox = compile_all_stuff(
												use_psg_color=values['use_psg_color'],
												show_time=values['show_time'])
		result_readme_txt,   result_readme_listbox_items   = result_readme__for_txt_n_listbox
		result_call_ref_txt, result_call_ref_listbox_items = result_call_ref__for_txt_n_listbox
		
		#
		# ░▒▒▓▓▓▓▓◘ define FILTER functions ◘▓▓▓▓▓▒▒░
		#
		badNames = [ i.strip() for i in values['_filter_tkinter_class_methods_'].split('\n') if i.strip()]
		badNames = '|'.join(badNames)
		regex_str1 = rf"fix .:return:. in .({badNames})."

		badNames = [ i for i in values['_filter_empty_tables_ml_'].split('\n') if i.strip()]
		badNames = '|'.join(badNames)
		regex_str2 = rf'empty md_table for .({badNames}).'

		def is_valid_regex_LogMessage(msg: str):
			nonlocal regex_str1, regex_str2

			# test 1 - filter tkinter class methods
			error1_found = False
			if values['checkbox_enable_filter_tkinter_class_methods'] and ':return:' in msg:
				error1_found = bool(re.search(regex_str1, msg, flags=re.M|re.DOTALL))
			
			# test 2 - filter "special empty tables"
			error2_found = False
			if values['checkbox_enable_empty_tables_filter'] and 'empty md_table for' in msg:
				error2_found = bool(re.search(regex_str2, msg, flags=re.M|re.DOTALL))
			
			return not error1_found and not error2_found
		def filter_log_messages(messages):
			if type(messages) is str:
				return '\n'.join([msg for msg in messages.split('\n') if is_valid_regex_LogMessage(msg)])
			raise TypeError

		#
		# ▓▓▓ Update GUI ▓▓▓
		#
		# =========== listbox's
		class ParsingError(object):
			def __init__(self, log_obj):
				self.log_obj = log_obj
				self.text = log_obj['message_text']

			def __str__(self): return self.__repr__()
			def __repr__(self):
				'''qwe'''
				# {
				#  'message_type': 'info',
				#  'message_text': 'STARTING',
				#  'message_time': 2,
				#  'message_metadata': {}
				# }

				text = self.log_obj['message_text']
				metadata = self.log_obj['message_metadata']
				lineno = ''
				if 'lineno' in metadata.keys(): lineno = "(line:" + str(metadata['lineno']) + ') '

				return f'{lineno} {text}'
				
		items1 = [i for i in result_readme_listbox_items if is_valid_regex_LogMessage(i['message_text']) ]
		items2 = [i for i in result_call_ref_listbox_items if is_valid_regex_LogMessage(i['message_text']) ]
		window['-README-listbox-']([ ParsingError(i) for i in items1])
		window['-CALL_REF-listbox-']([ ParsingError(i) for i in items2])

		# =========== multitext's

		def set_it(prefix = 'CALL_REF', messages_obj = result_call_ref_txt):

			t_error, t_warning, t_info, t_debug = ['\n'.join(i) for i in messages_obj[:4]]
			t_error = filter_log_messages(t_error)
			t_warning = filter_log_messages(t_warning)
			t_info = filter_log_messages(t_info)
			t_debug = filter_log_messages(t_debug)

			window[f'-{prefix}-error-'](t_error)
			window[f'-{prefix}-warning-'](t_warning)
			window[f'-{prefix}-info-'](t_info)
			window[f'-{prefix}-debug-'](t_debug)

			# /// colors warning_info
			window[f'-{prefix}-warning_info-'].update('')
			t_warning_info_obj = messages_obj[-1]

			if values['use_psg_color']:
				for text, color in t_warning_info_obj:
					if not is_valid_regex_LogMessage(text): continue
					window[f'-{prefix}-warning_info-'].print(text, text_color=color)
			else:
				window[f'-{prefix}-warning_info-'](t_warning_info_obj)
		
		# two calls
		set_it('README', result_readme_txt)
		set_it('CALL_REF', result_call_ref_txt)

		# ~~~~~~~~~~~~
		# GUI updating
		# ~~~~~~~~~~~~
		update_time_in_GUI()

	values = window.read(timeout=0)[1]
	update_compilation_in_psg(values)
	p_values = values

	window['_PyCharm_path_'](APP_CONFIGS['_PyCharm_path_'])
	window['_text_editor_combo_'].update(set_to_index=APP_CONFIGS['_text_editor_combo_']) # index

	window['toggle_progressbar'](APP_CONFIGS['toggle_progressbar'])

	window['checkbox_enable_empty_tables_filter'](APP_CONFIGS['checkbox_enable_empty_tables_filter'])
	window['_filter_empty_tables_ml_'](APP_CONFIGS['_filter_empty_tables_ml_'])

	window['checkbox_enable_filter_tkinter_class_methods'](APP_CONFIGS['checkbox_enable_filter_tkinter_class_methods'])
	window['_filter_tkinter_class_methods_'](APP_CONFIGS['_filter_tkinter_class_methods_'])

	window['show_time'](APP_CONFIGS['show_time'])
	window['use_psg_color'](APP_CONFIGS['use_psg_color'])
	
	window['README_OFILE'](APP_CONFIGS['README_OFILE'])
	window['CALL_REF_OFILE'](APP_CONFIGS['CALL_REF_OFILE'])


	next_val_gen = next_star()
	my_timeout = None
	while True:
		event, values = window(timeout=my_timeout)
		if event in ('Exit', None):
			# save to disk
			
			# APP_CONFIGS['_PyCharm_path_']  								= p_values['_PyCharm_path_']
			APP_CONFIGS['_text_editor_combo_']  						= 1 if window['_text_editor_combo_'].get() == 'subl' else 0

			APP_CONFIGS['toggle_progressbar']  							= p_values['toggle_progressbar']

			APP_CONFIGS['checkbox_enable_empty_tables_filter']  		= p_values['checkbox_enable_empty_tables_filter']
			APP_CONFIGS['_filter_empty_tables_ml_']  					= p_values['_filter_empty_tables_ml_']

			APP_CONFIGS['checkbox_enable_filter_tkinter_class_methods'] = p_values['checkbox_enable_filter_tkinter_class_methods']
			APP_CONFIGS['_filter_tkinter_class_methods_']  				= p_values['_filter_tkinter_class_methods_']

			APP_CONFIGS['show_time']  									= p_values['show_time']
			APP_CONFIGS['use_psg_color']  								= p_values['use_psg_color']
			
			APP_CONFIGS['README_OFILE'] 								= p_values['README_OFILE']
			APP_CONFIGS['CALL_REF_OFILE'] 								= p_values['CALL_REF_OFILE']

			save_configs(APP_CONFIGS)
			break
		p_values = values

		
		if '__TIMEOUT__' in event:
			if values['toggle_progressbar']:
				window['_star_bar1_'].UpdateBar(next(next_val_gen))
				window['_star_bar2_'].UpdateBar(next(next_val_gen))
		if '__TIMEOUT__' not in event:
			print('PSG event>', event)

		if event == 'toggle_progressbar':
			my_timeout = None if not values['toggle_progressbar'] else 100

		if event == '-README-listbox-':
			metadata = values['-README-listbox-'][0].log_obj['message_metadata']
			print(f'metadata = {metadata}')

		if event == '-CALL_REF-listbox-':
			ParsingError_obj = values['-CALL_REF-listbox-'][0]
			metadata = ParsingError_obj.log_obj['message_metadata']
			if 'lineno' in metadata.keys():
				lineno = metadata['lineno']
				texteditor = values['_text_editor_combo_']
				psg_module_path_SDK = psg_module_path.replace('__init__.py', 'PySimpleGUI.py')
				if 'pycharm' == texteditor:
					texteditor = values['_PyCharm_path_']
					subprocess.Popen(f'"{texteditor}" --line {lineno} "{psg_module_path_SDK}"', shell=True)
				elif 'subl' == texteditor:
					subprocess.Popen(f'{texteditor} "{psg_module_path_SDK}:{lineno}"', shell=True)

		# if event == '-CALL_REF-listbox-':
		# 	res = values['-CALL_REF-listbox-'][0]
		# 	print(f'res = {res}')


		if event == '-run-' or 'F1' in event:  update_compilation_in_psg(values)
		# folder
		if event == '-open_db_folder-':        opendir(cd)
		# folder
		if event == 'open in explorer_readme': opendir(os.path.dirname(os.path.join(cd, values['README_OFILE'])))
		if event == 'open in explorer_calref': opendir(os.path.dirname(os.path.join(cd, values['CALL_REF_OFILE'])))
		# file
		if event == 'open file - readme':      openfile(os.path.join(cd, values['README_OFILE']))
		if event == 'open file - calref':      openfile(os.path.join(cd, values['CALL_REF_OFILE']))
		# file
		if event == 'open_init_file': openfile(psg_module_path)
		if event == 'open_psg_file':  openfile(psg_module_path.replace('__init__.py', 'PySimpleGUI.py'))
		




		# hotkeys
		if 'F2' in event: window['show_time'](not values['show_time'])
		if 'F3' in event: window['use_psg_color'](not values['use_psg_color'])

	window.close()


if __name__ == '__main__':
	mini_GUI()