/// class PD.Web.UI.Controls.ContextMenu
/// using PD.Web.UI.Controls.Control

PD.Web.UI.Controls.ContextMenu =
PD.Web.UI.Controls.Control.extend({

    //===================================
    // FIELDS
    //===================================

    _items: null,
    _segments: null,
    _kendo: null,
    _cache: null,

    //===================================
    // PROPERTIES
    //===================================

    get_cache: function () {
        return this._cache;
    },

    get_openCallback: function () {
        return this.get_options()["open"] ?? function () { };
    },

    get_isVisible: function () {
        return this.get_node().is(":visible");
    },

    //===================================
    // EVENT HANDLERS
    //===================================

    onInit: function (e) {
        this._items = new PD.BCL.List();
        this._segments = new PD.BCL.List();
        this._cache = new PD.Web.UI.Controls.ContextMenuCache();
    },

    _onFrameExit: function (e) {
        this.onRegisterSegments(e);
        this.onRegisterItems(e);
    },

    onRegisterSegments: function (e) {

        var that = this,
            segments = new PD.BCL.List(this.get_options().segments);

        segments.each(function (index, segment) {
            if (segment.meetsLoadConditions(e)) {
                that._segments.add(segment);
            };
        });

    },

    onRegisterItems: function (e) {

        var that = this;

        this._segments.each(function (index, segment) {

            segment.onRegisterItems(new PD.Web.UI.Controls.ContextMenuOnRegisterItemsEventArgs({
                menu: that,
                items: that._items,
                segment: segment
            }));

        });

    },

    template: function (e) {
        return "<ul class='-pd-context-menu'></ul>";
    },

    onActivate: function (e) {

        var items = this._items.transform(function (item) {
            return item.getSettings();
        }).toArray();

        this._iterateNodes(items, function (item) {
            delete item.imageUrl
            delete item.spriteCssClass
        });

        this._kendo = this.get_node().kendoContextMenu(this._mergeOptions({
            dataSource: items,
            select: $.proxy(this.onClick, this),
            open: $.proxy(this.onOpen, this)
        })).data("kendoContextMenu");

    },

    onOpen: function (e) {

        var that = this;

        this._segments.each(function (index, segment) {
            segment.open(that._kendo, $(e.event.currentTarget), that.get_cache());
        });

        this.get_openCallback()();

    },

    onClick: function (e) {

        var that = this,
            item = null,
            id = $(e.item).find(".k-link:first > [data-id]").data("id");

        e = $.extend({
            id: id,
            context: this._context
        }, e);

        this._iterateItems(this._items, function (i) {
            if (i.data("id") === id) {
                item = i;
                return false;
            }
        });

        this._segments.each(function (index, segment) {
            segment.click(that._kendo, e.currentTarget, item, that.get_cache());
        });

    },

    onRemove: function () {
        if (this._kendo != null) {
            this._kendo.destroy();
        }
    },

    //===================================
    // PRIVATE METHODS
    //===================================

    _mergeOptions: function (settings) {

        var result = null,
            options = this._options;

        result = $.extend({}, settings, {
            animation: {
                open: {
                    effects: "fadeIn",
                    duration: 150
                },
                close: {
                    effects: "none"
                }
            },
            target: options.target || undefined,
            filter: options.filter || undefined,
            showOn: options.showOn || undefined,
            direction: options.direction || "default",
            alignToAnchor: options.alignToAnchor || false,
            orientation: options.orientation || "vertical"
        });

        return result;

    },

    _iterateItems: function (items, fn) {

        var that = this;

        items.each(function (index, item) {

            var abort = false;

            if (PD.Type.isFunction(fn)) {
                abort = fn(item) === false;
            }

            if (!abort && item.get_items().count() > 0) {
                that._iterateItems(item.get_items(), fn);
            }

            return !abort;

        });

    },

    _iterateNodes: function (nodes, fn) {

        var index = 0,
            abort = false,
            node = null;

        for (i = 0; i < nodes.length; i++) {

            node = nodes[i];

            if (PD.Type.isFunction(fn)) {
                abort = fn(node) === false;
            }

            if (!abort && node.items) {
                this._iterateNodes(node.items);
            }

        }

    }

});