#!/usr/bin/env python
from __future__ import print_function
"""
CustomLoggingClient implements a Tkinter interface that monitors in realtime the ACS custom
logging events generated runtime.
@TODO: implement window scrolling and window resize

"""
import acscommon
import Management
from Acspy.Nc.Consumer import Consumer
import signal
import sys
import logging
import bisect
import functools
try:
    import Tkinter as tk
except:
    import tkinter as tk
from IRAPy.bsqueue import BoundedSortedQueue

#DEFINE LOGGING RECORDS TOTAL ORDERING RULES
Management.CustomLoggingData.__eq__ = lambda self, other: self.timeStamp == other.timeStamp
Management.CustomLoggingData.__ne__ = lambda self, other: self.timeStamp != other.timeStamp
Management.CustomLoggingData.__lt__ = lambda self, other: self.timeStamp <  other.timeStamp
Management.CustomLoggingData.__le__ = lambda self, other: self.timeStamp <= other.timeStamp
Management.CustomLoggingData.__gt__ = lambda self, other: self.timeStamp >  other.timeStamp
Management.CustomLoggingData.__ge__ = lambda self, other: self.timeStamp >= other.timeStamp
#DEFINE LOGGING RECORDS STRING REPRESENTATION
Management.CustomLoggingData.__repr__ = lambda self: self.msg

# Maximum size for log messages display
"""
The number of logging events kept in memory
"""
MAX_QUEUE_SIZE = 200

"""
The number of logging events displayed in the window
"""
MAX_WINDOW_SIZE = 30

class App:
    """Tkinter GUI application
    """
    def __init__(self, master):
        """Constructor."""
        self.record_list = BoundedSortedQueue(max_size=MAX_QUEUE_SIZE)
        frame = master
        self.yscrollbar = tk.Scrollbar(frame, orient=tk.VERTICAL)
        self.yscrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.list_box = tk.Listbox(frame, 
                                   width=160, 
                                   height=MAX_WINDOW_SIZE, 
                                   yscrollcommand=self.yscrollbar.set)
        self.clear_button = tk.Button(frame, text="clear", command=self.clear)
        self.clear_button.pack(side=tk.BOTTOM, anchor=tk.SW)
        self.list_box.pack(expand=True, side=tk.LEFT, fill=tk.BOTH)
        self.yscrollbar.config(command=self.list_box.yview)
  
    def handler(self, event):
        """
        Handle a log_event adding it to a BoundedSortedQueue in memory and to the 
        corresponding GUI representation (in Tkinter this sould be a Listbox).
        @param event: the logging event.
        """
        index, popped = self.record_list.push(event)
        if popped:
            self.list_box.delete(0)
        self.list_box.insert(index, event.msg)
        self.list_box.yview(tk.END) # Listbox autoscroll

    def clear(self):
        """Empty the event list."""
        self.record_list.clear()
        self.list_box.delete(0, self.list_box.size())

if __name__ == '__main__':
    from IRAPy import logger
    try:
        root = tk.Tk()
        root.wm_title("ACS custom logging client")
        root.resizable(tk.YES, tk.YES)
        root.geometry('934x256')
        app = App(root)
        consumer = Consumer(Management.CUSTOM_LOGGING_CHANNEL_NAME)
        consumer.addSubscription(Management.CustomLoggingData, app.handler)
        consumer.consumerReady()
    except Exception as ex:
        print("exception caught: ", ex) #TODO: throw excep
        logger.logError(ex.message)
    #try:

    def handle_signal(num, trace):
        #trace.f_locals['app'].clear()
        #trace.f_locals['consumer'].disconnect()
        print("Exiting")
        sys.exit(0)

    signal.signal(signal.SIGINT, handle_signal)     
    signal.signal(signal.SIGUSR1, handle_signal)     
    root.mainloop()    
    #except KeyboardInterrupt as ki:
    #    pass
    #finally:
    #    consumer.disconnect()
    #    print("Exiting")
