# For future implement: TkinterDnD2: 
#  https://juu7g.hatenablog.com/entry/Python/csv/viewer#%E3%83%89%E3%83%A9%E3%83%83%E3%82%B0%E3%82%A2%E3%83%B3%E3%83%89%E3%83%89%E3%83%AD%E3%83%83%E3%83%97%E3%81%AE%E5%AE%9F%E8%A3%85TkinterDnD2%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9
import sys
from sys import exit
import os
import time
import platform
import glob
import re
from numpy import exp, log, log10, sin, cos, tan, arcsin, arccos, arctan, sqrt
import tkinter
import tkinter.font as font


from tklib.tkutils import getarg, getintarg, getfloatarg, pint, pfloat, terminate, desktop_name
from tklib.tkutils import get_os, add_path, split_file_path, find_executable_path, search_executable_path, convert_by_vars
from tklib.tkparams import tkParams
from tklib.tkfile import open_chardet
from tklib.tkgui.tkapplication_gui import tkApplication_GUI
import tklib.tkgui.tktkinter as tktkinter
from tklib.tkscript_macro import tkScript
from tklib.tksci.tksci import h, h_bar, hbar, e, kB, NA, c, pi, pi2, torad, todeg, basee
from tklib.tksci.tksci import me, mp, mn, u0, e0, e2_4pie0, a0, R, F, g
from tklib.tksci.tksci import acos, asin, atan, cosh, sinh, tanh
from tklib.tksci.tksci import degcos, degsin, degtan, degacos, degasin, degatan
from tklib.tksci.tksci import eVTonm, nmToeV
from tklib.tksci.tksci import factorial, Factorize, Gaussian, Lorentzian, combination, gamma



"""
Semiconductor parameters
"""


usage_str = "\n" \
          + "(i)   usage: python Launcher.py [-s=script_list_name]\n" \
          + "         ex: python Launcher.py -s={script_list_name}\n"



#=============================
# global variables
#=============================
prog_name = 'Semiconductor parameters'
version = [0, 1, 0]


#=============================
# Treat argments
#=============================
def usage(app):
    for s in app.usage_str.split('\n'):
        cmd = 'print({})'.format(s.rstrip())
        eval(cmd)


def initialize(app, config):
#================================
# Global variables
#================================
    app.tkvars  = tkParams()

    app.window_title = f'{prog_name} ver.{version[0]}.{version[1]}.{version[2]}'

def update_vars(app, cparams):
    app.add_argument(opt = "-s", type = "str", var_name = 'script_list_name',  opt_str = "-s=script_list_name", desc = 'Script list file',
                     defval = "", optional = True);

def create_menu(app, config, cparams, root_window):
    def onOpen(event = None):
#        data_path_button_click(app, tkvars)
        print("")
        print("Warning: This function is not impletmented")
    
    menu_bar  = app.create_menu()

    menu_file = tktkinter.Menu(app, menu_bar, tearoff = 0)
    menu_file.add_command(label = app.p('Open'), accelerator = 'Alt+O', 
                command = onOpen)
#                command = lambda: data_path_button_click(app, tkvars))
    menu_file.add_command(label = app.p('exit'), accelerator='Alt+E', command = lambda e: app.on_closing())
    menu_bar.add_cascade(label = app.p('File'), menu = menu_file)

    setup_widgets = 'editor_path|confirm_on_exit|debug_mode'

    menu_tool = tkinter.Menu(menu_bar, tearoff = 0)
    menu_tool.add_command(label = app.p('Setup'), accelerator = 'Alt+u', 
                command = lambda e: app.dialog_setup(widgets = setup_widgets))
    menu_bar.add_cascade(label = app.p('Tool'), menu = menu_tool)
    menu_bar.bind_all("<Alt-o>", onOpen)
    menu_bar.bind_all("<Alt-e>", lambda e: app.on_closing())
    menu_bar.bind_all("<Alt-u>", lambda e: app.dialog_setup(widgets = setup_widget))

    return menu_bar

