/*!
 * jquery.fancytree.menu.js
 *
 * Enable jQuery UI Menu as context menu for tree nodes.
 * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
 *
 * @see http://api.jqueryui.com/menu/
 *
 * Copyright (c) 2014, Martin Wendt (http://wwWendt.de)
 *
 * Released under the MIT license
 * https://github.com/mar10/fancytree/wiki/LicenseInfo
 *
 * @version 2.4.1
 * @date 2014-09-23T19:33
 */

;(function($, window, document, undefined) {

"use strict";

// prevent duplicate loading
// if ( $.ui.fancytree && $.ui.fancytree.version ) {
//     $.ui.fancytree.warn("Fancytree: duplicate include");
//     return;
// }

$.ui.fancytree.registerExtension({
	name: "menu",
	version: "0.0.1",
	// Default options for this extension.
	options: {
		enable: true,
		selector: null,  //
		position: {},    //
		// Events:
		create: $.noop,  //
		beforeOpen: $.noop,    //
		open: $.noop,    //
		focus: $.noop,   //
		select: $.noop,  //
		close: $.noop    //
	},
	// Override virtual methods for this extension.
	// `this`       : is this extension object
	// `this._base` : the Fancytree instance
	// `this._super`: the virtual function that was overridden (member of prev. extension or Fancytree)
	treeInit: function(ctx){
		var opts = ctx.options,
			tree = ctx.tree;

		this._super(ctx);

		// Prepare an object that will be passed with menu events
		tree.ext.menu.data = {
			tree: tree,
			node: null,
			$menu: null,
			menuId: null
		};

//        tree.$container[0].oncontextmenu = function() {return false;};
		// Replace the standard browser context menu with out own
		tree.$container.delegate("span.fancytree-node", "contextmenu", function(event) {
			var node = $.ui.fancytree.getNode(event),
				ctx = {node: node, tree: node.tree, originalEvent: event, options: tree.options};
			tree.ext.menu._openMenu(ctx);
			return false;
		});

		// Use jquery.ui.menu
		$(opts.menu.selector).menu({
			create: function(event, ui){
				tree.ext.menu.data.$menu = $(this).menu("widget");
				var data = $.extend({}, tree.ext.menu.data);
				opts.menu.create.call(tree, event, data);
			},
			focus: function(event, ui){
				var data = $.extend({}, tree.ext.menu.data, {
					menuItem: ui.item,
					menuId: ui.item.find(">a").attr("href")
				});
				opts.menu.focus.call(tree, event, data);
			},
			select: function(event, ui){
				var data = $.extend({}, tree.ext.menu.data, {
					menuItem: ui.item,
					menuId: ui.item.find(">a").attr("href")
				});
				if( opts.menu.select.call(tree, event, data) !== false){
					tree.ext.menu._closeMenu(ctx);
				}
			}
		}).hide();
	},
	treeDestroy: function(ctx){
		this._super(ctx);
	},
	_openMenu: function(ctx){
		var data,
			tree = ctx.tree,
			opts = ctx.options,
			$menu = $(opts.menu.selector);

		tree.ext.menu.data.node = ctx.node;
		data = $.extend({}, tree.ext.menu.data);

		if( opts.menu.beforeOpen.call(tree, ctx.originalEvent, data) === false){
			return;
		}

		$(document).bind("keydown.fancytree", function(event){
			if( event.which === $.ui.keyCode.ESCAPE ){
				tree.ext.menu._closeMenu(ctx);
			}
		}).bind("mousedown.fancytree", function(event){
			// Close menu when clicked outside menu
			if( $(event.target).closest(".ui-menu-item").length === 0 ){
				tree.ext.menu._closeMenu(ctx);
			}
		});
//        $menu.position($.extend({my: "left top", at: "left bottom", of: event}, opts.menu.position));
		$menu
			.css("position", "absolute")
			.show()
			.position({my: "left top", at: "right top", of: ctx.originalEvent, collision: "fit"})
			.focus();

		opts.menu.open.call(tree, ctx.originalEvent, data);
	},
	_closeMenu: function(ctx){
		var $menu,
			tree = ctx.tree,
			opts = ctx.options,
			data = $.extend({}, tree.ext.menu.data);
		if( opts.menu.close.call(tree, ctx.originalEvent, data) === false){
			return;
		}
		$menu = $(opts.menu.selector);
		$(document).unbind("keydown.fancytree, mousedown.fancytree");
		$menu.hide();
		tree.ext.menu.data.node = null;
	}
//	,
//	nodeClick: function(ctx) {
//		var event = ctx.originalEvent;
//		if(event.which === 2 || (event.which === 1 && event.ctrlKey)){
//			event.preventDefault();
//			ctx.tree.ext.menu._openMenu(ctx);
//			return false;
//		}
//		this._super(ctx);
//	}
});
}(jQuery, window, document));
