import rox
from rox import choices, croak, g
import os, sys
import options

def choose_backdrop():
	# We've been called by the filer; print the backdrop to use.
	try:
		if options.mode == 'Random':
			choose_random()
		else:
			choose_advanced()
	except:
		rox.report_exception()

def choose_random():
	def choose():
		print choose_random_image()
	choose_on_timeout(choose)

def choose_on_timeout(callback):
	"""Call callback now and on each timeout (if set). callback may return a
	function which should be used to remove any temporary file."""
	from select import select
	time_between_updates = options.change_time.value * 60	# in s

	clean_fn = None
	try:
		while 1:
			clean_fn = callback()
			sys.stdout.flush()
			
			if sys.stdin.readline() != 'ok\n' or not time_between_updates:
				break

			if clean_fn: clean_fn()
			clean_fn = None

			ready = select([sys.stdin], [], [], time_between_updates)[0]
			if ready:
				break	# Ready to read end-of-file => pinboard closed
	finally:
		if clean_fn: clean_fn()

def choose_random_image():
	def images(path, style):
		if not path:
			return []
		ret = []
		for file in os.listdir(path):
			ret.append((os.path.join(path, file), style))
		return ret

	images = images(choices.load('Wallpaper', 'Centred'), 'centre') + \
		 images(choices.load('Wallpaper', 'Scaled'), 'scale') + \
		 images(choices.load('Wallpaper', 'Tiled'), 'tile')

	if not images:
		croak('No images found! Run Wallpaper and use Setup \
to choose some images.')

	import random

	image, style = random.choice(images)
	return "%s %s" % (style, image)

def create_tmp_file():
	import random
	t = 1
	while 1:
		tmpfile = '/tmp/wallpaper-' + `random.randint(1, 100000)`
		try:
			return (tmpfile,
				os.open(tmpfile, os.O_CREAT | os.O_EXCL | os.O_RDWR,
				        0600))
		except:
			if t < 10:
				t += 1
			else:
				raise

def choose_advanced():
	def choose():
		(tmpfile, out) = create_tmp_file()
		child = os.fork()
		if child == 0:
			try:
				if out != 1:
					os.dup2(out, 1)
					os.close(out)
				os.system(options.advanced_command)
				os._exit(0)
			finally:
				os._exit(1)
		os.close(out)
		(pid, status) = os.waitpid(child, 0)
		assert pid == child
		if os.WIFEXITED(status) and os.WEXITSTATUS(status):
			rox.alert("Command '%s' failed!" % options.advanced_command)
		print "centre", tmpfile
		def clean(): os.unlink(tmpfile)
		return clean
	choose_on_timeout(choose)
