Future = require('fibers/future')
wait = Future.wait

# creates a function that will call the obj.methodName with a callback and check for error and wait until return using a Future thus making it synchronous
makeSync = (obj, methodName)->
	fn = (args...)->
		# set up a Future
		future = new Future
		
		# create the variable we will store the return result in
		result = null

		# create our callback that will handle checking the error and storing result
		callback = (err, r)->
			#TODO: Check err and throw if it exists
			result = r
			future.return()
		
		# push the callback as the last parameter
		args.push(callback)

		# invoke given method
		obj[methodName].apply(obj, args)
		
		# wait for it to complete and return result
		Future.wait(future)
		return result

	return fn

# proxies all the given methods from source to target, making them synchronous in the process
proxySync = (source, target, methods)->
	for method in methods
		target[method] = makeSync(source, method)

# runs code in a fiber so that functions using Futures will work correctly
sync = (fn)->
	Fiber(fn).run()

exports.sync = sync
exports.makeSync = makeSync
exports.proxySync = proxySync