/// class ProspectDirector.Modules.Explorer.ExplorerModule
/// using ProspectDirector.Types.Core.ContextMenu

ProspectDirector.Modules.Explorer.ExplorerModule = (function (options) {

    var 

        PRIVATE = {

            explorerReloadSubscription: null,

            explorerContext: new PDJS.Hub.Explorer.ExplorerContext(),

            init: function () {

                options = $.extend({
                    data: {
                        entityId: null,
                        expandPath: null
                    }
                }, options);
                
                PRIVATE.init_splitter();
                PRIVATE.init_tree();
                PRIVATE.init_explorerPanel();
                PRIVATE.addWindowResizeHandler();
                PRIVATE.loadContent(options.data.expandPath[options.data.expandPath.length - 1], options.data.entityId);

                setTimeout(function () {
                    PRIVATE.splitter_onResize();
                }, 25);
                
            },

            //---------------------------
            //--- PROPERTIES
            //---------------------------

            get_splitter: function () {
                return $("[data-id=explorer-module]");
            },

            get_tree: function () {
                return $("[data-id=explorer-module-treeview]");
            },

            get_contentPane: function () {
                return PRIVATE.get_splitter().find("[data-id=explorer-content]");
            },

            get_explorerPanel: function () {
                return PRIVATE.get_splitter().find("[data-id=explorer-panel]");
            },

            content: function (value) {
                if (!value) {
                    return options.content;
                }
                options.content = value;
            },

            //---------------------------
            //--- EVENT HANDLERS
            //---------------------------

            splitter_onResize: function () {

                var filler = PRIVATE.get_tree().data("filler");

                if (filler) {
                    setTimeout(function () {

                        filler.size();

                    }, 100);
                }

                Jade.Application
                    .instance
                    .contexts
                    .global
                    .events
                    .publish("Browser:Resized");

            },

            tree_onDataBound: function (e) {

                var tree = PRIVATE.get_tree().data("kendoTreeView"),
                data = null,
                item = null,
                node = null,
                index = 0;

                if (e.node === undefined || e.node.length === 0) {
                    data = e.sender.dataSource._data;
                }
                else {
                    data = tree.dataItem(e.node).children._data;
                }

                if (data !== undefined) {

                    for (index = 0; index < data.length; index++) {

                        item = data[index];
                        node = PRIVATE.nodeTemplate(item);
                        arrIndex = $.inArray(item.id, options.data.expandPath);

                        if (arrIndex > -1) {
                            tree.select(node);
                            if (arrIndex < options.data.expandPath.length - 1) {
                                tree.expand(node);
                            }
                        }

                    }

                }

            },

            tree_onRead: function (settings) {

                var localDataSource = options.data.preloadNodes,
                    tree = PRIVATE.get_tree().data("kendoTreeView"),
                    data = [];

                if ($.isEmptyObject(settings.data)) {
                    data = ProspectDirector.Util.traverseAndFind(localDataSource);
                }
                else {
                    data = ProspectDirector.Util.traverseAndFind(localDataSource, {
                        filters: {
                            id: settings.data.id
                        }
                    });
                }

                if (data) {
                    settings.success(data);
                }
                else {

                    PD.ajax({
                        url: ProspectDirector.RUNTIME.resolveUrl("~/Explorer/GetFolders"),
                        data: {
                            entityId: tree.dataSource.get(settings.data.id).entityId,
                            folderId: settings.data.id
                        },
                        success: function (result) {
                            settings.success(result);
                        }
                    });

                }

            },

            tree_onSelect: function (e) {

                var tree = PRIVATE.get_tree().data("kendoTreeView"),
                    item = tree.dataItem(e.node);

                e.preventDefault();

                if (!item.isNavigable) {
                    return;
                }

                ProspectDirector.RUNTIME.MODULES.Navigator.go(function () {

                    PRIVATE.loadContent(item.id,
                                        item.entityId,
                                        e.node);

                });

            },

            tree_onMouseOver: function (e) {

                var tree = this.get_tree().data("kendoTreeView"),
                    node = $(e.target).closest("LI.k-item"),
                    item = tree.dataItem(node),
                    kin = node.find(".k-in").first();

                if (!item.isNavigable) {
                    kin.removeClass("k-state-hover");
                }

            },

            explorerPanel_onSelect: function (e) {

                var id = $(e.currentTarget).data("id");

                switch (id) {
                    case "reports":

                        ProspectDirector.Modules.Reports.ReportSelectorDialog.Dialog.show({
                            params: {
                                entityId: options.data.entityId
                            }
                        });

                        break;
                    case "properties":

                        PDJS.Entities.EntityDialogs.showProperties({
                            entityId: options.data.entityId,
                            onSave: function (sender, e) {
                            }
                        });
                        
                        break;
                }

            },

            //---------------------------
            //--- INITIALIZERS
            //---------------------------

            init_tree: function () {

                var tree = PRIVATE.get_tree().kendoTreeView({
                    dataSource: new kendo.data.HierarchicalDataSource({
                        transport: {
                            read: $.proxy(PRIVATE.tree_onRead, PRIVATE)
                        },
                        schema: {
                            model: {
                                id: "id",
                                hasChildren: "hasFolders"
                            }
                        }
                    }),
                    dataBound: $.proxy(PRIVATE.tree_onDataBound, PRIVATE),
                    select: $.proxy(PRIVATE.tree_onSelect, PRIVATE)
                }).data("kendoTreeView");
                
                PRIVATE.get_tree().disableTextSelection();

                PRIVATE.get_tree().data("contextMenu", new ProspectDirector.Modules.Explorer.ExplorerModule.TreeContextMenu({
                    module: PRIVATE
                }));

                PRIVATE.get_tree().on("mouseover", "LI.k-item", $.proxy(this.tree_onMouseOver, this));

                if (ProspectDirector.RUNTIME.ENVIRONMENT.EXPLORER_ANCESTOR_DISPLAY_MODE !== 2) {
                    tree.expand(PRIVATE.get_tree().find("LI.k-item:first"));
                }
                else {
                    tree.expand(PRIVATE.get_tree().find("LI.k-item:last"));
                }

            },

            init_splitter: function () {

                var splitter = PRIVATE.get_splitter().kendoSplitter({
                    orientation: "horizontal",
                    panes: [
                        { size: "300px", scrollable: false },
                        { scrollable: false }
                    ],
                    resize: $.proxy(PRIVATE.splitter_onResize, PRIVATE)
                }).data("kendoSplitter");

            },

            init_explorerPanel: function () {

                PRIVATE.get_explorerPanel().on("click", "DIV[data-id]", $.proxy(PRIVATE.explorerPanel_onSelect, PRIVATE));

            },

            //---------------------------
            //--- METHODS
            //---------------------------

            addWindowResizeHandler: function () {

                $(window).on("resize", $.proxy(function () {

                    if (PRIVATE.get_splitter().length > 0) {

                        setTimeout(function () {
                            PRIVATE.get_splitter().data("kendoSplitter").resize();
                        }, 100);

                    }
                    else {
                        $(window).off("resize", this);
                    }

                }, PRIVATE));

                setTimeout(function () {
                    PRIVATE.get_splitter().data("kendoSplitter").resize();
                }, 100);

            },

            nodeTemplate: function (data) {

                var tree = PRIVATE.get_tree().data("kendoTreeView"),
                    $span = $("<span class=\"node-label\"></span>"),
                    $node = tree.findByUid(data.uid),
                    $inner = $node.find(".k-in").first(),
                    innerHTML = data.name;

                if (data.ref !== undefined) {
                    $node.attr("data-ref", data.ref);
                }

                if (data.role !== undefined) {
                    $node.attr("data-role", data.role);
                }

                if (data.isHidden) {
                    $span.css({
                        opacity: .40
                    });
                }
                else if ($node.parent().length > 0) {
                    $span.css({
                        opacity: $node.parent().closest(".k-item").find(".node-label:first").css("opacity")
                    });
                }

                if (data.supportsFiles && data.fileCount > 0) {
                    innerHTML += " <b>(" + data.fileCount + ")</b>";
                }

                if (data.icon !== undefined && data.icon != null) {
                    innerHTML = "<img src=\"" + ProspectDirector.RUNTIME.resolveUrl("~/application/icons/16x16/" + data.icon) + "\" style=\"vertical-align:top;\" />&nbsp;" + innerHTML;
                }

                $span.html(innerHTML);
                $inner.empty();
                $inner.html($span[0].outerHTML);

                return $node;

            },

            loadContent: function (folderId, entityId, node) {

                var splitter = PRIVATE.get_splitter().data("kendoSplitter");

                if (entityId === undefined) {
                    entityId = options.data.entityId;
                }

                PRIVATE.makeContentRequest(entityId, folderId);

                if (node) {
                    PRIVATE.get_tree().data("kendoTreeView").select(node);
                }

                if (PRIVATE.explorerReloadSubscription == null) {

                    PRIVATE.explorerReloadSubscription = Jade.Application
                        .instance
                        .contexts
                        .current
                        .events
                        .subscribe("explorer/reload", function (e) {

                            PDJS.JS
                                .ProspectDirector
                                .RUNTIME
                                .MODULES
                                .Navigator
                                .canvasFormChanged = null;

                            var stateEntityId = window.history.state.entityId;
                            var stateFolderId = window.history.state.folderId;

                            PRIVATE.makeContentRequest(stateEntityId || entityId, stateFolderId || folderId);

                        });

                }

            },

            makeContentRequest: function (entityId, folderId) {

                PRIVATE.unloadContent();

                PD.ajax({
                    url: Jade.Path.resolve("~/explorer/contents"),
                    data: {
                        entityId: entityId,
                        folderId: folderId
                    },
                    success: function (e) {
                        
                        PRIVATE.get_contentPane().empty();
                        PRIVATE.get_contentPane().append(e);
                        window.history.pushState({
                            entityId: entityId,
                            folderId: folderId
                        }, null, Jade.Path.resolve("~/explore/" + entityId + "/folder/" + folderId));

                    }
                });

            },

            unloadContent: function () {

                PRIVATE.explorerContext.unload();
                
                if (options.content) {
                    options.content.unload();
                }

            },

            reloadNode: function (data) {

                var tree = PRIVATE.get_tree().data("kendoTreeView"),
                    item = tree.dataSource.get(data.id),
                    node = null,
                    span = null;

                if (!item) {
                    return;
                }

                node = tree.findByUid(item.uid);

                span = node.find(".k-in").first().find("span").first();

                item = $.extend(item, data);

                node = PRIVATE.nodeTemplate(item);

                span.html(node.find(".k-in").first().find("span").first().html());

            }

        },

        PUBLIC = {
            content: PRIVATE.content,
            loadContent: PRIVATE.loadContent,
            reloadNode: PRIVATE.reloadNode
        };

    PRIVATE.init();

    return PUBLIC;

});

