/**
	_enyo.Node_ is a control that creates structured trees based on Enyo's child
	component hierarchy format, e.g.:

		{kind: "Node", icon: "images/folder-open.png", content: "Tree",
			expandable: true, expanded: true, components: [
				{icon: "images/file.png", content: "Alpha"},
				{icon: "images/folder-open.png", content: "Bravo",
					expandable: true, expanded: false, components: [
						{icon: "images/file.png", content: "Bravo-Alpha"},
						{icon: "images/file.png", content: "Bravo-Bravo"},
						{icon: "images/file.png", content: "Bravo-Charlie"}
					]
				}
			]
		}

	The default kind of components within a node is itself _enyo.Node_, so only
	the	top-level node of the tree needs to be explicitly defined as such.

	When an expandable tree node expands, an _onExpand_ event is sent; when it
	is tapped, a _nodeTap_ event is sent.

	When the optional property _onlyIconExpands_ is set to true, expandable
	nodes may only be opened by tapping the icon; tapping the content label
	will fire the _nodeTap_ event, but will not expand the node.
*/

enyo.kind({
	name: "enyo.Node",
	published: {
		//* @public
		//* Whether or not the Node is expandable and has child branches
		expandable: false,
		//* Open/closed state of the current Node
		expanded: false,
		//* Path to image to be used as the icon for this Node
		icon: "",
		/**
			Optional flag that, when true, causes the Node to expand only when
			the icon is tapped; not when the contents are tapped
		*/
		onlyIconExpands: false,
		//* @protected
		//* Adds or removes the Enyo-selected CSS class.
		selected: false
	},
	style: "padding: 0 0 0 16px;",
	content: "Node",
	defaultKind: "Node",
	classes: "enyo-node",
	components: [
		{name: "icon", kind: "Image", showing: false},
		{kind: "Control", name: "caption", Xtag: "span", style: "display: inline-block; padding: 4px;", allowHtml: true},
		{kind: "Control", name: "extra", tag: 'span', allowHtml: true}
	],
	childClient: [
		{kind: "Control", name: "box", classes: "enyo-node-box", Xstyle: "border: 1px solid orange;", components: [
			{kind: "Control", name: "client", classes: "enyo-node-client", Xstyle: "border: 1px solid lightblue;"}
		]}
	],
	handlers: {
		ondblclick: "dblclick"
	},
	events: {
		//* @public
		//* Fired when the Node is tapped
		onNodeTap: "nodeTap",
		//* Fired when the Node is double-clicked
		onNodeDblClick: "nodeDblClick",
		/**
			Fired when the Node expands or contracts, as indicated by the
			'expanded' property in the event data
		*/
		onExpand: "nodeExpand",
		//* Fired when the Node is destroyed
		onDestroyed: "nodeDestroyed"
	},
	//
	//* @protected
	create: function() {
		this.inherited(arguments);
		//this.expandedChanged();
		//this.levelChanged();
		this.selectedChanged();
		this.iconChanged();
	},
	destroy: function() {
		this.doDestroyed();
		this.inherited(arguments);
	},
	initComponents: function() {
		// TODO: optimize to create the childClient on demand
		//this.hasChildren = this.components;
		if (this.expandable) {
			this.kindComponents = this.kindComponents.concat(this.childClient);
		}
		this.inherited(arguments);
	},
	//
	contentChanged: function() {
		//this.$.caption.setContent((this.expandable ? (this.expanded ? "-" : "+") : "") + this.content);
		this.$.caption.setContent(this.content);
	},
	iconChanged: function() {
		this.$.icon.setSrc(this.icon);
		this.$.icon.setShowing(Boolean(this.icon));
	},
	selectedChanged: function() {
		this.addRemoveClass("enyo-selected", this.selected);
	},
	rendered: function() {
		this.inherited(arguments);
		if (this.expandable && !this.expanded) {
			this.quickCollapse();
		}
	},
	//
	addNodes: function(inNodes) {
		this.destroyClientControls();
		for (var i=0, n; (n=inNodes[i]); i++) {
			this.createComponent(n);
		}
		this.$.client.render();
	},
	addTextNodes: function(inNodes) {
		this.destroyClientControls();
		for (var i=0, n; (n=inNodes[i]); i++) {
			this.createComponent({content: n});
		}
		this.$.client.render();
	},
	//
	tap: function(inSender, inEvent) {
		if(!this.onlyIconExpands) {
			this.toggleExpanded();
			this.doNodeTap();
		} else {
			if((inEvent.target==this.$.icon.hasNode())) {
				this.toggleExpanded();
			} else {
				this.doNodeTap();
			}
		}
		return true;
	},
	dblclick: function(inSender, inEvent) {
		this.doNodeDblClick();
		return true;
	},
	//
	toggleExpanded: function() {
		this.setExpanded(!this.expanded);
	},
	quickCollapse: function() {
		this.removeClass("enyo-animate");
		this.$.box.applyStyle("height", "0");
		var h = this.$.client.getBounds().height;
		this.$.client.setBounds({top: -h});
	},
	_expand: function() {
		this.addClass("enyo-animate");
		var h = this.$.client.getBounds().height;
		this.$.box.setBounds({height: h});
		this.$.client.setBounds({top: 0});
		setTimeout(this.bindSafely(function() {
			// things may have happened in the interim, make sure
			// we only fix height if we are still expanded
			if (this.expanded) {
				this.removeClass("enyo-animate");
				this.$.box.applyStyle("height", "auto");
			}
		}), 225);
	},
	_collapse: function() {
		// disable transitions
		this.removeClass("enyo-animate");
		// fix the height of our box (rather than 'auto'), this
		// gives webkit something to lerp from
		var h = this.$.client.getBounds().height;
		this.$.box.setBounds({height: h});
		// yield the thead so DOM can make those changes (without transitions)
		setTimeout(this.bindSafely(function() {
			// enable transitions
			this.addClass("enyo-animate");
			// shrink our box to 0
			this.$.box.applyStyle("height", "0");
			// slide the contents up
			this.$.client.setBounds({top: -h});
		}), 25);
	},
	expandedChanged: function(inOldExpanded) {
		if (!this.expandable) {
			this.expanded = false;
		} else {
			var event = {expanded: this.expanded};
			this.doExpand(event);
			if (!event.wait) {
				this.effectExpanded();
			}
		}
	},
	effectExpanded: function() {
		if (this.$.client) {
			if (!this.expanded) {
				this._collapse();
			} else {
				this._expand();
			}
		}
		//this.contentChanged();
	}
});