Ext.define('Ext.ux.util.ComponentController', {
	
	statics: {
		uppercaseFirst: function (str) {
			s = str + ''; //str.toLowerCase();
			return s.replace(/\b./g, function(m) {
				return m.toUpperCase();
			});
		}
	},

	initComponentController: function () {

		var i_cmp = this;

		i_cmp.__children = {};

		i_cmp.initReferences();

		return i_cmp;
	},

	initReferences: function () {

		var i_cmp = this,
			a_refs = i_cmp.refs;

		if (a_refs && a_refs.length) {
			Ext.Array.each(a_refs, function (o_ref) {

				var s_ref = o_ref.ref,
					s_method = 'get' + Ext.ux.util.ComponentController.uppercaseFirst(s_ref),
					s_selector = o_ref.selector;

				// Check if method getter already exists
				if (i_cmp[s_method]) {
					throw new Error('Method ' + s_method + ' already exists on ', i_cmp.$className);
				}
				else {
					i_cmp[s_method] = function () {

						var i_found;

						// Check if we have already found and stored the reference
						if (i_cmp.__children[s_ref]) {
							i_found = i_cmp.__children[s_ref];
						}

						// We have not, attempt to query and store it
						else {
							i_found = i_cmp.down(s_selector);
							if (i_found) i_cmp.__children[s_ref] = i_found;
						}

						return i_found;
					};
				}
			});
		}
	},

	control: function (o_control) {

		var i_cmp = this;

		Ext.Object.each(o_control, function (s_ref, o_listeners) {

			// Look for a referenced child and set the scope
			var i_child = i_cmp['get' + Ext.ux.util.ComponentController.uppercaseFirst(s_ref)](),
				i_scope = o_listeners.scope || i_cmp;

			// If a child was found - set the control for listeners
			if (i_child && Ext.isFunction(i_child.on)) {
				
				// Add the component controller and a getter to the child
				i_child.__componentController = i_cmp;
				i_child.getComponentController = function () {
					return this.__componentController;
				};

				// Pipe the event through to the controller if child was found
				// and event managment was present
				Ext.Object.each(o_listeners, function (s_key, f_action) {
					if (s_key != 'scope') {
						i_child.on(s_key, f_action, i_scope);
					}
				});
			}
		});

		return i_cmp;
	}
});
