#!/usr/bin/env python
# -*- coding: CP1252 -*-
#
# generated by wxGlade 0.6.8 (standalone edition) on Tue Oct 07 12:53:43 2014
#

import wx,wx.grid,win32com.client,json,os,subprocess,win32clipboard,time,win32con

	

from threading import Thread
from Queue import Queue, Empty
 
class NonBlockingStreamReader:
 
	def __init__(self, stream):
		'''
	   stream: the stream to read from.
			   Usually a process' stdout or stderr.
	   '''
 
		self._s = stream
		self._q = Queue()
 
		def _populateQueue(stream, queue):
			'''
		   Collect lines from 'stream' and put them in 'queue'.
		   '''
 
			while True:
				line = stream.readline()
				if line:
					queue.put(line)
				else:
					break
 
		self._t = Thread(target = _populateQueue,
				args = (self._s, self._q))
		self._t.daemon = True
		self._t.start() #start collecting lines from the stream
 
	def readline(self, timeout = None):
		try:
			return self._q.get(block = timeout is not None,
					timeout = timeout)
		except Empty:
			return None
 



# Content of this block not found. Did you rename this class?
pass

# Content of this block not found. Did you rename this class?
pass

class Macro(wx.Frame):
	def __init__(self, *args, **kwds):
		# begin wxGlade: Macro.__init__
		kwds["style"] = wx.DEFAULT_FRAME_STYLE
		wx.Frame.__init__(self, *args, **kwds)
		self.label_1 = wx.StaticText(self, wx.ID_ANY, "Create your own macro\nenter key combinations to send as though you had typed them\nUse ^ for ctrl\nUse % for alt\nUse + for shift\nUse {} for keys eg {ESC} or {TAB}\nUse |*| # to repeat a command\nUse CTRL+F12 to stop a running macro\Use ALT+F12 to start a macro")
		self.MACRO_NAME = wx.StaticText(self, wx.ID_ANY, "Macro Name")
		self.button_1 = wx.Button(self, wx.ID_ANY, "Load")
		self.button_2 = wx.Button(self, wx.ID_ANY, "Save")
		self.button_3 = wx.Button(self, wx.ID_ANY, "Test Windows")
		self.button_4 = wx.Button(self, wx.ID_ANY, "Run")
		self.label_2 = wx.StaticText(self, wx.ID_ANY, "Repeat #")
		self.REPEAT_NUMBER = wx.TextCtrl(self, wx.ID_ANY, "1")
		self.label_4 = wx.StaticText(self, wx.ID_ANY, "Time Delay")
		self.TIME_DELAY = wx.TextCtrl(self, wx.ID_ANY, ".1")
		self.label_3 = wx.StaticText(self, wx.ID_ANY, "Window List")
		self.WINDOW_NAMES = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE)
		self.button_5 = wx.Button(self, wx.ID_ANY, "Insert Row")
		self.button_6 = wx.Button(self, wx.ID_ANY, "Clear Row")
		self.VIEWER = wx.grid.Grid(self, wx.ID_ANY, size=(1, 1))

		self.__set_properties()
		self.__do_layout()

		self.Bind(wx.EVT_BUTTON, self.onLoad, self.button_1)
		self.Bind(wx.EVT_BUTTON, self.onSave, self.button_2)
		self.Bind(wx.EVT_BUTTON, self.testWindows, self.button_3)
		self.Bind(wx.EVT_BUTTON, self.onRun, self.button_4)
		self.Bind(wx.EVT_TEXT, self.saveRepeat, self.REPEAT_NUMBER)
		self.Bind(wx.EVT_TEXT, self.saveTimeDelay, self.TIME_DELAY)
		self.Bind(wx.EVT_TEXT, self.saveWindows, self.WINDOW_NAMES)
		self.Bind(wx.EVT_BUTTON, self.onInsert, self.button_5)
		self.Bind(wx.EVT_BUTTON, self.onClearRow, self.button_6)
		self.Bind(wx.grid.EVT_GRID_CMD_CELL_CHANGE, self.onCellChange, self.VIEWER)
		# end wxGlade
		self.hotKeyId=150
		self.RegisterHotKey(self.hotKeyId,win32con.MOD_CONTROL, win32con.VK_F12)
		self.Bind(wx.EVT_HOTKEY, self.onKey, id=self.hotKeyId)
		self.RegisterHotKey(self.hotKeyId+1,win32con.MOD_ALT, win32con.VK_F12)
		self.Bind(wx.EVT_HOTKEY, self.onRun, id=self.hotKeyId+1)
		self.settings = {}
		self.recur = False
		self.p=None


	def __set_properties(self):
		# begin wxGlade: Macro.__set_properties
		self.SetTitle("Macro")
		self.REPEAT_NUMBER.SetToolTipString("Enter how many times you want the macro to run")
		self.VIEWER.CreateGrid(1, 1)
		self.VIEWER.SetRowLabelSize(20)
		self.VIEWER.SetColLabelValue(0, "Command")
		# end wxGlade

	def __do_layout(self):
		# begin wxGlade: Macro.__do_layout
		sizer_1 = wx.BoxSizer(wx.VERTICAL)
		sizer_4 = wx.BoxSizer(wx.HORIZONTAL)
		sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
		sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
		sizer_1.Add(self.label_1, 0, wx.EXPAND, 0)
		sizer_1.Add(self.MACRO_NAME, 0, 0, 0)
		sizer_2.Add(self.button_1, 0, 0, 0)
		sizer_2.Add(self.button_2, 0, 0, 0)
		sizer_2.Add(self.button_3, 0, 0, 0)
		sizer_2.Add(self.button_4, 0, 0, 0)
		sizer_2.Add(self.label_2, 0, 0, 0)
		sizer_2.Add(self.REPEAT_NUMBER, 0, 0, 0)
		sizer_2.Add(self.label_4, 0, 0, 0)
		sizer_2.Add(self.TIME_DELAY, 0, 0, 0)
		sizer_1.Add(sizer_2, 0, wx.EXPAND, 0)
		sizer_3.Add(self.label_3, 0, 0, 0)
		sizer_3.Add(self.WINDOW_NAMES, 1, wx.EXPAND, 0)
		sizer_1.Add(sizer_3, 1, wx.EXPAND, 0)
		sizer_4.Add(self.button_5, 0, 0, 0)
		sizer_4.Add(self.button_6, 0, 0, 0)
		sizer_1.Add(sizer_4, 0, wx.EXPAND, 0)
		sizer_1.Add(self.VIEWER, 4, wx.EXPAND, 0)
		self.SetSizer(sizer_1)
		sizer_1.Fit(self)
		self.Layout()
		# end wxGlade
	
		
	def onKey(self, event):
		if self.p:
			self.p.kill()
			self.retval='Killed'
		else:
			wx.MessageBox('No macro running','Results',wx.ICON_INFORMATION)
		event.Skip()

	def onLoad(self, event):  # wxGlade: Macro.<event_handler>
		dia = wx.FileDialog(None,message = "Select File", wildcard = 'macro (*.macro)|*.macro|All files (*.*)|*.*', style = wx.OPEN)
		if dia.ShowModal() == wx.ID_OK:
			filepath = dia.GetPaths()[0]
			i = open(filepath)
			self.settings = json.loads(i.read())
			i.close()
		if self.settings:
			self.MACRO_NAME.Label = self.settings['MACRO_NAME']
			self.WINDOW_NAMES.Value = self.settings['WINDOW_NAMES']
			self.REPEAT_NUMBER.Value = self.settings['REPEAT_NUMBER']
			self.TIME_DELAY.Value = self.settings['TIME_DELAY']
			self.loadViewer(self.settings['VIEWER'])
		event.Skip()
	
	def loadViewer(self,viewer_list):
		self.recur = True
		for i in range(self.VIEWER.GetNumberRows()-1,-1,-1):
			self.VIEWER.DeleteRows()
		for i in range(0,len(viewer_list)):
			self.VIEWER.AppendRows()
			self.VIEWER.SetCellValue(i,0,viewer_list[i])
		self.VIEWER.AppendRows()
		self.recur = False

	def onSave(self, event):  # wxGlade: Macro.<event_handler>
		dia = wx.FileDialog(None,message = "Select Output File", wildcard = 'macro (*.macro)|*.macro|All files (*.*)|*.*', style = wx.SAVE|wx.OVERWRITE_PROMPT)
		if dia.ShowModal() == wx.ID_OK:
			filepath = dia.GetPaths()[0]
			self.MACRO_NAME.Label = filepath
			self.settings['MACRO_NAME'] = self.MACRO_NAME.Label
			self.settings['VIEWER'] = [self.VIEWER.GetCellValue(i,0) for i in range(0,self.VIEWER.GetNumberRows()) if self.VIEWER.GetCellValue(i,0)]
			self.settings['REPEAT_NUMBER'] = self.REPEAT_NUMBER.Value
			self.settings['TIME_DELAY']=self.TIME_DELAY.Value
			o=open(filepath,'w')
			o.write(json.dumps(self.settings))
			o.close()
		event.Skip()

	def testWindows(self, event):  # wxGlade: Macro.<event_handler>
		shell = win32com.client.Dispatch("WScript.Shell")
		window_list = self.settings['WINDOW_NAMES'].split('\n')
		message_list = ["Window %s test %s\n"%(i+1,{False:"Failed",True:"Worked"}[shell.AppActivate(window_list[i])]) for i in range(0,len(window_list)) if window_list[i]]
		wx.MessageBox(''.join(message_list),"Test Results",wx.ICON_INFORMATION)
		event.Skip()

	def onRun(self, event):  # wxGlade: Macro.<event_handler>
		os.system('espeak "start"')
		command_list = [self.VIEWER.GetCellValue(i,0) for i in range(0,self.VIEWER.GetNumberRows()) if self.VIEWER.GetCellValue(i,0)]
		window_list = self.settings['WINDOW_NAMES'].split('\n')
		self.p = subprocess.Popen(['basicinterpreter/basicinterpreter.exe'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
		self.pout=NonBlockingStreamReader(self.p.stdout)
		command = '''sys.path.append(os.getcwd())\nshell=client.Dispatch("WScript.Shell")\n'''
		self.p.stdin.write(command)
		self.p.stdin.flush()
		command = '''def clipboard(shell,time,win32clipboard):\n	win32clipboard.OpenClipboard()\n	commands = win32clipboard.GetClipboardData()\n	win32clipboard.CloseClipboard()\n	for a in commands.strip():\n		shell.SendKeys(a)\n\ndef myrun(shell,time,win32clipboard):\n'''
		for z in range(0,int(self.REPEAT_NUMBER.Value)):
			for i in command_list:
				if i:
					if ' |*| ' in i:
						key,repeat = i.split(' |*| ')
						for a in range(0,int(repeat)):
							command += "	shell.SendKeys('%s')\n	time.sleep(%s)\n"%(key,float(self.TIME_DELAY.Value))
					elif 'switch ' in i:
						command +='%s'%("	if not shell.AppActivate('%s'):\n		return 'window failure'\n"%window_list[int(i.replace('switch ',''))-1],)
					elif 'sleep ' in i:
						command +='%s'%("	time.sleep(%s)\n"%float('%s'%i.replace('sleep ','')),)
					elif 'clipboard' in i:
						command += "	clipboard(shell,time,win32clipboard)\n"
					elif 'end ' in i:
						command += "	shell.AppActivate('%s')\n"%window_list[int(i.replace('end ',''))-1]
					else:
						command += "	shell.SendKeys('%s')\n"%i
				command += "	time.sleep(%s)\n"%float(self.TIME_DELAY.Value)
		command += '	return "Done"\n\n'
		o = open('macro.py','w')
		o.write(command)
		o.close()
		command = 'from macro import *\nmyrun(shell,time,win32clipboard)\nsys.stdout.flush()\n'
		self.p.stdin.write(command)
		self.retval = None
		while not self.retval:
			self.retval = self.pout.readline()
			wx.Yield()
		self.p.stdin.close()
		os.system('espeak "%s"'%self.retval.replace('... ','').replace('>>> ','').replace("'",''))
		self.pout=None
		self.p.wait()
		event.Skip()

	def onInsert(self, event):  # wxGlade: Macro.<event_handler>
		self.VIEWER.InsertRows(self.VIEWER.GetGridCursorRow())
		self.VIEWER.SetFocus()
		event.Skip()

	def onClearRow(self, event):  # wxGlade: Macro.<event_handler>
		self.VIEWER.SetCellValue(self.VIEWER.GetGridCursorRow(),0,'')
		self.VIEWER.SetFocus()
		event.Skip()

	def onCellChange(self, event):  # wxGlade: Macro.<event_handler>
		if self.VIEWER.GetCellValue(self.VIEWER.GetNumberRows()-1,0):
			self.VIEWER.AppendRows()
		event.Skip()

	def saveWindows(self, event):  # wxGlade: Macro.<event_handler>
		self.settings['WINDOW_NAMES']=self.WINDOW_NAMES.Value
		event.Skip()

	def saveTimeDelay(self, event):  # wxGlade: Macro.<event_handler>
		self.settings['TIME_DELAY'] = self.TIME_DELAY.Value
		event.Skip()
		
	def saveRepeat(self, event):  # wxGlade: Macro.<event_handler>
		self.settings['REPEAT_NUMBER']=self.REPEAT_NUMBER.Value
		event.Skip()
		
# end of class Macro
if __name__ == "__main__":
	app = wx.PySimpleApp(0)
	wx.InitAllImageHandlers()
	Macro = Macro(None, wx.ID_ANY, "")
	app.SetTopWindow(Macro)
	Macro.Show()
	app.MainLoop()
