#!/usr/bin/env python
"""
Check for running python and only start a new one if there's no old instance
hanging around.
"""

import sys, os, re

from Xlib import X, display, Xutil

vimpath = "/usr/bin"
if not os.path.exists(os.path.join(vimpath, "vim")):
	vimpath = "/usr/local/bin"

if os.environ.has_key("DISPLAY"):
	vimcommand = os.path.join(vimpath, "gvim")
else:
	vimcommand = os.path.join(vimpath, "vim")


class Error(Exception):
	pass

class NoRunningWindow(Error):
	pass


def startvim(opts, args):
	os.execv(vimcommand, [vimcommand]+opts+args)


def parseCommandLine():
	opts, args = [], []
	for arg in sys.argv[1:]:
		if arg.startswith("-"):
			opts.append(arg)
		else:
			args.append(arg)
	return opts, args


def makeVimTitleRe(targetFile):
	dir, base = os.path.dirname(targetFile), os.path.basename(targetFile)
	dir = dir.replace(os.environ["HOME"], "~")
	return "%s (\+ )?\(%s\) - G?VIM\d*$"%(base, dir)

def getAllChildWins(win):
	wl = win.query_tree()
	for win in wl.children:
		for child in getAllChildWins(win):
			yield child
		yield win

def getWindowForTitleRe(titleRe):
	titlePat = re.compile(titleRe)
	dpy = display.Display()
	screen = dpy.screen(dpy.get_default_screen())
	for win in getAllChildWins(screen.root):
		name = win.get_wm_name()
		if name and titlePat.match(name):
			return dpy, win
	raise NoRunningWindow(titleRe)

def _raiseForTitle(titleRe):
	print "Raising existing instance"
	dpy, win = getWindowForTitleRe(titleRe)
	win.unmap()
	win.map()
	dpy.sync()
	win.warp_pointer(50, 50)
	dpy.sync()
	
def raiseRunningWindows(opts, args):
	swpFileName = os.path.join(os.path.dirname(args[0]), "."+
		re.sub(r"^\.", "", os.path.basename(args[0])+".swp"))
	if not os.path.exists(swpFileName):
		raise NoRunningWindow, "No swapfile found"
	realTarget = os.path.realpath(args[0])
	_raiseForTitle(makeVimTitleRe(realTarget))


if __name__=="__main__":
	opts, args = parseCommandLine()
	if len(args)==0:
		startvim(opts, args)
	elif len(args)>1:
		sys.stderr.write("More than one arg -- leaving mess to vim.\n")
		startvim(opts, args)
	if not os.environ.has_key("DISPLAY"):
		startvim(opts, args)
	try:
		raiseRunningWindows(opts, args)
	except NoRunningWindow:
		startvim(opts, args)
