/* global CQ, $CQ, CrownpeakDQM */
/***
 * Requires:
 * - CQ
 * - $CQ
 * - CrownpeakDQM
 * - CrownpeakDQM.Type
 */
(function(CQ, $, CrownpeakDQM) {

	CrownpeakDQM.Injector = (function() {
		var api = {},
			sequences = {
				originalFirst: function(original, injected) {
					return function() {
						var result = original.apply(this, arguments);

						injected.apply(this, arguments);

						return result;
					};
				},
				originalLast: function(original, injected) {
					return function() {
						injected.apply(this, arguments);

						return original.apply(this, arguments);
					};
				}
			},
			isFunction = function(obj) {
				return typeof(obj) === "function";
			};

		function inject(targetClass, injected, sequence) {
			$.each(injected, function(id, injectedItem) {
				var original = targetClass.prototype[id];

				if (isFunction(original) && isFunction(injectedItem)) {
					targetClass.prototype[id] = sequence(original, injectedItem);
				}
			});
		}

		api.injectAfter = function(targetClass, injected) {
			inject(targetClass, injected, sequences.originalFirst);
		};

		api.injectBefore = function(targetClass, injected) {
			inject(targetClass, injected, sequences.originalLast);
		};

		return api;
	}());

}(CQ, $CQ, CrownpeakDQM));

