
"""

This file is part of PGLauncher.

PGLauncher is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

PGLauncher is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with PGLauncher.  If not, see <http://www.gnu.org/licenses/>.

"""

import logging
import tkinter
import tkinter.ttk as ttk
import threading
from tkinter import N, S, W, E

import pglauncher.patcher
import pglauncher.launcher

class WidgetLogger(logging.Handler):
    def __init__(self, append_log_callback):
        logging.Handler.__init__(self)
        
        self.setLevel(logging.DEBUG)
        self.append_log_callback = append_log_callback
		
    def emit(self, record):
    	self.append_log_callback(" • {}\n".format(self.format(record)))
		
class Application(ttk.Frame):
	
	def __init__(self, master=None):
		ttk.Frame.__init__(self, master)
		self.grid(column=0, row=0, sticky=(N, S, W, E))
		
		self.create_widgets()
		
		self.master.columnconfigure(0, weight=1)
		self.master.rowconfigure(0, weight=1)
		
	def create_widgets(self):
		self.button_quit = tkinter.Button(self, text="Quit", command=self.quit)
		self.button_quit.grid(row=0, column=0, sticky=tkinter.E)
		
		self.columnconfigure(0, weight=1)
		self.rowconfigure(0, weight=1)
		
class Launcher(Application, pglauncher.patcher.PatcherCallbacks):
	
	def __init__(self, master=None):
		Application.__init__(self, master)
		self.master.title("ProjectGorgon: Linux Launcher")
		
		# Register handler for displaying log output
		logger = logging.getLogger("pglauncher.patcher")
		logger.addHandler(WidgetLogger(self.append_log))
		
		# Create patcher instance that will run this show
		self.patcher = pglauncher.patcher.LinuxPatcher(self, logger)
		
	def create_widgets(self):
		self.label_versions_frame = ttk.Frame(self)
		self.label_launcher_version = ttk.Label(self.label_versions_frame, text="Launcher Version: ")
		self.label_launcher_version.grid(row=0, column=0, sticky=tkinter.W)
		
		self.label_launcher_version_num = ttk.Label(self.label_versions_frame, text="–")
		self.label_launcher_version_num.grid(row=0, column=1, sticky=tkinter.W)
		
		self.label_game_version = ttk.Label(self.label_versions_frame, text="Game Version: ")
		self.label_game_version.grid(row=1, column=0, sticky=tkinter.W)
		
		self.label_game_version_num = ttk.Label(self.label_versions_frame, text="–")
		self.label_game_version_num.grid(row=1, column=1, sticky=tkinter.W)
		
		self.label_versions_frame.grid(row=0, column=0, sticky=tkinter.W)
		
		self.separator_versions = ttk.Separator(self)
		self.separator_versions.grid(row=1, column=0, sticky=(W, E))
		
		self.label_patch = ttk.Label(self, text="Patch Progress:")
		self.label_patch.grid(row=2, column=0, sticky=tkinter.W)
		
		self.progressbar_patch = ttk.Progressbar(self)
		self.progressbar_patch.grid(row=3, column=0, sticky=tkinter.W+tkinter.E)
		self.progressbar_patch["max"] = 1.0
		
		self.label_download_frame = ttk.Frame(self)
		self.label_download = ttk.Label(self.label_download_frame, text="Download Progress: ")
		self.label_download.grid(row=0, column=0, sticky=W)
		self.label_download_msg = ttk.Label(self.label_download_frame)
		self.label_download_msg.grid(row=0, column=1, sticky=W)
		self.label_download_frame.grid(row=4, column=0, sticky=W)
		
		self.progressbar_download = ttk.Progressbar(self)
		self.progressbar_download.grid(row=5, column=0, sticky=tkinter.W+tkinter.E)
		self.progressbar_download["max"] = 1.0
		
		self.label_debug = ttk.Label(self, text="Debug:")
		self.label_debug.config(state='disabled')
		self.label_debug.grid(row=6, column=0, sticky=tkinter.W)
		
		self.text_debug_frame = ttk.Frame(self)
		self.text_debug = tkinter.Text(self.text_debug_frame, width=120, height=10)
		self.text_debug.grid(row=0, column=0, sticky=(N, S, W, E))
		
		self.scrollbar_debug_y = ttk.Scrollbar(self.text_debug_frame, orient=tkinter.VERTICAL, command=self.text_debug.yview)
		self.scrollbar_debug_y.grid(row=0, column=1, sticky=(N, S, W, E))
		
		self.text_debug.configure(yscrollcommand=self.scrollbar_debug_y.set)
		self.text_debug_frame.grid(row=7, column=0, sticky=(N, S, W, E))
		self.text_debug_frame.columnconfigure(0, weight=1)
		self.text_debug_frame.rowconfigure(0, weight=1)
		
		self.separator_debug = ttk.Separator(self)
		self.separator_debug.grid(row=8, column=0, sticky=(W, E))
		
		self.button_validate_game_data = ttk.Button(self, text="Validate Game Data", state=tkinter.DISABLED, command=self.do_validate)
		self.button_validate_game_data.grid(row=9, column=0, sticky=tkinter.W)
		
		self.button_launch_game_binary = ttk.Button(self, text="Launch Game", state=tkinter.DISABLED, command=self.do_launch)
		self.button_launch_game_binary.grid(row=9, column=0, sticky=tkinter.E)
		
		self.columnconfigure(0, weight=1)
		self.rowconfigure(7, weight=1)
	
	def append_log(self, message):
		self.text_debug.config(state='normal')
		self.text_debug.insert(tkinter.END, message)
		self.text_debug.see(tkinter.END)
		self.text_debug.config(state='disabled')
	
	def disable_buttons(self):
		self.button_launch_game_binary["state"] = tkinter.DISABLED
		self.button_validate_game_data["state"] = tkinter.DISABLED
	
	def enable_buttons(self):
		self.button_launch_game_binary["state"] = tkinter.NORMAL
		self.button_validate_game_data["state"] = tkinter.NORMAL
	
	def do_patch(self, **kwargs):
		self.disable_buttons()
		
		# Start patching process in background
		threading.Thread(target=self.patcher.patch, kwargs=kwargs, daemon=True).start()
	
	def do_validate(self):
		self.do_patch(force_file_checksums=True, check_launcher_version=False)
	
	def do_launch(self):
		self.disable_buttons()
		threading.Thread(target=pglauncher.launcher.launch, args=(self.patcher,)).start()
		self.enable_buttons()
	
	
	
	def handle_patcher_have_launcher_version(self, launcher_version):
		self.label_launcher_version_num["text"] = str(launcher_version)
	
	def handle_patcher_have_game_version(self, game_version):
		self.label_game_version_num["text"] = str(game_version)
	
	def handle_patcher_have_welcome_message(self, welcome_message):
		self.append_log(welcome_message)
	
	def handle_patcher_progress_total(self, value):
		self.progressbar_patch["value"] = value
	
	def handle_patcher_progress_current(self, value_part, value_file, message):
		self.progressbar_download["value"] = value_file
		self.label_download_msg["text"] = message if value_file < 1.0 else ""
	
	def handle_patcher_done(self):
		self.enable_buttons()
		