ProspectDirector.Modules.Explorer.ExplorerModule.TreeContextMenu = ProspectDirector.Types.Core.ContextMenu.extend({

    //---------------------------
    //--- CONSTRUCTOR
    //---------------------------

    init: function (options) {

        this._super($.extend({
            module: null,
            width: 300
        }, options));

    },

    //---------------------------
    //--- PROPERTIES
    //---------------------------

    get_module: function () {
        return this.options.module;
    },

    get_tree: function () {
        return this.get_module().get_tree()
    },

    get_contextMenuSelector: function () {
        return this.get_tree().selector + " LI.k-item";
    },

    //---------------------------
    //--- PROTECTED METHODS
    //---------------------------

    _executeCommand: function (command, e) {

        var trigger = e.$trigger,
            isFolder = trigger.data("role") === "folder",
            data = this.getDataItem(trigger);

        if (isFolder) {
            this.executeFolderOption(command, data);
        }
        else {
            this.executeEntityOption(command, data);
        }

    },

    _configureContextMenu: function (sender, e) {

        var tree = this.get_tree().data("kendoTreeView"),
            data = tree.dataItem($(sender));

        if (data.role === "folder") {
            this.configureFolderOptions(e.config, data);
        }
        else {
            this.configureEntityOptions(e.config, data);
        }

    },

    configureFolderOptions: function (config, data) {

        config.items.open = {
            name: "Open",
            disabled: !data.isNavigable
        };

        config.items.openInNewWindow = {
            name: "Open in new window",
            disabled: !data.isNavigable
        };

    },

    executeFolderOption: function (command, data) {

        var tree = this.get_tree().data("kendoTreeView");

        switch (command) {

            case "open":

                ProspectDirector.RUNTIME.MODULES.Navigator.go(function () {
                    ProspectDirector.RUNTIME.MODULES.Explorer.loadContent(data.id, data.entityId, tree.findByUid(data.uid));
                });

                break;

            case "openInNewWindow":

                window.open(ProspectDirector.RUNTIME.resolveUrl("~/explore/") + data.entityId + "/folder/" + data.id);
                break;

        }

    },

    configureEntityOptions: function (config, data) {

        config.items.open = {
            name: "Open"
        };

        config.items.openInNewWindow = {
            name: "Open In New Window"
        };

        config.items.sep1 = "";

        config.items.reports = {
            name: "Reports..."
        };

        config.items.addToFavorites = {
            name: "Add to Favorites"
        };

        config.items.sep2 = "";

        config.items.properties = {
            name: "Properties..."
        };

    },

    executeEntityOption: function (command, data) {

        switch (command) {

            case "open":

                ProspectDirector.RUNTIME.MODULES.Navigator.go("~/explore/" + data.entityId);
                break;

            case "openInNewWindow":

                window.open(ProspectDirector.RUNTIME.resolveUrl("~/explore/") + data.entityId);
                break;

            case "reports":

                ProspectDirector.RUNTIME.MODULES.Navigator.go(function () {

                    ProspectDirector.Modules.Reports.ReportSelectorDialog.Dialog.show({
                        params: {
                            entityId: data.entityId
                        }
                    });

                });

                break;

            case "addToFavorites":

                ProspectDirector.Modules.Personalization.AddToFavoritesDialog.Dialog.show({
                    params: {
                        ids: JSON.stringify([data.entityId])
                    }
                });

                break;

            case "properties":

                PDJS.Entities.EntityDialogs.showProperties({
                    entityId: data.entityId,
                    onSave: function (sender, e) {
                    }
                });
                
                break;

        }

    },

    getDataItem: function (element) {

        return this.get_tree().data("kendoTreeView").dataSource.getByUid(element.data("uid"));

    }

});