#!/usr/bin/env python3
from argparse import ArgumentParser
from sys import exit
from local import *
from tkinter import *

parser = ArgumentParser("Arena admin panel")
parser.add_argument("-g","--gui",help="Run GUI panel",dest="gui",action="store_true")
parser.add_argument("-p","--password",help="Change password",dest="password")
parser.add_argument("-o","--port",help="Set up port",dest="port")
parser.add_argument("-c","-console",help="Run with no GUI",dest="console",action="store_true")
"""/*
    Class: ArenaGUI
    Main GUI interface for graphical management of the Arena backend
    server.

    Provides graphical management of the underlying server system, as well
    as a panel for displaying any log messages generated by the system.

    Usage:
        _From command line_
        (start code (bash))
            python3 ArenaGUI.py
        (end code)

        _From python shell_
        (start code (py))
            root = ArenaGUI()
            root.mainloop()
        (end code)
*/"""
class ArenaGUI(Tk):

    """/*
        Group: Constructors
    */"""

    """/*
        Constructor: __init__
        Initialises the main window, and creates the children <Panel>s

        Parameters:
            obj master - The parent of this window. Defaults to None
    */"""
    def __init__(self, master=None):
        # Set up the master window
        super(ArenaGUI, self).__init__(master)
        self.title("Arena Server")
        self.resizable(0, 0)
        self.minsize(width=750, height=650)
        self.protocol("WM_DELETE_WINDOW", self._close)

        """/*
            Group: Instance Variables
        */"""

        """/*
            var: _logPanel
            Reference to this window's instance of <LogPanel>.

            Used to call methods in the instance
        */"""
        self._logPanel = None

        """/*
            var: _gameServerPanel
            Reference to this window's instance of <GameServerPanel>.

            Used to call methods in the instance
        */"""
        self._gameServerPanel = None

        """/*
            var: _httpPanel
            Reference to this window's instance of HttpPanel

            Used to call methods in the instance
        */"""
        self._httpPanel = None

        self._initialiseLogPanel()
        self._initialiseServerPanel()

    """/*
        Group: Private Methods
    */"""

    """/*
        Function: _initialiseLogPanel
        Initialise an instance of <LogPanel>, save it into <_logPanel>,
        and add it to the main window.
    */"""
    def _initialiseLogPanel(self):
        self._logPanel = LogPanel(self, "Log", 400, 650)
        self._logPanel.pack(side=LEFT, fill=BOTH, expand=1)

    """/*
        Function: _initialiseServerPanel
        Initialise an instance of <GameServerPanel>, save it into
        <_gameServerPanel>, and add it to the main window.
    */"""
    def _initialiseServerPanel(self):
        self._gameServerPanel = GameServerPanel(
            self, "Status Controls", 300,
            625, logMessage=self._logPanel.logMessage)
        self._gameServerPanel.pack(side=TOP, expand=1, fill=BOTH)

    """/*
        Function: _close
        Handler for the closing of the entire application.

        Ensures that all child <Panel> instances can be closed, then destroys
        the main window.

        If any child cannot be closed, then call <_popup> to inform the user
        of which panel cannot be closed

        Notes:
            This method is automatically called when the main window's "X"
            button is clicked
    */"""
    def _close(self):
        # Attempt to close every panel before closing the main window
        closing = True
        closing = closing and self._gameServerPanel.close()
        if not closing:
            self._popup(self._gameServerPanel.getTitle())
            return
        closing = closing and self._logPanel.close()
        # Close the log panel last
        if not closing:
            self._popup(self._logPanel.getTitle())
            return
        self.destroy()

    """/*
        Function: _popup
        Creates a popup window to display an error message when the main window
        cannot be closed

        Parameters:
            str panelTitle - The title of the <Panel> that failed to close

        Example:
            Running the following code:
            (start code (py))
                # First create the main GUI window
                gui = ArenaGUI()
                gui.mainloop()
                # Now create a popup
                gui._popup('Example')
            (end code)
            Will cause the following popup to appear
            (start diagram)
                +---------------------------------+
                |      Panel failed to close      |
                +---------------------------------+
                | Panel "Example" failed to close |
                |            +-------+            |
                |            | Close |            |
                |            +-------+            |
                +---------------------------------+
            (end diagram)
    */"""
    def _popup(self, panelTitle):
        popup = Toplevel(self)
        popup.title('Panel failed to close')

        message = 'Panel "%s" failed to close' % (panelTitle)
        Label(popup, text=message).pack(fill=BOTH, expand=1)

        Button(popup, command=popup.destroy, text="Close").pack(
            fill=BOTH, expand=1)


if __name__ == '__main__':
    args = parser.parse_args()

    # Gui Specified
    if args.gui:
        server = ArenaGUI(None)
        server.mainloop()

    # Console Specified
    elif args.console:
        from datetime import datetime
        try:
            logfile = open(
                './logs/arena_' + datetime.now().strftime(
                    '%d%m%Y%H%M%S') + '.log',
                'w', 1)

            # Write a method to handle logging
            def consoleLog(s):
                logfile.write(s)
                print(s)
        except IOError:
            print("Error when attempting to open logfile")
            log = print
        kwargs = {'log': consoleLog}
        if args.port:
            try:
                kwargs['port'] = int(args.port)
            except:
                log('Port was not an integer')
                exit(1)
        if args.password:
            kwargs['password'] = args.password

        server = ArenaServer.ArenaServer(**kwargs)
        try:
            server.listen()
        except KeyboardInterrupt:
            server.close()

    # Assume GUI if no args passed
    else:
        server = ArenaGUI(None)
        server.mainloop()
    

