# win32traceutil like utility for Pythonwin
import thread
import win32trace, win32event, win32api
from pywin.framework import winout

outputWindow = None

def CollectorThread(stopEvent, file):
	win32trace.InitRead()
	handle = win32trace.GetHandle()
	# Run this thread at a lower priority to the main message-loop (and printing output)
	# thread can keep up
	import win32process
	win32process.SetThreadPriority(win32api.GetCurrentThread(), win32process.THREAD_PRIORITY_BELOW_NORMAL)

	try:
		while 1:
			rc = win32event.WaitForMultipleObjects((handle, stopEvent), 0, win32event.INFINITE)
			if rc == win32event.WAIT_OBJECT_0:
				# About the only char we can't live with is \0!
				file.write(win32trace.read().replace("\0", "<null>"))
			else:
				# Stop event
				break
	finally:
		win32trace.TermRead()
		print "Thread dieing"

class WindowOutput(winout.WindowOutput):
	def __init__(self, *args):
		apply(winout.WindowOutput.__init__, (self,)+args)
		self.hStopThread = win32event.CreateEvent(None, 0, 0, None)
		thread.start_new(CollectorThread, (self.hStopThread, self))
	def _StopThread(self):
		win32event.SetEvent(self.hStopThread)
		self.hStopThread = None
	def Close(self):
		self._StopThread()
		winout.WindowOutput.Close(self)
#	def OnViewDestroy(self, frame):
#		return winout.WindowOutput.OnViewDestroy(self, frame)
#	def Create(self, title=None, style = None):
#		rc = winout.WindowOutput.Create(self, title, style)
		return rc
		

def MakeOutputWindow():
	# Note that it will not show until the first string written or
	# you pass bShow = 1
	global outputWindow
	if outputWindow is None:
		title = "Python Trace Collector"
		# queueingFlag doesnt matter, as all output will come from new thread
		outputWindow = WindowOutput(title, title)
		# Let people know what this does!
		msg = """\
# This window will display output from any programs that import win32traceutil
# win32com servers registered with '--debug' are in this category.
"""
		outputWindow.write(msg)
	# force existing window open
	outputWindow.write('')
	return outputWindow

if __name__=='__main__':
	MakeOutputWindow()
