import maya.cmds as cmd
import sys
import pdb
import traceback
import re

class myPyDebug:

	def __init__(self):
		self.debug = pdb.Pdb('tab', self, self)
		self.debug.prompt = ''

	def pause(self):
		self.debug.set_trace()

	def breaks(self, point):
		pass

        def traceRetParse(self, ret):
            escape_dict={'\a':r'\a',
                       '\b':r'\b',
                       '\c':r'\c',
                       '\f':r'\f',
                       '\n':r'\n',
                       '\r':r'\r',
                       '\t':r'\t',
                       '\v':r'\v',
                       '\'':r'\'',
                       '\"':r'\"',
                       '\0':r'\0',
                       '\1':r'\1',
                       '\2':r'\2',
                       '\3':r'\3',
                       '\4':r'\4',
                       '\5':r'\5',
                       '\6':r'\6',
                       '\7':r'\7',
                       '\8':r'\8',
                       '\9':r'\9'}
            def raw(text):
                """Returns a raw string representation of text"""
                new_string=''
                for char in text:
                    try: new_string+=escape_dict[char]
                    except KeyError: new_string+=char
                return new_string

            fileName = ''
            lineNo =  ''
            funName =  ''
            code = ''

            ret = str(ret).strip()
            parts = ret.partition('->')
            if parts[1]:
                head = str(parts[0]).strip()
                tail = str(parts[2]).strip()
            else:
                head = str(parts[0])
                tail = None

            headPattern = r'(.*.)\(([0-9].*.)\)(.*.\(\))'
            head = raw(head)
            head = head.replace('\\','/')
            res = re.match(headPattern, head, re.M|re.I)
            if res and len(res.groups())>=2:
                fileName = str(res.groups()[0]).strip()
                lineNo =  str(res.groups()[1]).strip()
                funName =  str(res.groups()[2]).strip()
            if tail: code = tail
            return (fileName, lineNo, funName, code)

	def stackPrint(self):
		print '\n'
		for eachFrame in self.getStackFrameAll():
               		fileName = eachFrame[0]
               		lineNo = eachFrame[1]
               		functionName = eachFrame[2]
               		code = eachFrame[3]
			self.framePrint(fileName, lineNo, functionName, code)
		print '\n'

	def framePrint(self, fileName, lineNo, functionName, code):
            	if code:
			print '#\tFile "%s", line %s, in %s\n#\t\t%s' % (fileName,lineNo,functionName, code)
            	else:
			print '#\tFile "%s", line %s, in %s' % (fileName,lineNo,functionName)

	def getStackFrameAll(self):
		stack = traceback.extract_stack()
		frames = []
       		for eachFrame in stack:
               		fileName = eachFrame[0]
               		lineNo = eachFrame[1]
               		functionName = eachFrame[2]
               		code = eachFrame[3]
               		if functionName == 'pause' or functionName == 'trace_dispatch':
				return frames
			else:
				frames.append(eachFrame)
		return frames

	def getStackFrame(self):
		stack = self.getStackFrameAll()
		return stack[len(stack)-1]

	def write(self, data):
		data = str(data).strip()
		if data and data!='>':
			info = self.traceRetParse(data)
			if info[0] and info[1] and info[2] and (info[2]!='pause()'):
				frame = self.getStackFrame()
				self.framePrint(frame[0],int(frame[1])-1,frame[2],frame[3])

	def flush(self):
		sys.stdout.flush()

	def readline(self):
		res = cmd.confirmDialog(  title='Debug',
		                          message='Maya Python Debugger',
		                          button=[
							'Step Into',
							'Step Next',
							'Step Out',
							'Line Info',
							'Stack',
							'Check Variable',
							'Run',
							'Quit',
							],
		                          defaultButton='Step Into',
		                          cancelButton='Run',
		                          dismissString='Quit'
		                        )
		if res == 'Stack':
			self.stackPrint()
			return 'h\n'

		if res == 'Step Into':
			return 'step\n'

		if res == 'Step Next':
			return 'next\n'

		if res == 'Step Out':
			return 'return\n'

		if res == 'Run':
			return 'continue\n'

		if res == 'Line Info':
			return 'bt\n'

		if res == 'Check Variable':
			return self.__chkVar()

		if res == 'Quit':
			return 'quit\n'

		return 'continue\n'

	def __chkVar(self):
		result = cmd.promptDialog(
				title='Debug Variable',
				message='Local Varible:',
				button=['OK', 'Cancel'],
				defaultButton='OK',
				cancelButton='Cancel',
				dismissString='Cancel')
		text = ''
		if result == 'OK':
			text = cmd.promptDialog(query=True, text=True)

		return 'pp %s\n'%(text)

dbg = myPyDebug()