# STATUS: Untested

NamedFunction = require "./internal/NamedFunction"
Type = require "./internal/Type"
Kind = require "./internal/Kind"

Mixin = NamedFunction "Mixin", (opts) ->
	Type.validate opts
		early: [Function]
		late: [Function]
	return Type.set opts, Mixin

# If mixins isn't an Array, no mixins are applied but `initialize` is still called and `target` is still returned.
Mixin.mix = (target, mixins, initialize) ->
	
	hasMixins = Type.is mixins, Array
	earlyResults = null
	
	if hasMixins
		earlyResults = new WeakMap
		for mixin in mixins
			continue unless Type.is mixin.early, Function
			earlyResults.set mixin, mixin.early.call(null, target)
	
	if Type.is initialize, Function
		initialize target
	
	if hasMixins
		for mixin in mixins
			continue unless Type.is mixin.late, Function
			mixin.late.call earlyResults.get(mixin), target
	
	return target

module.exports = Mixin