def create_toolbar(app, config, cparams, root_window):
    ctkvars = app.tkvars
    tkvars  = ctkvars.get_param_dict()
    config  = app.configparams

    def toolbar_clickevent(event):
        pass

    tool_bar = app.create_toolbar(bg = 'blue')

    setup_widgets = 'editor_path|confirm_on_exit|debug_mode'
    setupButton = tktkinter.Button(app, tool_bar, text = "Setup", font = ("", config.font_size),
                        command = lambda: app.dialog_setup(
                                    entry_width = 50, button_width = 10, edit_button_width = 10, 
                                    shell_button_width = 0, 
                                    widgets = setup_widgets,
                                    is_print = True)
                         )
    setupButton.pack(side = tkinter.LEFT, anchor = 'w', padx = 1, pady = 0)

    def edit_inifile():
        editor = config.get("editor_path", None)
        if editor is None== '' or editor == '':
            editors = app.get_editors()
            if len(editors) > 0:
                editor = editors[0]
                tktkinter.dialog_okcancel(app, title = app.p('Error'), 
                        message = 'editor_path is not specified.\nUse {editor}')
            else:
                tktkinter.dialog_okcancel(app, title = app.p('Error'), message = 'editor_path is not specified.')
                return
         
#        tktkinter.execute_command(app, config.editor_path, working_dir = '.', is_print = True, files = [config.inifile])
        tkScript().execute_external_command(app, config.editor_path, [config.inifile], is_print = False)

    edit_ini_Button = tktkinter.Button(app, tool_bar, text = 'Edit ini file', font = ("", config.font_size),
                    command = edit_inifile)
    edit_ini_Button.pack(side = tkinter.LEFT, anchor = 'w', padx = 1, pady = 0)

    def lang_sel_change(e):
        config.lang = tkvars['lang_combobox'].get()
        phrases = {'WillApplyUponReboot': {'ja': f'日本語に変更されました。再起動後に有効になります',
                                           'en': f'Changed to English. Will be applied after reboot'
                                          }
                  }
        app.phrases = app.read_resource(app.resource_path, config.lang, app.phrases)
        tktkinter.dialog_okcancel(app, title = app.p('Quit'), message = app.p('WillApplyUponReboot', phrases = phrases))

    tkvars['lang'] = tkinter.StringVar(value = config.lang)
#    optionmenu = tkinter.OptionMenu(tool_bar, tool_bar, 'ja', 'en')
#    optionmenu.pack(side = tkinter.LEFT, anchor = 'w', padx = 1, pady = 0)
    combobox = tkinter.ttk.Combobox(tool_bar, values = ('ja', 'en'), width = 2)
    combobox.set(tkvars['lang'].get())
    combobox.bind('<<ComboboxSelected>>', lang_sel_change)
    combobox.pack(side = tkinter.LEFT, anchor = 'w', padx = 1, pady = 0)
    tkvars['lang_combobox'] = combobox

    exitButton = tktkinter.Button(app, tool_bar, text = 'Exit', font = ("", config.font_size),
                        command = lambda: app.on_closing(), 
                        anchor = tkinter.NW)
    exitButton.pack(side = tkinter.LEFT, anchor = 'w', padx = 1, pady = 0)

def input_path_button_click(app, cparams, tkvars, 
                varname = "infile", parameterpath_varname = "prmpath", outputpath_varname = "outfile",
                file_type = [("Excel", "*.xlsx"), ("All", "*.*")], ini_dir = '.'):
    selpath = tkinter.filedialog.askopenfilename(filetypes = file_type, initialdir = ini_dir)

    header, ext            = os.path.splitext(selpath)
    filebody               = os.path.basename(header)
    cparams.outfile        = header + f'-predict.xlsx'
    cparams.parameter_path = header + '.prm'

    tkvars[varname].set(selpath)
    tkvars[outputpath_varname].set(cparams.outfile)
