(function ($) {
    $.widget("qusion.toolbox", {
        options: {
            openFade: 200,
            closeFade: 200,
            pinned: false,
            selected: null,
            panels: null,
            items: null,
            showHeader: true,
            showTitle: true,
            showPin: true,
        },
        _create: function () {
            var self = this,
                options = self.options,
                element = this.element;

            self.panels = options.panels;
            // toolbox navigation container
            self.nav = element.find('.q-toolbox-nav:first-child');
            if (!self.nav.length)
                self.nav = $('<ul class="q-toolbox-nav" />').appendTo(element);

            // toolbox panel container
            self.container = element.find('.q-toolbox-panels:first-child');
            if (!self.container.length)
                self.container = $('<div class="q-toolbox-panels" />').appendTo(element);

            // selected item
            self.active = null;
            // detects if toolbox is pinned (does not collapse)
            self.pinned = options.pinned;
            // set initial container properties
            element
                .uniqueId()
                .addClass("q-toolbox")
                .attr({
                    role: "toolbox",
                    tabIndex: 0
                });

            // generate panels and navigation
            self._generatePanels();
            // and create everything else
            self._refresh();

        },
        _refresh: function () {
            var self = this,
                options = this.options,
                element = this.element;

            if (options.selected)
                self._open(options.selected);

            if (options.pinned === true)
                self._pin(true);

            // atach events
            this._on(element, {
                "click .q-toolbox-tab": function (e) {
                    var target = $(e.currentTarget).closest('.q-toolbox-tab');
                    e.stopPropagation();

                    var key = target.data('panel');

                    (self.active == null || self.active.key != key)
                        ? self.open(key, e)
                        : (self.pinned === false ? self.close(key, e) : function () {
                        });
                },
                "click .q-group-header": function (e) {
                    var target = $(e.currentTarget).closest('.q-group-header');
                    var elem = target.next('ul');
                    var container = target.parents('.q-toolbox-panel');
                    //console.log(target);
                    e.stopPropagation();

                    var key = container.data('key');


                    elem.is(':visible')
                        ? self._collapseGroup(container, target.data('group'))
                        : self._expandGroup(container, target.data('group'));
                },
                "click .q-toolbox-pin": function (e) {
                    e.stopPropagation();
                    self.pin(!self.pinned);
                },
                "click": function (e) {
                    if (self.pinned === false)
                        e.stopPropagation();
                }
            });
        },
        _generatePanels: function () {
            var self = this,
                options = this.options;

            // no need to loop throught
            if (!self.panels) return;

            // loop through items and generate
            for (var i = 0; i < self.panels.length; i++) {
                self._addPanel(self.panels[i]);
            }
        },
        _addPanel: function (panel) {
            var self = this,
                options = this.options;

            var n = $('<li />')
                .addClass('q-toolbox-tab')
                .addClass(panel.className)
                .attr('data-panel', panel.key)
                .appendTo(self.nav);

            n.append($('<a />'))
                .find('a')
                .append($('<i />', { 'class': panel.iconClass }))
                .append($('<span />', { text: panel.title }));

            var p = $('<div class="q-toolbox-panel" />')
                .data('panel', panel)
                .css({ 'display': 'none' })
                .attr('data-key', panel.key);


            if (options.showHeader === true) {
                var h = $('<div class="q-toolbox-header" />').prependTo(p);

                if (options.showPin === true)
                    h.append($('<a class="q-toolbox-pin"><i class="icon-pushpin"></i></a>'));

                if (options.showTitle === true)
                    h.append('<span>' + panel.title + '</span>');
            }

            self.container.append(p);

            // items
            if (panel.items) {
                for (var i = 0; i < panel.items.length; i++) {
                    self._addItem(panel.key, panel.items[i]);
                }
            }

        },
        _addItem: function (panelKey, item) {
            var self = this,
                options = this.options,
                element = this.element;
            var p = self.find(panelKey);

            var group = self._getOrCreateGroup(p.content, item.group);

            group.next('ul')
                .append($('<li />')
                    .append($('<a />')
                        .data('item', item)
                        .attr('data-title', item.title)
                        .attr('data-group', item.group)
                        .attr('data-id', item.ID)
                        .addClass('q-toolbox-item')
                        .append('<i class="icon-th" />')
                        .append(item.title)
                    ));

        },
        _getOrCreateGroup: function (container, group) {
            var g = container.find('[data-group="' + group + '"]');

            if (!g.length) {
                g = $('<a />', { 'data-group': group })
                    .addClass('q-group-header')
                    .append('<i class="icon-folder-close"></i>')
                    .append(group)
                    .appendTo(container);

                $('<ul />').hide().appendTo(container);
            }
            return g;
        },
        _open: function (p, e) {
            var self = this,
                options = this.options,
                element = this.element;

            var key = p === Object(p) ? p.key : p;
            var panel = self.find(key);

            // close current active
            self.nav.find('li.active').removeClass('active');
            self.container.find('.q-toolbox-panel.active').removeClass('active').hide();

            // set active classes and show active panel
            panel.link.addClass('active');
            panel.content.addClass('active').show(); // 'blind', { percent: 100 }, 100

            $(document).on("click", function (event) {
                //console.log(event.which);
                if (event.which != 1) return;

                if (self.pinned === false)
                    self.closeAll();
            });

            self.active = panel;
            self._trigger('onOpen', e);
        },
        _close: function (p, e) {
            var self = this,
                options = this.options,
                element = this.element;

            var key = p === Object(p) ? p.key : p;
            var panel = self.find(key);

            panel.link.removeClass('active');
            panel.content.removeClass('active').hide(); // 'blind', { percent: 100 }, 100

            // if this is the last active panel thenset active to null (no active panel)

            //console.log(self.active);
            if (self.active && self.active.key === panel.key)
                self.active = null;

            self._trigger('onClose', e);
        },
        _pin: function (flag, e) {

            var self = this;
            if (flag !== true)
                flag = false;

            self.pinned = flag;
            //console.log(self.pinned);
            if (self.pinned === true) {
                self.element
                    .addClass('q-toolbox-pinned');
            } else
                self.element
                    .removeClass('q-toolbox-pinned');

            self._trigger('onPin', e, self.pinned);
        },
        _expandGroup: function (container, group) {
            var self = this;
            self._collapseAllGroups();
            var group = self._getOrCreateGroup(container, group);
            group.next('ul').show();
        },
        _collapseGroup: function (container, group) {
            var self = this;
            var group = self._getOrCreateGroup(container, group);
            group.next('ul').hide();
        },
        _collapseAllGroups: function () {
            var self = this;
            self.container.find('.q-group-header').each(function () {
                $(this).next().hide();
            });
        },
        pin: function (p, e) {
            var self = this;
            self._pin(p, e);
        },
        isPinned: function (p, e) {
            var self = this;
            return self.pinned;
        },
        open: function (p, e) {
            var self = this;
            self._open(p, e);
        },
        close: function (p, e) {
            var self = this;
            self._close(p, e);
        },
        closeAll: function () {
            var self = this,
                options = self.options,
                element = this.element;

            //for (var i = 0; i < self.panels.length; i++) {
            //    var p = self.panels[i];

            //}
            
            if (self.active)
                self._close(self.active.key);
        },
        addPanel: function (panel) {
            var self = this;
            self._addPanel(panel);
            self._trigger('paneladd', null, { panel: panel });
        },
        find: function (key) {
            var self = this;
            for (var i = 0; i < self.panels.length; i++) {
                var p = self.panels[i];
                if (p.key === key) {
                    return {
                        key: key,
                        link: self.nav.find('[data-panel="' + key + '"]'),
                        content: self.container.find('[data-key="' + key + '"]'),
                        data: p
                    };
                }
            }
            return null;
        }
    });
})(jQuery);