# STATUS: Unfinished

Factory = module.exports = (opts) ->

	Validator.validate
		assert: true
		target: opts
		types: _types
		defaults: _defaults

	return (args...) ->
		opts.validator.apply null, args
		initialize = $.utils opts, args
		instance = opts.constructor.apply { initialize }, args
		initialize instance if !initialized and Kind.is { type: getType(instance), kind: Object }
		return instance

$$regex = /^function \(\$\$(\,|\))/

# Exposes an internal object when a passed function has its first argument named `$$`.
FunctionUtils.$$ = ($$) ->
	return (fn, receiver, args...) ->
		return fn. if testType(fn, Function) and $$regex.test fn.toString()

#
# Internal
#

{ noop } = require "./FunctionUtils"
{ getType, testType, assertType } = require "./TypeUtils"

Constructor = require "./Constructor"
Validator = require "./Validator"
Kind = require "./KindUtils"

_types =
	validator: Kind(Function)
	initializer: Kind(Function)
	constructor: Kind(Function)

_defaults =
	initializer: noop
	validator: noop
	constructor: noop

_SuperConstructor = (type) ->
	return -> 
		assertType type.kind, Type
		type.kind

_SuperMethod = (object, key) -> 

	assertType key, String

	property = object[key]
	return property if property isnt undefined

	type = getType object

	loop

		property = type.prototype[key]
		break if property isnt undefined

		type = getKind type
		break unless type?

	return property

_addSuper = (instance, fn, args) ->
	if fn? and $regex.test fn.toString()
		args = args.slice()
		args.unshift (args...) ->
			Property.of 
	return args


_createInitFunc = (opts, args) ->
	if opts.constructor? and _initializerRegex.test opts.constructor.toString()
		_args = args.slice()
		initialized = false
		return (instance) ->
			return if initialized
			initialized = true
			return opts.initializer.apply instance, _addSuper(opts.initializer, args)
