﻿(function ($) {

    var settings = {
        'edit': false,
        'openOnClick': false,
        'hideDelay': 0,
        'onItemSelected': function ($item) { }
    };

    var methods = {
        init: function (options) {

            return this.each(function () {

                if (options) {
                    $.extend(settings, options);
                }

                var $root = $(this);

                if (!$root.data("initialized")) {
                    $root.data("initialized", true);

                    $root.data("selectedObject", null);

                    $root.tufmenu("hide");

                    $root.tufmenu("attachMenuHandlers");

                    $("html").click(function () {
                        $root.tufmenu("hide");
                    });
                }
            });
        },
        hide: function (options) {
            return this.each(function () {
                var $this = $(this);

                $this.find("li").children("ul").hide();
            });
        },
        addMenu: function (where) {
            return this.each(function () {
                var $root = $(this);
                var $selected = $root.data("selectedObject");

                if (!$selected || where == "root") {
                    $selected = $('<li><a href="#">New Menu</a></li>').appendTo($root);
                    $root.tufmenu("attachMenuHandlers", $selected);
                }
                else if ($selected.children("ul").size() < 1) {
                    $selected = $('<ul><li><a href="#">New Item</a></li></ul>').appendTo($selected).children("li");
                    $root.tufmenu("attachMenuHandlers", $selected);
                }
            });
        },
        addItem: function (options) {
            return this.each(function () {
                var $root = $(this);
                var $selected = $root.data("selectedObject");

                if ($selected) {
                    var $new_item = null;

                    if (!$selected.has("ul")) $new_item = $('<ul><li><a href="#">New Item</a></li></ul>').appendTo($selected).children("li");
                    else $new_item = $new_item = $('<li><a href="#">New Item</a></li>').appendTo($selected.children("ul"));

                    $root.tufmenu("attachMenuHandlers", $new_item);
                }
            });
        },
        removeSelectedItem: function (options) {
            return this.each(function () {
                var $root = $(this);
                var $selected = $root.data("selectedObject");

                $selected.data("removed", true).hide();
            });
        },
        attachMenuHandlers: function ($new_menu) {

            return this.each(function () {

                var $root = $(this);
                var $target = null;

                if (settings.edit) {
                    $root.sortable({
                        items: "li",
                        cancel: "li>a[contenteditable='true']"
                    }).disableSelection();
                }

                if (!$new_menu) {
                    $target = $("> li, .sub-menu > li", this).filter(function (index) {
                        return $(this).closest(".tufmenu")[0] === $root[0];
                    });
                }
                else {
                    if ($new_menu.is("li")) $target = $new_menu;
                    else $target = $new_menu.parent();
                }

                $target.find("ul").each(function () {
                    var $parent = $(this).parent();

                    $parent.children("a").append($('<span class="has-children"></span>'));
                });

                if (!settings.edit) {
                    if (!settings.openOnClick) {
                        $target.mouseenter(function () {
                            var $item = $(this);
                            clearTimeout($item.data("timeOut"));
                            $item.children("ul").show();
                        }).mouseleave(function () {
                            $(this).data("timeOut", setTimeout($.proxy(function () { $(this).children("ul").hide(); }, this), settings.hideDelay));
                        });
                    }
                    else {
                        $target.click(function (e) {
                            e.stopPropagation();

                            var $item = $(this);

                            var $subMenu = $(this).children(".sub-menu");

                            if ($subMenu.length > 0) {
                                var $root_subs = $root.find(".sub-menu").filter(function (index) {
                                    return $(this).closest(".tufmenu")[0] === $root[0];
                                });

                                $root_subs.not($subMenu.parentsUntil(".tufmenu", ".sub-menu")).hide();
                                $subMenu.show();
                            }
                        });
                    }
                }
                else {
                    $target.click(function (e) {
                        var $item = $(this);
                        $root.data("selectedObject", $item);
                        $root.find("li a").removeAttr("contenteditable").unbind("click").blur();
                        $root.tufmenu("hide");
                        $item.parents("ul").disableSelection().show();
                        var $children = $item.children("ul");
                        $children.show();
                        e.stopPropagation();
                        e.preventDefault();
                        if (settings.onItemSelected) settings.onItemSelected($item);
                    }); //.dblclick(function (e) {
                    //                            var $item = $(this);
                    //                            $root.data("selectedObject", $item);
                    //                            var $link = $item.children("a");
                    //                            $link.attr("contenteditable", true).focus();
                    //                            $link.click(function (z) { z.stopPropagation() });
                    //                            $root.tufmenu("hide");
                    //                            $item.parents("ul").enableSelection().show();
                    //                            var $children = $item.children("ul");
                    //                            $children.show();
                    //                            e.stopPropagation();
                    //                            e.preventDefault();
                    //                        });
                }
            });
        },
        getSelectedItem: function () {
            return this.data("selectedObject");
        },
        toJSON: function () {
            function buildJSON($parent) {
                var $children = $parent.children("li");

                var children_json = [];

                $children.each(function () {
                    var $c = $(this);
                    var $link = $c.children("a");
                    children_json.push({
                        "Text": $link.text(),
                        "Link": $link.attr("href"),
                        "ID": $c.attr("id"),
                        "Removed": $c.data("removed"),
                        "Children": buildJSON($c.children("ul"))
                    });
                });

                return children_json;
            }

            return buildJSON(this);
        }
    };

    $.fn.tufmenu = function (method) {

        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.tufmenu');
        }

    };

})(jQuery);

