# STATUS: Untested

getType = (value) ->
	return Null if Null.isTypeOf value
	return Undefined if Undefined.isTypeOf value
	return value.constructor

setType = (value, type) ->
	value.constructor = type if value?
	return value

testType = (value, type) ->
	return _compare getType(value), type

assertType = (value, type) ->
	throw TypeError "A value was a #{getType(value).name} when a #{type.name} was expected." unless testType value, type

compareTypes = (type1, type2) ->
	return _compare type1, type2

validateTypes = (target, specs) ->
	
	for key, spec of specs

		switch TypeUtils.getType spec

			when Function
				spec target, key, target[key]

			when Object
				target[key] = {} unless TypeUtils.testType target[key], Object
				TypeUtils.validateTypes target[key], spec

			when Array
				[ type, defalt ] = spec
				target[key] = defalt if target[key] is undefined
				assert TypeUtils.testType(target[key], type) if type?

	return

module.exports = {
	getType
	setType
	testType
	assertType
	compareTypes
	validateTypes
}

#
# Internal
#

Null = require "./../Null"
Undefined = require "./../Undefined"

_is = (type1, type2) -> type1 is type2
_compare = _is

Object.defineProperties module.exports,
	_is:
		value: _is
	_compare:
		get: -> _compare
		set: (fn) -> _compare = fn
