/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/


dojo.provide("dojo.widget.TreeDndControllerV3");

dojo.require("dojo.dnd.TreeDragAndDropV3");
dojo.require("dojo.experimental");

dojo.experimental("Tree drag'n'drop' has lots of problems/bugs, it requires dojo drag'n'drop overhaul to work, probably in 0.5");

dojo.widget.defineWidget(
	"dojo.widget.TreeDndControllerV3",
	[dojo.widget.HtmlWidget, dojo.widget.TreeCommon],
	function() {
		this.dragSources = {};
		this.dropTargets = {};
		this.listenedTrees = {};
	},
{
	listenTreeEvents: ["afterChangeTree","beforeTreeDestroy", "afterAddChild"],
	listenNodeFilter: function(elem) { return elem instanceof dojo.widget.Widget},

	initialize: function(args) {
		this.treeController = dojo.lang.isString(args.controller) ? dojo.widget.byId(args.controller) : args.controller;

		if (!this.treeController) {
			dojo.raise("treeController must be declared");
		}

	},

	onBeforeTreeDestroy: function(message) {
		this.unlistenTree(message.source);
	},

	// first Dnd registration happens in addChild
	// because I have information about parent on this stage and can use it
	// to check locking or other things
	onAfterAddChild: function(message) {
		//dojo.debug("Dnd addChild "+message.child);
		this.listenNode(message.child);
	},


	onAfterChangeTree: function(message) {
		/* catch new nodes on afterAddChild, because I need parent */
		if (!message.oldTree) return;

		//dojo.debug("HERE");

		if (!message.newTree || !this.listenedTrees[message.newTree.widgetId]) {
			this.processDescendants(message.node, this.listenNodeFilter, this.unlistenNode);
		}

		if (!this.listenedTrees[message.oldTree.widgetId]) {
			// we have new node
			this.processDescendants(message.node, this.listenNodeFilter, this.listenNode);
		}
		//dojo.profile.end("onTreeChange");
	},


	/**
	 * Controller(node model) creates DndNodes because it passes itself to node for synchroneous drops processing
	 * I can't process DnD with events cause an event can't return result success/false
	*/
	listenNode: function(node) {

		//dojo.debug("listen dnd "+node);
		//dojo.debug((new Error()).stack)
		//dojo.profile.start("Dnd listenNode "+node);
		if (!node.tree.DndMode) return;
		if (this.dragSources[node.widgetId] || this.dropTargets[node.widgetId]) return;


		/* I drag label, not domNode, because large domNodes are very slow to copy and large to drag */

		var source = null;
		var target = null;


		if (!node.actionIsDisabled(node.actions.MOVE)) {
			//dojo.debug("reg source")

			//dojo.profile.start("Dnd source "+node);
			var source = this.makeDragSource(node);
			//dojo.profile.end("Dnd source "+node);

			this.dragSources[node.widgetId] = source;
		}

		//dojo.profile.start("Dnd target "+node);
		//dojo.debug("reg target");
		var target = this.makeDropTarget(node);
		//dojo.profile.end("Dnd target "+node);

		this.dropTargets[node.widgetId] = target;

		//dojo.profile.end("Dnd listenNode "+node);


	},

	/**
	 * Factory method, override it to create special source
	 */
	makeDragSource: function(node) {
		return new dojo.dnd.TreeDragSourceV3(node.contentNode, this, node.tree.widgetId, node);
	},


	/**
	 * Factory method, override it to create special target
	 */
	makeDropTarget: function(node) {
		 return new dojo.dnd.TreeDropTargetV3(node.contentNode, this.treeController, node.tree.DndAcceptTypes, node);
	},

	unlistenNode: function(node) {

		if (this.dragSources[node.widgetId]) {
			dojo.dnd.dragManager.unregisterDragSource(this.dragSources[node.widgetId]);
			delete this.dragSources[node.widgetId];
		}

		if (this.dropTargets[node.widgetId]) {
			dojo.dnd.dragManager.unregisterDropTarget(this.dropTargets[node.widgetId]);
			delete this.dropTargets[node.widgetId];
		}
	}

});
