/*global define*/

define([
	'jquery',
	'backbone',
	'underscore',
	'epoxy'
], function ($, Backbone, _, Epoxy) {

	'use strict';

	/**
	 * View model
	 */
	var ViewModel = Epoxy.Model.extend({

		/**
		 * Default model values
		 * @type {Object}
		 */
		defaults: {
			loaded: false,
			active: false,
			loadedComponents: {},
			target: '',
			role: '',
			view: '',
			replace: false,
			rendered: false,
			children: undefined,
			default: undefined
		},


		/**
		 * Computed properites
		 * @type {Object}
		 */
		computeds: {
			activeChild: {
				deps: ['children'],
				get: function (children) {
					return children.active(role);
				}
			}
		},


		/**
		 * Initialize
		 */
		initialize: function () {

			this.set('children', new ViewsCollection());
			this.set('loadedComponents', {
				loader: false,
				children: false
			});
		},


		/**
		 * Triggered by the view on load
		 */
		onLoaded: function () {

			this.trigger('loaded', this);
		}
	});


	/**
	 * Views collection - declared here because of circular dependencies
	 */
	var ViewsCollection = Backbone.Collection.extend({

		/**
		 * Default model
		 * @type {Function}
		 */
		model: ViewModel,


		/**
		 * How many of the children have loaded?
		 * @type {Number}
		 */
		loadedCount: 0,


		/**
		 * Add a child to the collection from a view definition
		 * @param {Object} child
		 */
		addFromDefinition: function (child) {

			var view = child.view ? child.view : child,
				target = child.target || undefined,
				Constructor = typeof view === 'function' ? view : undefined;


			// New instance of the child if we need to
			if (Constructor) {
				view = new Constructor({
					collection: child.collection || view.prototype.collection,
					model: child.model || view.prototype.model
				});
			}

			// New model if the view doesn't have one
			var viewModel = view.viewModel || new this.model();


			// Listen to the view for load events
			viewModel.listenToOnce(view, 'loaded', viewModel.onLoaded);


			// Set model properties
			viewModel.set({
				id: view.id,
				view: view,
				target: target,
				replace: child.replace,
				role: child.role || '',
				default: child.default
			});


			// Let the view know about its model if it doesn't already
			view.viewModel = viewModel;


			// Add the model to the collection
			this.add(viewModel);
		},


		/**
		 * Get the child active in a role
		 * @return {Object}
		 */
		active: function (role) {

			if (!role) {
				return;
			}

			return this.findWhere({
				active: true,
				role: role
			});
		}
	});


	return ViewModel;
});
@@ -545,43 +545,8 @@
 ild:
- %7B%0A%09%09%09%09deps: %5B'children'%5D,%0A%09%09%09%09get:
  fun
@@ -572,44 +572,34 @@
 %09%09%09%09
-%09
 return 
-children
+this
 .active
-(role);%0A%09%09%09%09%7D
+Child();
 %0A%09%09%09
@@ -792,23 +792,195 @@
 %0A%09%09%09%7D);%0A
-
 %09%09%7D,%0A%0A%0A
+%09%09/**%0A%09%09 * Get the active child for a role%0A%09%09 * @param %7BString%7D role%0A%09%09 */%0A%09%09activeChild: function (role) %7B%0A%09%09%09return this.get('children').active(role %7C%7C 'primary');%0A%09%09%7D%0A%0A%0A
 %09%09/**%0A%09%09

active child updates