+/**
+Base Class from which almost all widgets are based overall the project
+
+The main idea behind constructing a new widget toolkit instead of using one of the many high quality widget
+toolkits avaliable is that we considered that currently, no widget system provides all the features that where
+required for this project.
+
+Features of the widget system
+* A custom and easy to handle event binding, dispatching and manipulation, with some sort of bubbling support
+* A module system which we can use to include specific behaviour to any widget and reuse the code where needed
+* A tree structure support for the widgets that the event system could bubble, and that also serves as
+* A navigation system.
+* The widgets must be able to be grouped to form more complex widgets
+* Remove the complexity of DOM manipulation and handling
+* A way to wrap widgets at our convenience to reuse widgets avaliable and make them comly to our needs
+without the need to hack those widgets, that would force us to maintain the new versions of those widgets
+and that is a very complex task when widgets become so complex.
+* A widget system that would allow us to start wrapping some widgets for a fast start and later code our own widgets
+at will.
+* expose a consistent API that allow us to choose the use of widgets by API calls and user interaction at will and with the same
+clearance and capacity
+* an easy way to allow subclasing widgets
+* an easy way to provide new html, class, and css for a specific instance of a widget that would remove us the need
+to create complex inheritance structures that are hard to maintain.
+
+Usage Example.
+
+The most basic usage of a widget is to simply create an instance and render it at a target element
+in this case body
+var myWidgetInstance = new Breezi.Widget();
+myWidgetInstance.render(document.body);
+
+like this widget does renders does not display anything so lets give it something to display first
+var myWidgetInstance = new Breezi.Widget();
+myWidgetInstance.element.html('Im a simple widget');
+myWidgetInstance.render(document.body);
+
+this reveals that internally every widget has an element property that is initialized by default to a jQuery Instance
+this allow easy DOM manipulation, animation and operations handled by a high quality third party library.
+@class Widget
+@namespace Breezi
+@inlcudes CustomEventSupport
+@includes NodeSupport
+@dependency Neon
+@dependency CustomEventSupport
+@dependency NodeSupport
+**/
+Class('Widget').includes(CustomEventSupport, NodeSupport)({
+
+ /**
+ The default html for the widget, at the most simple case this is just a div.
+ @name HTML
+ @attribute_type CONSTANT
+ @type String
+ */
+ HTML : '<div></div>',
+
+ /**
+ the widget container default class for all widgets is widget
+ @name ELEMENT_CLASS
+ @constant
+ @type String
+ **/
+ ELEMENT_CLASS : 'widget',
+
+ /**
+ @property prototype
+ @type Object
+ **/
+ prototype : {
+ /**
+ Holds the active status of the widget
+ By default all widgets are deactivated waiting
+ for an action to activate it.
+ @property active <public> [Boolean] (false)
+ **/
+ active : false,
+
+ /**
+ Holds the disabled status of the widget
+ By default all widgets are enabled and only by
+ API could be disabled.
+ @property disabled <public> [Boolean] (false)
+ **/
+ disabled : false,
+
+ __destroyed : false,
+
+ init : function init(config) {
+ var property;
+
+ Object.keys(config || {}).forEach(function (propertyName) {
+ this[propertyName] = config[propertyName];
+ }, this);
+
+ if (this.element == null) {
+ this.element = $(this.constructor.HTML.replace(/\s\s+/g, ''));
+ this.element.addClass(this.constructor.ELEMENT_CLASS);
+ }
+
+ if (this.hasOwnProperty('className') === true) {
+ this.element.addClass(this.className);
+ }
+ },
+
+ /**
+ implementation of the activate method, when you need an override, do it
+ over this method instead of doing it on activate
+ @property _activate <private> [Function]
+ @return undefined [undefined]
+ **/
+ _activate : function _activate() {
+ this.active = true;
+ this.element.addClass('active');
+ },
+
+ /**
+ Public activation method for widget, you can listen to this event
+ to take some other actions, but the most important part of this
+ method is that it runs its default action, (its activation)
+ this method uses _activate as its implementation to maintain
+ the events order intact.
+ @property activate <public> [Function]
+ @method
+ @dispatch beforeActivate
+ @dispatch activate
+ @return this [Widget]
+ **/
+ activate : function activate() {
+ if (this.__destroyed === true) {
+ console.warn('calling on destroyed object');
+ }
+ this.dispatch('beforeActivate');
+ this._activate();
+ this.dispatch('activate');
+ return this;
+ },
+
+ /**
+ deactivation implementation
+ this is the oposite of activation method and as such it must be
+ treated as important as that.
+ @property _deactivate <private> [Function]
+ @method
+ @return undefined [undefined]
+ **/
+ _deactivate : function _deactivate() {
+ this.active = false;
+ this.element.removeClass('active');
+ },
+
+ /**
+ Public deactivation method for widget, you can listen to this event
+ to take some other actions, but the most important part of this
+ method is that it runs its default action, (its activation)
+ this method uses _deactivate as its implementation to maintain
+ the events order intact.
+ @property activate <public> [Function]
+ @method
+ @dispatch beforeDeactivatee
+ @dispatch deactivate
+ @return this [Widget]
+ **/
+ deactivate : function deactivate() {
+ if (this.__destroyed === true) {
+ console.warn('calling on destroyed object');
+ }
+ this.dispatch('beforeDeactivate');
+ this._deactivate();
+ this.dispatch('deactivate');
+ return this;
+ },
+
+ /**
+ Enable implementation method
+ if you need to provide a different procedure for enable
+ you must override this method and call "super"
+ @property _enable <private> [Function]
+ @method
+ @return undefined [undefined]
+ **/
+ _enable : function _enable() {
+ this.disabled = false;
+ this.element.removeClass('disable');
+ },
+
+ /**
+ Public enable method, this method should not be
+ overriden.
+ @property enable <public> [Function]
+ @method
+ @return this [Widget]
+ **/
+ enable : function enable() {
+ if (this.__destroyed === true) {
+ console.warn('calling on destroyed object');
+ }
+ this.dispatch('beforeEnable');
+ this._enable();
+ this.dispatch('enable');
+
+ return this;
+ },
+
+ /**
+ Disable implementation
+ @property _disable <private> [Function]
+ @return undefined [undefined]
+ **/
+ _disable : function _disable() {
+ this.disabled = true;
+ this.element.addClass('disable');
+ },
+
+ /**
+ Disables the widget, the idea behind disabling a widget
+ comes from DOM form elements. so following this idea
+ all widgets can be disabled and queried for its disabled
+ state via the disabled property.
+ Same as DOM form elements there is feedback and that is why
+ the default implementation sets the "disable" class
+ on the element so proper visual feedback can be provided
+ to the user.
+ @property disable <public> [Function]
+ @method
+ @return this [Widget]
+ **/
+ disable : function disable() {
+ if (this.__destroyed === true) {
+ console.warn('calling on destroyed object');
+ }
+ this.dispatch('beforeDisable');
+ this._disable();
+ this.dispatch('disable');
+
+ return this;
+ },
+
+ /**
+ Destroy implementation. Its main responsabilities are cleaning
+ all references to other objects so garbage collector can collect
+ the memory used by this and the other objects
+ @property _destroy <private> [Function]
+ @method
+ @return undefined [undefined]
+ **/
+ _destroy : function _destroy() {
+ var childrenLength;
+
+ if (this.element) {
+ this.element.remove();
+ }
+
+ if (this.children !== null){
+ childrenLength = this.children.length;
+ while(childrenLength > 0){
+ this.children[0].destroy();
+ if (this.children.length === childrenLength) {
+ this.children.shift();
+ }
+ childrenLength--;
+ }
+ }
+
+ if (this.parent) {
+ this.parent.removeChild(this);
+ }
+
+ this.children = null;
+ this.element = null;
+ },
+
+ /**
+ Destroy public method, this one should not be replaced
+ @property destroy <public> [Function]
+ @method
+ @return null [null]
+ **/
+ destroy : function destroy() {
+ if (this.__destroyed === true) {
+ console.warn('calling on destroyed object');
+ }
+
+ this.dispatch('beforeDestroy');
+ this._destroy();
+ this.dispatch('destroy');
+
+ this.eventListeners = null;
+ this.__destroyed = true;
+
+ return null;
+ },
+
+ /**
+ The render method is the mechanism by which you pass a widget from
+ living only on memory to get into the DOM and with this into the
+ application flow. The recomendation is that render is the last method
+ of the setup of a widget, including appending its children. this is
+ because once a widget gets renderer, further operations cause browser
+ reflows, and DOM operations are slower than memory operations.
+ This method shoudl not be replaced by its children.
+ @property render <public> [Function]
+ @method
+ @argument element <required> [JQuery] (undefined) This is the element
+ into which the widget will be appended.
+ @argument beforeElement <optional> [jQuery] (undefined) this is the element
+ that will be used as a reference to insert the widgets element. this argument
+ must be a child of the "element" argument.
+ @return this [Widget]
+ **/
+ render : function render(element, beforeElement) {
+ if (this.__destroyed === true) {
+ console.warn('calling on destroyed object');
+ }
+ this.dispatch('beforeRender', {
+ element : element,
+ beforeElement : beforeElement
+ });
+ if (beforeElement) {
+ this.element.insertBefore(beforeElement);
+ } else {
+ this.element.appendTo(element);
+ }
+ this.dispatch('render');
+ return this;
+ }
+ }
+});