BindingInterface:: = Object.create BindingInterfacePrivate,
	of:					get: ()-> METHOD_of if not @stage			#=== if stage is 0
	ofEvent:			get: ()-> METHOD_ofEvent if not @stage		#=== if stage is 0
	chainTo:			get: ()-> METHOD_chainTo if @stage			#=== if stage is 1 or 2
	set:				get: ()-> METHOD_set if @stage				#=== if stage is 1 or 2
	get:				get: ()-> METHOD_get if @stage				#=== if stage is 1 or 2
	transformSelf:		get: ()-> METHOD_transformSelf if @stage is 1
	transform:			get: ()-> METHOD_transform if @stage is 2
	transformAll:		get: ()-> METHOD_transformAll if @stage is 2
	condition:			get: ()-> METHOD_condition if @stage is 2
	conditionAll:		get: ()-> METHOD_conditionAll if @stage is 2
	bothWays:			get: ()-> METHOD_bothWays if @stage is 2
	unBind:				get: ()-> METHOD_unBind if @stage is 2
	pollEvery:			get: ()-> METHOD_pollEvery if @stage is 2
	stopPolling:		get: ()-> METHOD_stopPolling if @stage is 2
	updateSubsOnEvent:	get: ()-> METHOD_updateSubsOnEvent if @stage is 2
	removeEvent:		get: ()-> METHOD_removeEvent if @stage is 2
	throttle:			get: ()-> METHOD_throttle if @stage #=== if stage is 1 or 2
	setOption:			get: ()-> METHOD_setOption if @stage is 2
	to:					get: ()-> genProxiedInterface(@) if @stage is 1
	toEvent:			get: ()-> genProxiedEventInterface(@) if @stage is 1
	and:				get: ()->
							cloneInterface = @selfClone(1)
							
							if @stage is 2
								return cloneInterface
							else if @stage is 1
								if not cloneInterface._.isMulti
									cloneBinding = cloneInterface._
									cloneInterface._ = new GroupBinding(cloneInterface)
									cloneInterface._.addBinding(cloneBinding)
								
								return genProxiedInterface(cloneInterface, true)
	

	once:				get: ()-> if @stage is 1
							interfaceToReturn = @selfClone(1)
							interfaceToReturn.updateOnce = true
							return interfaceToReturn

	# ==== Aliases =================================================================================
	update:				get: ()-> @set
	twoWay:				get: ()-> @bothWays
	pipe:				get: ()-> @chainTo




METHOD_of = (object)->
	throwErrorBadArg(object) unless checkIf.isObject(object) or checkIf.isFunction(object)
	
	if checkIf.isBindingInterface(object)
		object = object.object

	@stage = 1
	return @setObject(object)






METHOD_ofEvent = (eventName, customInMethod, customOutMethod)->
	if not eventName or not checkIf.isString(eventName)
		throwErrorBadArg(eventName)

	else if isNaN parseInt(@property)
		throwWarning('badEventArg',1)

	@eventName = eventName
	@selector = @property+'#'+@eventName
	@customEventMethod = 
		'in': customInMethod
		'out': customOutMethod

	return @




METHOD_chainTo = (subject, specificOptions, saveOptions)->
	return SimplyBind(@subs[@subs.length-1]).to(subject, specificOptions, saveOptions)





METHOD_set = (newValue)->
	@_.setValue(newValue, @placeholder)
	return @


METHOD_get = ()->
	if not @placeholder or @_.isMulti
		return @_.value
	else
		return @_.pholderValues[@placeholder]









METHOD_transformSelf = (transformFn)-> # Applied only to the last sub
	if not checkIf.isFunction(transformFn)
		throwWarning('fnOnly',1)
	else
		@_.setSelfTransform(transformFn, @options.updateOnBind)
		
	return @


METHOD_transform = (transformFn)-> # Applied only to the last sub
	@_.addModifierFn('transforms', @subs.slice(-1), transformFn, @options.updateOnBind)
	return @


METHOD_transformAll = (transformFn)-> # Applied to entrie subs set		
	@_.addModifierFn('transforms', @subs, transformFn, @options.updateOnBind)
	return @






METHOD_condition = (conditionFn)-> # Applied only to the last sub
	@_.addModifierFn('conditions', @subs.slice(-1), conditionFn)
	return @


METHOD_conditionAll = (conditionFn)-> # Applied to entrie subs set
	@_.addModifierFn('conditions', @subs, conditionFn)
	return @







METHOD_bothWays = (altTransform)-> # Applied only to the last sub
	sub = @subs[@subs.length-1] # Last Proxied
	subBinding = sub._
	bindings = if @_.isMulti then @_.bindings else [@_]

	subBinding.addSub(@_, sub.options)
	
	for binding in bindings
		originTransform = binding.transforms and binding.transforms[subBinding.ID]
		originCondition = binding.conditions and binding.conditions[subBinding.ID]

		if originTransform or altTransform
			transformToUse = if checkIf.isFunction(altTransform) then altTransform else originTransform
			subBinding.setModifierFn(@_.ID, 'transforms', transformToUse) if transformToUse and altTransform isnt false

		if originCondition
			subBinding.setModifierFn(@_.ID, 'conditions', originCondition)

	return @



METHOD_unBind = (bothWays)-> # Applied to all subs
	@_.removeSub(sub._, bothWays) for sub in @subs
	return @





METHOD_pollEvery = (time)->
	@_.addPollInterval(time)
	return @



METHOD_stopPolling = ()->
	@_.removePollInterval()
	return @






METHOD_updateSubsOnEvent = (eventName, customMethod)->
	@_.registerEvent(eventName, customMethod)
	return @


METHOD_removeEvent = (eventName, customMethod)->
	@_.unRegisterEvent(eventName, customMethod)
	return @



METHOD_throttle = (delay)->
	if delay and checkIf.isNumber(delay)
		@_.throttleRate = delay

	else if delay is false
		delete @_.throttleRate

	return @



METHOD_setOption = (optionName, newValue)->
	@_.subOpts[@subs[@subs.length-1]._.ID][optionName] = newValue
	
	return @

























