import wx
import telnetlib
import win32gui

import win32com.client
import os
import sys
import time
import traceback
def process_is_running(proc_name):
	#From Adam Pletcher's "Python for Tech Artsts" (

	import win32pdh
	proc_name = os.path.splitext(proc_name)[0].lower()
	junk, instances = win32pdh.EnumObjectItems(None,None,'Process', win32pdh.PERF_DETAIL_WIZARD)
	for proc_inst in instances:
		if (proc_inst.lower() == proc_name):
			return True

	return False
class MB_Sub_Frame(wx.Frame):
        #This comes from Adam Pletcher's "Python for Tech Artsts", and FeindishVegan's Maya Python post here:
	_top_mb_window_handle = None
	def __init__(self, parent, app, id=-1, title="Motion Builder Tool", pos=(60, 120), size=(350, 200), name='frame', resize=True, style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.FRAME_NO_TASKBAR):

		wx.Frame.__init__(self, parent, id, title, pos, size, style) = app
		self.panel = None
		self.initialPosOffset = pos
		self._runningModal = False
		# resizable windows is the default in wxPython, but we allow caller to override that.
		if (not resize):
			wx.Frame.ToggleWindowStyle(self, wx.RESIZE_BORDER)

		# Tool window's background color.  This should be made to match the user's BG color in Max.
		bg_color = (197, 197, 197)
		self.SetBackgroundColour(wx.Color(bg_color[0], bg_color[1], bg_color[2]))
		# Event Bindings
		self.Bind(wx.EVT_CLOSE, self.on_close)
	def create(cls, *args, **kw):
		Call this static class method to create a new instance of your subframe.
		This will use the 3dsmax window as a parent for the current frame.
		Limitation: If > 1 copy of 3dsmax is open, uses the first one it finds.
		Could probably be fixed, however.

		if (not process_is_running('motionbuilder.exe')):
			raise WindowsError('*** ERROR: MotionBuilder is not running')
			app = wx.GetApp()

			if (app == None):
				app = wx.App(redirect=False)
			val = MB_Sub_Frame._get_top_mb_window()
			topHandle = val[0]
			if (topHandle == None):
				raise WindowsError('*** ERROR: Motion Builder window handle not found.')
				windowPos = val[1]

				toolFrame = wx.PreFrame()
					frame = cls(toolFrame, app, *args, **kw)
					print cls.__name__
					print traceback.format_exc()
					frame = None

				return frame
	def _get_top_mb_window():
		if MB_Sub_Frame._top_mb_window_handle is not None:
			return MB_Sub_Frame._top_mb_window_handle

		# EnumWindows requires a callback function
		def callback(handle, winList):
			return True
		# Get list of open windows
		windows = []
		win32gui.EnumWindows(callback, windows)
		# Find window belonging to 3ds Max

		for handle in windows:
			title = win32gui.GetWindowText(handle)
			if ('MotionBuilder 7.5' in title):
				# Maximize the window if it's minimized
				import win32con
				window = win32gui.ShowWindow(handle, win32con.SW_MAXIMIZE)

				# Get upper left desktop coords of MB window
				pos = win32gui.GetWindowRect(handle)[:2]
				# Set handle id in our instance
				MB_Sub_Frame._top_mb_window_handle = handle
				return (handle, pos)
		# MB window not found
		return None

	def on_close(self, evt):
		Event handler for EVT_CLOSE event.
		# Regular wx Destroy waits for the application to destroy the window.
		# Since there is no wxApp running, we do it ourselves.

	def show_modal_dialog(self, dlg):
		Method to display a modal dialog that also disables the 3dsmax window.
		mb_disabled = self._runningModal					# Save enabled state, so we can restore it when this modal dialog is done
		if (not mb_disabled):
			self._runningModal = True
			top = MB_Sub_Frame._top_mb_window_handle	# get MB window handle

			win32gui.EnableWindow(top, False)				# disable it
		ret_val = dlg.ShowModal()								# show our dialog - won't continue until dialog is closed
		if (not mb_disabled):									# enables 3dsmax window again, if it was enabled when this dialog started
			win32gui.EnableWindow(top, True)
			self._runningModal = False

		return ret_val
host = telnetlib.Telnet("", 4242)
def mbPipe(command):
	host.read_until('>>>', .01)
	#write the command
	host.write(command + '\n')
	#read all data returned

	raw = str(host.read_until('>>>', .1))
	#removing garbage i don't want
	raw = raw.replace('\n\r>>>','')
	raw = raw.replace('\r','')
	rawArr = raw.split('\n')
	#cleanArr = [item.replace('\r', '') for item in rawArr]

	return rawArr
class MyFrame(MB_Sub_Frame):
    def __init__(self,parent,app):
        # create a frame, no parent, default to wxID_ANY
        MB_Sub_Frame.__init__(self, parent, app, id=-1, title='mbUI test',pos=(200, 150),size=(175,280))

        #create listbox
        self.selListBox = wx.ListBox(self, -1, choices=[],pos=(8,38),size=(150, 145))
        self.selListBox.Bind(wx.EVT_LISTBOX, self.selListBoxChange)
        #create model metadata
        self.translationLabel = wx.StaticText(self,-1,'Pos:',pos=(8,185))
        self.rotationLabel = wx.StaticText(self,-1,'Rot:',pos=(8,200))
        #make buttons

        self.selItems = wx.Button(self, id=-1,label='Get Selected Items',pos=(8, 8),size=(150, 28))
        self.selItems.Bind(wx.EVT_BUTTON, self.selItemsClick)
        self.selItems.SetToolTip(wx.ToolTip("Gets all 'models' selected in Motion Builder"))
        self.delItems = wx.Button(self, id=-1,label='Delete This Model',pos=(8, 217),size=(150, 28))
        self.delItems.Bind(wx.EVT_BUTTON, self.delItemsClick)
        self.delItems.SetToolTip(wx.ToolTip("Will delete selected models"))
        # show the frame

    def selItemsClick(self,event):
        mbPipe("selectedModels = FBModelList()")
        for item in (mbPipe("for item in selectedModels: print item.Name")):

    def delItemsClick(self,event):
        mbPipe('FBFindModelByName("' + str(self.selListBox.GetStringSelection()) + '").FBDelete()')
        mbPipe("selectedModels = FBModelList()")
        for item in (mbPipe("for item in selectedModels: print item.Name")):

    def selListBoxChange(self,event):
        trans = mbPipe('FBFindModelByName("' + str(self.selListBox.GetStringSelection()) + '").Translation')
        rot = mbPipe('FBFindModelByName("' + str(self.selListBox.GetStringSelection()) + '").Rotation')
        self.translationLabel.SetLabel(('Pos: ' + trans[0]))
        self.rotationLabel.SetLabel(('Rot: ' + rot[0]))

    def on_close(self, event):
        #This method is bound by MB_Sub_Frame to the EVT_CLOSE event.
        print 'Shutting down...'
        self.user_exit = True
application = wx.PySimpleApp()
window = MyFrame.create()
#window = MyFrame()