#    tkvars[parameterpath_varname].set(cparams.parameter_path)


def create_frame(app, config, cparams, parent_notebook):
    config  = app.configparams
    ctkvars = app.tkvars
    tkvars  = ctkvars.get_param_dict()

    page1_frame = tktkinter.Frame(app, parent_notebook, bg = 'dim gray')
    page1_frame.pack(fill = tkinter.BOTH, expand = True)
    parent_notebook.add(page1_frame, text = app.p('Menu'))
    notebook_frame = page1_frame

    return notebook_frame


def create_window(app, config, cparams):
    ctkvars = app.tkvars
    tkvars  = ctkvars.get_param_dict()

    root_window = app.create_window(title = app.window_title)
#                    geometry = config.geometry, minsize = config.minsize, default_font = ('FixedSys', config.default_font_size)) #None) #('FixedSys', 14))
    menu_bar = create_menu(app, config, cparams, root_window)
    tool_bar = create_toolbar(app, config, cparams, root_window)
# 2分割ウインドウを使う場合。いづれのpaneもnotebook型ウインドウが作られる
#    panes = app.add_root_panes(root = root_window, type = "pane2", sashwidth = 2, left_pane_width = 600)
#    main_pane, left_notebook, right_notebook = panes
# 1p分割ウインドウを使う場合。paneはnotebook型ウインドウが作られる
    panes = app.add_root_panes(type = "pane1", sashwidth = 2)
    left_notebook = panes[0]

# 左ペインのnotebookにタブを追加。２ページ目は開発者用タブ
    ltabframe1 = create_frame(app, config, cparams, left_notebook)
#    ltabframe2 = app.create_development_tab(config, cparams, left_notebook)#, copy_tkvars = copy_tkvars)
#    ltabframe3 = app.create_editor_tab(config, cparams, left_notebook, title = 'Editor test',
#                    entry_width = 35, 
#                    eval_button_args = { 'text': 'eval', 'width': 4, "command": None },
#                    )


def main():
#==================================================================
# Initialize parameters
#==================================================================
    app = tkApplication_GUI(usage_str = usage_str, globals = globals(), locals = locals(), 
                        use_user_inifile = True,
                        inifile_dirs = ['../../user', 'user'], create_inidir = False)
    print(f"Configuration file: {app.config.inifile}")

# 設定パラメータオブジェクト
    config  = app.config
    config.font_size = 14
    cparams = app.get_params()   # 計算エンジンのパラメータオブジェクト
    mtime = time.localtime(os.path.getctime(app.script_path))

    print("")
    print( "################################################")
    print(f"# {app.script_path} ver {version[0]}.{version[1]}.{version[2]}")
    print(f"#       Modified time: {mtime.tm_year}/{mtime.tm_mon}/{mtime.tm_mday} {mtime.tm_hour}:{mtime.tm_min}:{mtime.tm_sec}")
    print( "################################################")

    print(f"Initialize parameters")
    initialize(app, config)

# GUIウィジェット変数オブジェクトと辞書型
    ctkvars = app.tkvars

#    print("")
#    print(f"Read configration from [{config.inifile}]")
#    config.read_parameters(path = config.inifile)

    print("")
    print(f"Update parameters by command-line arguments")
    update_vars(app, cparams)

    create_window(app, config, cparams)

    app.mainloop()

# メインウインドウサイズをconfigにコピー
#    config.geometry = app.root_window_geometry
#    print("")
#    print(f"Save configuration to [{config.inifile}]")
#    ret = config.save_parameters(path = config.inifile, section = 'Configure', sort_by_keys = True, IsPrint = False)
#    if not ret:
#        print(f"\nError: Can not write to [{config.inifile}]\n")

    app.terminate(usage = app.usage())


if __name__ == "__main__":
    main()


