/*
 * Copyright (C) 2005 - 2011 Jaspersoft Corporation. All rights reserved.
 * http://www.jaspersoft.com.
 *
 * Unless you have purchased  a commercial license agreement from Jaspersoft,
 * the following license terms  apply:
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License  as
 * published by the Free Software Foundation, either version 3 of  the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero  General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public  License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

///////////////////////////////
// Secondary search box object
///////////////////////////////
repositorySearch.secondarySearchBox = {
    _searchBox: null,

    initialize: function(text) {
        this._searchBox = new SearchBox({
            id: "secondarySearchBox"
        });

        this._searchBox.onSearch = function(text) {
            repositorySearch.fire(repositorySearch.Event.SEARCH_SEARCH, {text: text});
        };

        this.setText(text);
    },

    setText: function(text) {
        this._searchBox.setText(text);
    }
};

///////////////////////////////
// Toolbar object
///////////////////////////////
repositorySearch.toolbar = {
    _bulkActions: {},

    initialize: function(bulkActions) {
        this._bulkActions = bulkActions;
        toolbarButtonModule.initialize(this._toActionMap(this._bulkActions));
        this.refresh();
    },

    refresh: function() {
        for(var name in this._bulkActions) {
            var id = this._bulkActions[name].buttonId;
            var testFn = toFunction(this._bulkActions[name].test);

            toolbarButtonModule.setButtonState($(id), testFn());
        }
    },

    _toActionMap: function(bulkActionModel) {
        var actionMap = {};

        for(var name in bulkActionModel) {
            var bulkAction = bulkActionModel[name];
            var id = bulkAction.buttonId;

            actionMap[id] = function(action, actionArgs) {
                return function() {
                    var myAction = getAsFunction(action);
                    var args = actionArgs;

                    var belongsToLocalContext = localContext && localContext[action];

                    if (args && isArray(args)) {
                        myAction.apply(belongsToLocalContext ? localContext : null, args);
                    } else {
                        myAction.call(belongsToLocalContext ? localContext : null, args);
                    }
                }
            }(bulkAction.action, bulkAction.actionArgs)
        }

        return actionMap;
    }
};

///////////////////////////////
// Folder panel object
///////////////////////////////
repositorySearch.foldersPanel =  {
    _treeId: 'foldersTree',
    _uri: "/",
    _cookieName: "lastFolderUri",
    _canDoBrowse: true,

    initialize: function (options) {
        var storedUri = new JSCookie(this._cookieName).value;
        this._uri = storedUri && storedUri.length > 0 ? storedUri : "/";

        // Setup folders tree
        this.tree = new dynamicTree.createRepositoryTree(this.getTreeId(), {
            providerId: 'repositoryExplorerTreeFoldersProvider',
            rootUri: repositorySearch.model.getRootFolderUri(),
            organizationId: options.organizationId,
            publicFolderUri: options.publicFolderUri,
            urlGetNode: 'flow.html?_flowId=searchFlow&method=getNode',
            urlGetChildren: 'flow.html?_flowId=searchFlow&method=getChildren',
            dragPattern: '.draggable',
            selectOnMousedown: true
        });

        disableSelectionWithoutCursorStyle($(this.getTreeId()).up(1));

        this.tree.observe('key:contextMenu', function(event) {
            var node = event.memo.node;
            var nodePosition = getBoxOffsets(node, true);
            repositorySearch.actionModel.showFolderMenu(event, {
                menuLeft: nodePosition[0] + 100, //TODO: use constants for offsets
                menuTop: nodePosition[1] + 20    //TODO: use constants for offsets
            });
            Event.stop(event);
        });

        this.tree.observe('key:escape', function(event) {
            actionModel.hideMenu();
            Event.stop(event);
        });

        this.tree.observe('tree:mouseover', function(event) {
            this.tree._overNode = event.memo.node;

        }.bindAsEventListener(this));

        this.tree.observe('tree:mouseout', function(event) {

            this.tree.refreshDropTarget(false);

            this.tree._overNode == event.memo.node && (this.tree._overNode = null);

        }.bindAsEventListener(this));

        this.tree.setDragStartState = function(node, draggable, event){
            dynamicTree.Tree.prototype.setDragStartState.call(this, node, draggable, event);

            var folder = new Folder(node);
            if (isMetaHeld(event, true)) {
                canFolderBeCopied(folder) && invokeFolderAction("CopyFolder", folder);
                $(document.body).addClassName(layoutModule.COPY_CLASS);
            } else {
                canFolderBeMoved(folder) && invokeFolderAction("MoveFolder", folder);
            }

        };
        this.tree.setDragEndState = function(node, draggable, event){
            repositorySearch.CopyMoveController.cancel();

            this.refreshDropTarget(false);
            $(document.body).removeClassName(layoutModule.COPY_CLASS);

            dynamicTree.Tree.prototype.setDragEndState.call(this, node, draggable, event);
        };

        this.tree.refreshDropTarget = function(allowed){
            if (this._overNode) {
                this._overNode.isDropTarget = allowed;
                this._overNode.refreshStyle();
            }
        };

        Droppables.remove(this.getTreeId());
        Droppables.add(this.getTreeId(),{
            accept: ['dragging', 'wrap'],
            onHover: (function(dragged, dropped, event){

                if (this.tree._overNode) {
                    var toFolder = new Folder(this.tree._overNode);

                    var hover = (dragged.node && canFolderBeCopiedOrMovedToFolder(toFolder)) ||
                            (dragged.items && canAllBeCopiedOrMovedToFolder(toFolder));

                    this.tree.refreshDropTarget(hover);
                }
            }).bind(this),
            onDrop: (function(dragged, dropped, event){
                if (this.tree._overNode) {
                    var toFolder = new Folder(this.tree._overNode);

                    dragged.node && canFolderBeCopiedOrMovedToFolder(toFolder) && invokeFolderAction("PasteFolder", toFolder);
                    dragged.items && canAllBeCopiedOrMovedToFolder(toFolder) && invokeFolderAction("PasteResources", toFolder);
                }
            }).bind(this)
        });

        this.tree.observe('server:error', function() {
            if (window.console) {
                alert("Tree load error.");
            }
        });

        this.tree.observe('childredPrefetched:loaded', function(event) {
            this.tree.openAndSelectNode(this._uri);
        }.bindAsEventListener(this));

        this.tree.observe('tree:loaded', function(event) {
            this._canDoBrowse = false; // Forbid do browse to prevent initial browsing for each folder in the uri.
            if (this._uri == "/") {
                this.tree.rootNode.select();
            } else {
                this.tree.openAndSelectNode(this._uri);
            }
            this._canDoBrowse = true;

            var node = this.tree.getSelectedNode();
            if (node) { node.scroll($(this._treeId).parentNode); }

            this.doBrowse(); // Do initial browse.
        }.bindAsEventListener(this));

        this.tree.observe('node:selected', function(event) {
            this._uri = event.memo.node.param.uri;

            new JSCookie(this._cookieName, this._uri);
            repositorySearch.model.setSelectedFolder(new Folder(event.memo.node));

            this.doBrowse();
        }.bindAsEventListener(this));

        this.tree.observe('node:mouseup', function(event) {
            repositorySearch.model.setContextFolder(new Folder(event.memo.node));
        });

        this.tree.showTreePrefetchNodes(this._uri);

        return this;
    },

    doBrowse: function() {
        if (this._canDoBrowse) {
            repositorySearch.fire(repositorySearch.Event.SEARCH_BROWSE, {
                uri: this._uri
            });
        }
    },

    getTreeId: function() {
        return this._treeId;
    },

    selectFolder: function(folder) {
        this.tree.openAndSelectNode(folder.URI);
    },

    reselectFolder: function(folder) {
        if (folder.node.isSelected()) {
            folder.node.deselect();
            folder.node.select();
        }
    },

    refreshFolder: function(folder) {
        this.selectFolder(folder);
        this.updateSubFolders(folder);
    },

    updateFolder: function (folder, label, description) {
        folder.label = label;
        folder.description = description;
        folder.node.changeName(folder.label);
        folder.node.param.extra.desc = folder.description;

        this.tree.resortSubtree(folder.node.parent);
        folder.node.parent.refreshNode();

//        folder.node.param.extra.date = folder.date;
    },

    updateSubFolders: function (folder) {
        if (!folder.node.hasChilds()) {
            folder.node.setHasChilds(true);
        }

        if (folder.node.isOpen()) {
            folder.node.handleNode();
        }

        folder.node.isloaded = false;
        folder.node.handleNode();
    },

    isFolderContextMenu: function(event) {
        return this.tree.getTreeNodeByEvent(event) && !this.tree.isIconEvent(event)
    },

    moveOrCopyFolder: function(targetFolder, toFolder, copy) {
        var parent = targetFolder.getParentFolder().node;

        copy || parent.removeChild(targetFolder.node);
        
        return this.tree.getTreeNodeChildren(toFolder.node, function(result) {
            if(result) {
                var node = result.detect(function(n) {
                    return n.param.id == targetFolder.name;
                });


                node && this.tree.openAndSelectNode(node.param.uri);
            }
        }.bind(this));
    }
};

///////////////////////////////
// Results panel object
///////////////////////////////
repositorySearch.resultsPanel =  {
    _list: null,
    _infiniteScroll: null,
    _resultListId: 'resultsList',
    _resultsContainerId: 'resultsContainer',

//    SCHEDULED_CLASS_NAME: 'scheduled',
//    NODE_CLASS_NAME: 'node',
//    LEAF_CLASS_NAME: 'leaf',
//    OPEN_CLASS_NAME: 'open',
//    CLOSED_CLASS_NAME: 'closed',

    NOTHING_TO_DISPLAY_ID: 'nothingToDisplay',

    NAME_PATTERN: '.resourceName',
    LINK_NAME_PATTERN: '.resourceName > a',
    DISCLOSURE_PATTERN: '.disclosure',
    SCHEDULED_PATTERN: '.scheduled',
    LOADING_CLASS_NAME: 'loading',
//    CHECKBOX_PATTERN: 'input[type="checkbox"]',

    initialize: function (options) {
        // List setup.
        this._list = new dynamicList.List(this._resultListId, {
            listTemplateDomId: "tabular_fourColumn_resources",
            itemTemplateDomId: "tabular_fourColumn_resources:leaf",
//            dragPattern: '.selected>.wrap',
            dragPattern: options.enableDnD ? '.draggable' : '',
            multiSelect: true,
            selectOnMousedown: true
        });

        this._intiListEvents();
        this._initDnD();

        this.getList().show();

        // Infinite scroll setup.
        this._infiniteScroll = new InfiniteScroll({
            id: this._resultsContainerId,
            contentId: this._resultListId
        });
        this._infiniteScroll.onLoad = function() {
            repositorySearch.fire(repositorySearch.Event.SEARCH_NEXT);
        };

        return this;
    },

    _createResourceItem: function(value) {
        var resourceItem;
        if (value.hasChildren) {
            resourceItem = new dynamicList.CompositeItem({
                cssClassName: layoutModule.NODE_CLASS,
                label: value.label.escapeHTML(),
                value: value,
                openHandlerPattern: ".disclosure.icon",
                closeHandlerPattern: ".disclosure.icon",
//                respondOnItemEvents: false,
                excludeFromSelectionTriggers: [".disclosure.icon"],
                listOptions: {
                    listTemplateDomId: "tabular_twoColumn_resources",
                    itemTemplateDomId: "tabular_twoColumn_resources:leaf",
                    multiSelect: true
                }
            });

            resourceItem.setLoading = function(b) {
                this.isLoading = b;
                this.refreshStyle();
            }
        } else {
            resourceItem = new dynamicList.ListItem({
                cssClassName: layoutModule.LEAF_CLASS,
                label: value.label.escapeHTML(),
                value: value
            });
        }

        resourceItem.processTemplate = function(element) {
            var isRunnable = canBeRun(this.getValue());

            var nameSelector = isRunnable ?
                               repositorySearch.resultsPanel.LINK_NAME_PATTERN : repositorySearch.resultsPanel.NAME_PATTERN;

            var name = element.select(nameSelector)[0];
            var desc = element.select(".resourceDescription")[0];

            name.update(this.getValue().label.escapeHTML());
            desc.update(this.getValue().description.escapeHTML());


            if (!this.getValue().isChild) {
                var path = element.select(".resourcePath")[0];
                var type = element.select(".column.three")[0];
                var date = element.select(".modifiedDate")[0];

                path.update(this.getValue().URIString);
                type.update(this.getValue().type);
                date.update(this.getValue().updateDate);
                date.title = this.getValue().updateDateTimestamp;
            }

            return element;
        };

        var baseRefreshStyle = resourceItem.refreshStyle;
        resourceItem.refreshStyle = function() {
            baseRefreshStyle.call(this);

            var element = this._getElement();

            if (this.getValue().isScheduled) { element.addClassName(layoutModule.SCHEDULED_CLASS); }
            if (this.isLoading) { element.addClassName(layoutModule.LOADING_CLASS); }
        };

        return resourceItem;
    },

    _initDnD: function() {
        var list = this.getList();
        list.setDragStartState = function(item, draggable, event) {
            dynamicList.List.prototype.setDragStartState.call(this, item, draggable, event);

            isMetaHeld(event, true) && $(document.body).addClassName(layoutModule.COPY_CLASS).setStyle({cursor: null});
            invokeBulkAction(isMetaHeld(event, true) ? "Copy" : "Move");
        };
        list.setDragEndState = function(item, draggable, event) {
            repositorySearch.CopyMoveController.cancel();

            repositorySearch.foldersPanel.tree.refreshDropTarget(false);
            $(document.body).removeClassName(layoutModule.COPY_CLASS);

            dynamicList.List.prototype.setDragEndState.call(this, item, draggable, event);
        };
    },

    _intiListEvents: function() {
        this.getList().observe('item:click', function(event) {
            var item = event.memo.item;
            var e = event.memo.targetEvent;
            var resource = item.getValue();

            if (this._isLinkEvent(e) && canBeRun(resource)) {
                invokeRedirectAction("RunResourceAction");
            }

            if (this._isScheduleIconEvent(e) && canBeScheduled(resource)) {
                invokeRedirectAction("ScheduleAction");
            }
        }.bindAsEventListener(this));

        this.getList().observe('item:selected', function(event) {
            var item = event.memo.item;
            var resources = this.getList().getSelectedItems().collect(function(lItem) {
                return lItem.getValue();
            });

            repositorySearch.model.setSelectedResources(resources);
            repositorySearch.actionModel.refreshToolbar();
        }.bindAsEventListener(this));

        this.getList().observe('item:unselected', function(event) {
            var item = event.memo.item;
            var resources = this.getList().getSelectedItems().collect(function(lItem) {
                return lItem.getValue();
            });

            repositorySearch.model.setSelectedResources(resources);
            repositorySearch.actionModel.refreshToolbar();
        }.bindAsEventListener(this));

        this.getList().observe('item:mouseup', function(event) {
//            var item = event.memo.item;
//            var resource = item.getValue();

//            repositorySearch.model.setContextResource(resource);
        });

        this.getList().observe('item:open', function(event) {
            var item = event.memo.item;
            var resource = item.getValue();

            if (!resource.isLoaded()) {
                item.setLoading(true);
                repositorySearch.fire(repositorySearch.Event.SEARCH_CHILDREN, { resource: resource, item: item });
            }
        });

        this.getList().observe('key:contextMenu', function(event) {
            var item = event.memo.node;
            var itemPosition = getBoxOffsets(item, true);
            var menuPosition = {
                menuLeft: itemPosition[0] + 100, //TODO: use constants for offsets
                menuTop: itemPosition[1] + 20    //TODO: use constants for offsets
            };

            if (this.getList().getSelectedItems().length > 1) {
                repositorySearch.actionModel.showResourceBulkMenu(event, menuPosition);
            } else {
                repositorySearch.actionModel.showResourceMenu(event, menuPosition);
            }
            Event.stop(event);
        }.bindAsEventListener(this));

        this.getList().observe('key:escape', function(event) {
            actionModel.hideMenu();
            Event.stop(event);
        });

    },

    _isLinkEvent: function(event) {
        var element = Event.element(event);

        return matchAny(element, [this.LINK_NAME_PATTERN]) != null;
    },

    _isScheduleIconEvent: function(event) {
        var element = Event.element(event);

        return element.match(this.SCHEDULED_PATTERN);
    },

    _isDisclosureEvent: function(event) {
        var element = Event.element(event);

        return matchAny(element, [this.DISCLOSURE_PATTERN]) != null;
    },

    _refreshEmptyListMessage: function() {
        var nothingToDisplay = $(this.NOTHING_TO_DISPLAY_ID);
        if (this._list.getItems().length == 0) {
            nothingToDisplay.removeClassName(layoutModule.HIDDEN_CLASS);
            centerElement(nothingToDisplay, {horz: true, vert: true});
        } else {
            nothingToDisplay.addClassName(layoutModule.HIDDEN_CLASS);
        }
    },

    getList: function() {
        return this._list;
    },

    removeResources: function(resources) {
        var children = resources.findAll(function(r) { return r.isChild });
        var other = resources.findAll(function(r) { return !r.isChild });
        
        var items = this.getList().getItems();

        var removedItems = [];
        var compositeItems = [];
        items.each(function(item) {
            item.isComposite && compositeItems.push(item);
            other.include(item.getValue()) && removedItems.push(item);
        });

        compositeItems.each(function(item) {
            if (item.getItems()) {
                item.removeItems(item.getItems().findAll(function(item) {
                    return children.include(item.getValue());
                }));
            }
        });

        this.getList().removeItems(removedItems);

        this._refreshEmptyListMessage();
    },

    setResources: function(resources, toItem) {
        var items = resources.collect(this._createResourceItem);

        if (toItem) {
            toItem.setItems(items);
            toItem.refresh();
        } else {
            this._infiniteScroll.reset();

            this.getList().setItems(items);
            this.getList().show();

            this._refreshEmptyListMessage();
        }
    },

    addResources: function(resources) {
        var items = resources.collect(this._createResourceItem);

        this.getList().addItems(items);
        this.getList().refresh();
    },

    isResourceContextMenu: function(event) {
        return this.getList().getItemByEvent(event)
    },

    updateResource: function(resource) {
        var items = this.getList().getItems();

        items.each(function(item) {
            if (item.getValue().URIString == resource.URIString) {
                item.setValue(resource);
                item.refresh();

                if (this.getList().isItemSelected(item)) {
                    // Reselecting to update item in selected list.
                    this.getList().selectItem(item);
                }
            }
        }.bind(this));
    }
};

///////////////////////////////
// Filter panel object
///////////////////////////////
repositorySearch.filtersPanel =  {
    _container: undefined,
    _filtersLists: {},
    _cookieName: "filtersPopularity",
    _ignoreFilterEvent: false,

    initialize: function (filtersMetaData, selectedFilters) {
        this._getContainer().update();

        // Process filters configuration
        filtersMetaData.each(function(filter, index) {
            this._getContainer().insert(new Element('ul', {
                id: filter.id,
                "data-tab-index": 5 + index,
                "data-component-type": "list"
            }));

            var list = this._createFiltersList(filter.id, filter);
            list.show();

            this._filtersLists[filter.id] = list;
        }.bind(this));

        for (var filterId in selectedFilters) {
            this.select(filterId, selectedFilters[filterId])
        }

        return this;
    },

    _createItemsList: function(filterMetaData) {
        var optionsMetaData = filterMetaData.options;
        var index = 0;

        var allItems = optionsMetaData.collect(function(optionMetaData) {
            return new dynamicList.ListItem({
                value: optionMetaData,
                cssClassName: layoutModule.LEAF_CLASS,
                label: repositorySearch.getMessage(optionMetaData.labelId)
            });
        }).partition(function() { return filterMetaData.showCount === -1 || filterMetaData.showCount > index++; });

        if (allItems[1].length > 0) {
             allItems[0].push(new dynamicList.CompositeItem({
                value: {isMore: true},
                templateDomId: "list_responsive_filters:node",
                openUp: true,
                openHandlerPattern: ".more.launcher",
                closeHandlerPattern: ".fewer.launcher",
                respondOnItemEvents: false,
                items: allItems[1]
            }));
        }

        return allItems[0];
    },

    _createFiltersList: function(filterId, filterMetaData) {
        var list = new dynamicList.List(filterId, {
            listTemplateDomId: "list_responsive_filters",
            itemTemplateDomId: "list_responsive_filters:leaf",
            items: this._createItemsList(filterMetaData)
        });

        // Add separator item to the list
        list.addItems([new dynamicList.CompositeItem({
            templateDomId: "list_responsive_filters:separator",
            respondOnItemEvents: false,
            value: { isSeparator: true }
        })].compact());

        // When item is selected fire filter event
        list.observe("item:selected", function(event) {
            var item = event.memo.item;

            if (item.getValue().isSeparator || item.getValue().isMore || this._ignoreFilterEvent) { return; }

            this._increasePopularity(list.getId(), item.getValue().id);

            repositorySearch.fire(repositorySearch.Event.SEARCH_FILTER, {
                filterId: list.getId(),
                optionId: item.getValue().id
            });
        }.bindAsEventListener(this));

        return list;
    },

    _increasePopularity: function(filterId, optionId) {
        var cookie = new JSCookie(this._cookieName);
        var storedJson = (cookie.value) ? cookie.value.evalJSON() : {};

        var list = this._filtersLists[filterId], listId = list.getId();

        if (!storedJson[listId]) {
            storedJson[listId] = {};
        }

        list.getItems().each(function(item) {
            var itemId = item.getValue().id;

            var p = (storedJson[listId][itemId]) ? storedJson[listId][itemId] : 0;

            storedJson[listId][itemId] = (listId === filterId && itemId === optionId) ? p + 1 : p;
        });

//        console.log(storedJson);
        new JSCookie(this._cookieName, Object.toJSON(storedJson));
    },

    select: function(filterId, optionId, isRestore) {
        var list = this._filtersLists[filterId];

        var filterOptionSelector = function(item) {
            if(item.getValue().id == optionId && !item.isSelected()) {
                this._ignoreFilterEvent = isRestore;
                item.select();
                this._ignoreFilterEvent = false;

                throw $break;
            }

            if (item.isComposite) {
                var element = item._getElement();
                if (!baseList.isItemOpen(element)) {
                    baseList.openItem(element);
                }

                if (item.getItems()) {
                    item.getItems().each(filterOptionSelector);
                }
            }
        }.bind(this);

        list.getItems().each(filterOptionSelector);
    },

    _getContainer: function() {
        if (!this._container) {
            this._container = $('filtersPanel');
        }
        return this._container;
    }
};

///////////////////////////////
// Filter path object
///////////////////////////////
repositorySearch.filterPath =  {
    _containerId: "filterPath",
    _contentBodySelector: ".primary.column>.content>.body",

    initialize: function () {
        this._filterPathList = new dynamicList.List(this._containerId, {
            listTemplateDomId: "list_control_path",
            itemTemplateDomId: "list_control_path:step"
        });

        // When item is selected fire rollback event
        this._filterPathList.observe("item:selected", function(event) {
            var item = event.memo.item;

            if (!item.getValue().isLast) {
                repositorySearch.fire(repositorySearch.Event.SEARCH_ROLLBACK, {
                    position: item.getValue().position
                });
            }
        });

        return this;
    },

    setPathItems: function(pathItems) {
        if (pathItems.length > 1) {
            var lastIndex = pathItems.length - 1;
            var listItems = pathItems.collect(function(pathItem, index) {

                pathItem.isLast = index == lastIndex;
                return new dynamicList.ListItem({
                    label: pathItem.label,
                    value: pathItem
                });
            });

            this._filterPathList.setItems(listItems);
            this._filterPathList.show();

            $(this._containerId).up().removeClassName('hidden');
            $(document.body).select(this._contentBodySelector)[0].addClassName('showingSubHeader');
        } else {
            this._filterPathList.setItems([]);
            this._filterPathList.show();

            $(this._containerId).up().addClassName('hidden');
            $(document.body).select(this._contentBodySelector)[0].removeClassName('showingSubHeader');
        }
    }
};

///////////////////////////////
// Sorters panel object
///////////////////////////////
repositorySearch.sortersPanel = {
    _LABEL_TEMPLATE_DOM_ID: "sortPanelLabelTemplate",
    _containerId: "sortMode",
    _ignoreSortEvent: false,

    sortersList: null,

    initialize: function (sortersMetaData, selectedSorter) {
        var labelItem = new dynamicList.ListItem({
            label: repositorySearch.getMessage("SEARCH_SORT_BY") + ":",
            value: {isLabel: true},
            templateDomId: "tabSet_control_horizontal_responsive:label",
            respondOnItemEvents: false
        });

        var sortItems = sortersMetaData.collect(function(sorterMetaData, index) {
            return new dynamicList.ListItem({
                label: repositorySearch.getMessage(sorterMetaData.labelId),
                value: sorterMetaData
            });
        });

        this.sortersList = new dynamicList.List(this._containerId, {
            listTemplateDomId: "tabSet_control_horizontal_responsive",
            itemTemplateDomId: "tabSet_control_horizontal_responsive:tab",
            items: [labelItem].concat(sortItems)
        });

        // When item is selected fire sort event
        this.sortersList.observe(this.sortersList.Event.ITEM_SELECTED, function(event) {
            var item = event.memo.item;

            if (item.getValue().isLabel || this._ignoreSortEvent) { return; }

            repositorySearch.fire(repositorySearch.Event.SEARCH_SORT, {
                sorterId: item.getValue().id
            });
        });

        this.sortersList.show();

        labelItem.disable();

        this.select(selectedSorter);

        return this;
    },

    select: function(sorterId, isRestore) {

        this.sortersList.getItems().each(function(item) {
            if(item.getValue().id == sorterId && !item.isSelected()) {
                this._ignoreSortEvent = isRestore;
                this.sortersList.selectItem(item);
                this._ignoreSortEvent = false;

                return;
            }
        }.bind(this));
    },

    _getContainer: function() {
        if (!this._container) {
            this._container = $(this._containerId);
        }
        return this._container;
    },

    _getLabelTemplate: function() {
        var e = $(this._LABEL_TEMPLATE_DOM_ID).cloneNode(true);
        e.removeAttribute('id');

        return e;
    }
};

/////////////////////////////////
// Repository permissions dialog
/////////////////////////////////
var ResourcePermissions = function(resource) {
    this._resource = resource;
    this._isVisible = false;
    this._listId = this.ENTITY_LIST_ID;
    this._listContainerId = this.LIST_CONTAINER_ID;
    this._searchBoxId = this.SEARCH_BOX_ID;

    this.viewBy = "USER",

    this._processTemplate();
};

ResourcePermissions.addVar("TEMPLATE_DOM_ID", "permissions");
ResourcePermissions.addVar("TOOLTIP_TEMPLATE_DOM_ID", "orgTooltip");
ResourcePermissions.addVar("LIST_TEMPLATE_ID", "tabular_twoColumn_setLeft");
ResourcePermissions.addVar("ITEM_TEMPLATE_ID", "tabular_twoColumn_setLeft:leaf");
ResourcePermissions.addVar("WAIT_ITEM_TEMPLATE_ID", "tabular_twoColumn_setLeft:loading");
ResourcePermissions.addVar("ENTITY_LIST_ID", "permissionsList");
ResourcePermissions.addVar("LIST_CONTAINER_ID", "permissionsListContainer");
ResourcePermissions.addVar("SEARCH_BOX_ID", "searchPermissionsBox");

ResourcePermissions.addVar("NAME_TOOLTIP_PATTERN", ".one");
ResourcePermissions.addVar("NAME_PATTERN", ".one>a.launcher");
ResourcePermissions.addVar("PERMISSIONS_PATTERN", ".two>select");
ResourcePermissions.addVar("VIEW_BY_TAB_SET_PATTERN", "#permissionsViewBy");
ResourcePermissions.addVar("TAB_PATTERN", ".tab>p");
ResourcePermissions.addVar("PATH_PATTERN", ".path");
ResourcePermissions.addVar("SUBMIT_BUTTON", "#permissionsOk");
ResourcePermissions.addVar("APPLAY_BUTTON", "#permissionsApply");
ResourcePermissions.addVar("CANCEL_BUTTON", "#permissionsCancel");
ResourcePermissions.addVar("BODY_PATTERN", "div.body");

ResourcePermissions.addMethod("_processTemplate", function() {
    this._dom = $(this.TEMPLATE_DOM_ID).cloneNode(true);

    this._dom.writeAttribute('id', null);

    var path = this._dom.select(this.PATH_PATTERN)[0];
    path.update(this._resource.URIString.truncate(50).escapeHTML());
    path.writeAttribute("title", this._resource.URIString.escapeHTML());

    this._viewByTabSet = this._dom.select(this.VIEW_BY_TAB_SET_PATTERN)[0];
    this._byUsersButton = this._dom.select(this.TAB_PATTERN)[0];
    this._byRolesButton = this._dom.select(this.TAB_PATTERN)[1];
    this._submitButton = this._dom.select(this.SUBMIT_BUTTON)[0];
    this._applyButton = this._dom.select(this.APPLAY_BUTTON)[0];
    this._cancelButton = this._dom.select(this.CANCEL_BUTTON)[0];

    this._byUsersButton.viewType = "USER";
    this._byRolesButton.viewType = "ROLE";

    this._submitButton.writeAttribute('id', null);
    this._applyButton.writeAttribute('id', null);
    this._cancelButton.writeAttribute('id', null);

    var list = this._dom.select('#' + this.ENTITY_LIST_ID)[0];
    var listContainer = this._dom.select('#' + this.LIST_CONTAINER_ID)[0];
    var searchBox = this._dom.select('#' + this.SEARCH_BOX_ID)[0];

    this._listId = list.writeAttribute('id', null).identify();
    this._listContainerId = listContainer.writeAttribute('id', null).identify();
    this._searchBoxId = searchBox.writeAttribute('id', null).identify();
});

ResourcePermissions.addMethod('_updateValueAndLabel', function(element, veSelector, value, leSelector) {
    var valueElement = element.select(veSelector)[0];

    valueElement.writeAttribute('id', null);
    valueElement.setValue(value);

    element.select(leSelector)[0].writeAttribute('for', valueElement.identify());

    return valueElement;
});

ResourcePermissions.addMethod('_updateContentAndLabel', function(element, veSelector, content, leSelector) {
    var valueElement = element.select(veSelector)[0];

    valueElement.writeAttribute('id', null);
    valueElement.update(content);

    element.select(leSelector)[0].writeAttribute('for', valueElement.identify());

    return valueElement;
});

ResourcePermissions.addMethod("_buttonClickHandler", function(e) {
    var element = e.element();

    if (!this._waiting) {
        var button = matchAny(element, [layoutModule.BUTTON_PATTERN], true);

        var uri = this._resource.URIString;

        if ([this._submitButton, this._applyButton].include(button)) {
            this._byUsersButton.addClassName(layoutModule.BUTTON_CLASS);
            this._byRolesButton.addClassName(layoutModule.BUTTON_CLASS);

            repositorySearch.fire(repositorySearch.PermissionEvent.UPDATE, {
                uri: uri,
                entities: this.getChangedEntities(),
                finishEdit: (button == this._submitButton)
            });
        }

        if ([this._byUsersButton, this._byRolesButton].include(button)) {
            if (this.isChanged()) {
                this._showWarning();
                e.stop();
            } else {
                this._hideWarning();

                this.viewBy = button.viewType;
                repositorySearch.fire(repositorySearch.PermissionEvent.BROWSE, {uri: uri, type: this.viewBy});
            }
        }

        [this._cancelButton].include(button) && this.hide();
    }
});

ResourcePermissions.addMethod("_showWarning", function() {
    this._dom.select(this.BODY_PATTERN)[0].addClassName(layoutModule.ERROR_CLASS);
});

ResourcePermissions.addMethod("_hideWarning", function() {
    this._dom.select(this.BODY_PATTERN)[0].removeClassName(layoutModule.ERROR_CLASS);
});

ResourcePermissions.addMethod("_launcherClickHandler", function(e) {
    var element = e.element();

    if (!this._waiting) {
        var launcher = matchAny(element, [this.NAME_PATTERN], true);

        if (launcher) {
            var li = element.up('li');

            if (li && li.listItem) {
                var value = li.listItem.getValue();
                value.navigateToManager();
            }
        }
    }

    e.stop();
});

ResourcePermissions.addMethod("_selectChangeHandler", function(e) {
    var element = e.element();
    e.stop();

    if (this._waiting) { return; }

    if (element.tagName.toLowerCase() == 'select') {

        var newPermission = element.options[element.selectedIndex].value;
        var li = element.up('li');

        if (li && li.listItem) {
            var value = li.listItem.getValue();

            li.listItem.getValue().permission.newPermission =
                    (newPermission != value.permission.getResolvedPermission()) ? newPermission : undefined;

            li.listItem.refresh();
        }
    }

    if (this.isChanged()) {
        this._byUsersButton.removeClassName(layoutModule.BUTTON_CLASS);
        this._byRolesButton.removeClassName(layoutModule.BUTTON_CLASS);
    } else {
        this._byUsersButton.addClassName(layoutModule.BUTTON_CLASS);
        this._byRolesButton.addClassName(layoutModule.BUTTON_CLASS);
    }
});

ResourcePermissions.addMethod("_selectMouseOverHandler", function(e) {
    var element = matchAny(e.element(), [this.PERMISSIONS_PATTERN], true);
    element && e.stop();
});

ResourcePermissions.addMethod("_initControls", function() {
    this.list = new dynamicList.List(this._listId, {
        listTemplateDomId: this.LIST_TEMPLATE_ID,
        itemTemplateDomId: this.ITEM_TEMPLATE_ID
    });

    this._infiniteScroll = new InfiniteScroll({
        id: $(this._listId).up(0),
        contentId: this._listId
    });

    this._searchBox = new SearchBox({
        id: this._searchBoxId
    });

    var uri = this._resource.URIString;
    this._infiniteScroll.onLoad = function() {
        if (!this._waiting) {
            repositorySearch.fire(repositorySearch.PermissionEvent.NEXT, {
                text: this._searchBox.getText(),
                uri: uri,
                type: this.viewBy
            });
        }
    }.bind(this);
    this._searchBox.onSearch = function(text) {
        if (!this._waiting) {
            if (this.isChanged()) {
                this._showWarning();
            } else {
                this._hideWarning();
                
                repositorySearch.fire(repositorySearch.PermissionEvent.SEARCH, {
                    text: text,
                    uri: uri,
                    type: this.viewBy
                });
            }
        }
    }.bind(this);
});

ResourcePermissions.addMethod("show", function() {
    if (!this._isVisible) {
        document.body.insert(this._dom);

        this._initControls();
        
        this.list.setItems([]);
        this.list.show();

        orgModule.entityList._createEntityItem = this._createEntityItem;

        this.viewBy = "ROLE";
        repositorySearch.fire(repositorySearch.PermissionEvent.BROWSE, {
            initialize: true,
            uri: this._resource.URIString,
            type: this.viewBy,
            isFolder: this._resource.isFolder()
        });

        this._isVisible = true;

        dialogs.popup.show(this._dom);

        this._dom.observe('click', this._buttonClickHandler.bindAsEventListener(this));
        this._dom.observe('click', this._launcherClickHandler.bindAsEventListener(this));
        // Change event not bubbled up in IE
//        this._dom.observe('change', this._selectChangeHandler.bindAsEventListener(this));
        this._dom.observe('mouseover', this._selectMouseOverHandler.bindAsEventListener(this));
    }
});

ResourcePermissions.addMethod("showAndWait", function() {
    this._waiting = true;
    this.show();

    this._waitingItem = new dynamicList.ListItem({
        templateDomId: this.WAIT_ITEM_TEMPLATE_ID
    });
    this.list.addItems([this._waitingItem]);
    this.list.refresh();
    
    this.disable();
});

ResourcePermissions.addMethod("stopWaiting", function() {
    if (this._waiting) {
        this._waiting = false;
        this.list.removeItems([this._waitingItem]);

        this.enable();
    }
});

ResourcePermissions.addMethod("hide", function() {
    dialogs.popup.hide(this._dom);
    this._dom.remove();
    this._dom.stopObserving('click');
    this._dom.stopObserving('change');
    this._dom.stopObserving('mouseover');

    repositorySearch.dialogsPool.removePermissionsDialog(this._resource);
});

ResourcePermissions.addMethod("enable", function() {
    this._searchBox.enable();

    buttonManager.enable(this._byUsersButton);
    buttonManager.enable(this._byRolesButton);
});

ResourcePermissions.addMethod("disable", function() {
    this._searchBox.disable();

    buttonManager.disable(this._byUsersButton);
    buttonManager.disable(this._byRolesButton);
});

ResourcePermissions.addMethod("_createItem", function(value) {
    var item = new dynamicList.ListItem({
            label: value.getDisplayName().escapeHTML(),
            value: value
        });

    var nameTooltipSelector = this.NAME_TOOLTIP_PATTERN;
    var nameSelector = this.NAME_PATTERN;
    var permissionsSelector = this.PERMISSIONS_PATTERN;
    var template = this.TOOLTIP_TEMPLATE_DOM_ID;
    var _this = this;

    item.processTemplate = function(element) {
        var nameTooltip = element.select(nameTooltipSelector)[0];
        var name = element.select(nameSelector)[0];
        var permissions = element.select(permissionsSelector)[0];

        var permission = this.getValue().permission;
        var tenantId = this.getValue().tenantId;

        if (permission.newPermission) {
            name.addClassName(layoutModule.EMPHASIS_CLASS);
        } else {
            name.removeClassName(layoutModule.EMPHASIS_CLASS);
        }
        name.update(this.getValue().getDisplayName().escapeHTML());

        tenantId && tenantId.length > 0 && new JSTooltip(nameTooltip, { text: tenantId, templateId: template });

        permissions.update("");

        var index = 0, permissionsConfig = repositorySearch.model.getConfiguration().permissions;
        for(var i=0; i<permissionsConfig.length; i++) {
            var label = repositorySearch.getMessage(permissionsConfig[i].labelId);
            var option = new Element('option', { value: permissionsConfig[i].name });

            permissions.insert(option.update(permission.inheritedPermission == permissionsConfig[i].name
                    ? label + " *" : label));

            if (permission.newPermission) {
                permission.newPermission == permissionsConfig[i].name && (index = i);
            } else {
                permission.getResolvedPermission() == permissionsConfig[i].name && (index = i);
            }
        }

        permissions.observe('change', _this._selectChangeHandler.bindAsEventListener(_this));
        permissions.selectedIndex = index;

        if (this.getValue().permission.isDisabled) {
            permissions.writeAttribute("disabled", "disabled");
        }

        return element;
    };

    return item;
});

ResourcePermissions.addMethod("addEntities", function(entities) {
    var items = entities.collect(this._createItem.bind(this));

    this.list.addItems(items);
    this.list.refresh();
});

ResourcePermissions.addMethod("setEntities", function(entities) {
    this.list.setItems([]);

    this.addEntities(entities);
});

ResourcePermissions.addMethod("getChangedEntities", function() {
    var items = this.list.getItems();

    var changed = [];
    items.each(function(item) {
        var value = item.getValue();
        if (value.permission && value.permission.newPermission) {
            changed.push(value);
        }
    });

    return changed;
});

ResourcePermissions.addMethod("updateEntities", function(entities) {
    var items = this.list.getItems();

    items.each(function(item) {
        var value = item.getValue();

        var updated = entities.detect(function(entity) {
            return entity.equals(value);
        });

        if (updated) {
            item.setValue(updated);
            item.refresh();
        }
    });
});

ResourcePermissions.addMethod("isChanged", function() {
    return this.getChangedEntities().length > 0;
});

/////////////////////////////////////////////////////////////////
// Poll with all properties and permissions dialogs.
// Use this pool object to create instances of thouse dialogs.
/////////////////////////////////////////////////////////////////
repositorySearch.dialogsPool = {
    POOL_NOT_FOUND_EXCEPTION: "PoolNotFoundException",
    DIALOD_EXIST_EXCEPTION: "DialodExistException",
    NULL_RESOURCE_EXCEPTION: "NullResourceException",

    _permissionsDialogPool: {},
    _propertiesDialogPool: {},

    _getPool: function(clazz) {
        var pool;

        clazz == ResourcePermissions && (pool = this._permissionsDialogPool);
        clazz == ResourceProperties && (pool = this._propertiesDialogPool);

        if (pool) {
            return pool;
        } else {
            throw {
                name: this.POOL_NOT_FOUND_EXCEPTION,
                message: "Can't find pool for " + clazz.toString()
            }
        }
    },

    _createDialog: function(clazz, resource, options) {
        var uri = resource.URIString;
        var pool = this._getPool(clazz);

        if (resource == null) {
            throw {
                name: this.NULL_RESOURCE_EXCEPTION,
                message: "Resource is null."
            }
        }

        if (!pool[uri]) {
            pool[uri] = new clazz(resource, options);
        } else {
            throw {
                name: this.DIALOD_EXIST_EXCEPTION,
                message: clazz.toString() + " dilaog for resource '" + uri + "' arleady exist."
            }
        }

        return pool[uri];
    },

    _createOrGetDialog: function(clazz, resource, options) {
        try {
            return this._createDialog(clazz, resource, options);
        } catch (e) {
            if (e.name == this.DIALOD_EXIST_EXCEPTION) {
                return this._getDialog(clazz, resource)
            } else {
                throw e;
            }
        }
    },

    _getDialog: function(clazz, resourceOrUri) {
        var uri = Object.isString(resourceOrUri) ? resourceOrUri : resourceOrUri.URIString;
        return this._getPool(clazz)[uri];
    },

    _getAllDialogs: function(clazz) {
        var pool = this._getPool(clazz), dialogs = [];
        for (var uri in pool) { pool[uri] && dialogs.push(pool[uri]); }

        return dialogs;
    },

    _removeDialog: function(clazz, resourceOrUri) {
        var uri = Object.isString(resourceOrUri) ? resourceOrUri : resourceOrUri.URIString;
        this._getPool(clazz)[uri] = undefined;
    },

    createPermissionsDialog: function(resource) { return this._createDialog(ResourcePermissions, resource); },
    createPropertiesDialog: function(resource) { return this._createDialog(ResourceProperties, resource); },

    createOrGetPermissionsDialog: function(resource) { return this._createOrGetDialog(ResourcePermissions, resource); },
    createOrGetPropertiesDialog: function(resource, options) {
        return this._createOrGetDialog(ResourceProperties, resource, options);
    },

    getAllPermissionsDialogs: function() { return this._getAllDialogs(ResourcePermissions); },
    getAllPropertiesDialogs: function() { return this._getAllDialogs(ResourceProperties); },

    getPermissionsDialog: function(resourceOrUri) { return this._getDialog(ResourcePermissions, resourceOrUri); },
    getPropertiesDialog: function(resourceOrUri) { return this._getDialog(ResourceProperties, resourceOrUri); },

    removePermissionsDialog: function(resourceOrUri) { return this._removeDialog(ResourcePermissions, resourceOrUri); },
    removePropertiesDialog: function(resourceOrUri) { return this._removeDialog(ResourceProperties, resourceOrUri); }
};

/////////////////////////////////
// Repository properties dialog
/////////////////////////////////
var ResourceProperties = function(resource, options) {
    this._resource = resource;
    this._changedCallback = options.changedCallback;
    this._showMode = options.showMode;

    this._processTemplate();
};

ResourceProperties.addVar("TEMPLATE_DOM_ID", "propertiesResource");

ResourceProperties.addMethod("_processTemplate", function() {
    this._dom = $(this.TEMPLATE_DOM_ID).cloneNode(true);

    this._dom.writeAttribute('id', null);

    var title = this._dom.select('.title')[0];
    title.update((title.innerHTML.strip() + ": " +  this._resource.label.truncate(50)).escapeHTML());

    this._label = this._updateValueAndLabel(this._dom, 'input#displayName', this._resource.label,
            'label[for="displayName"]');
    this._description = this._updateContentAndLabel(this._dom, 'textarea#description', this._resource.description,
            'label[for="description"]');

    if (this._showMode) {
        this._dom.addClassName('showMode');

        this._label.writeAttribute('readonly', 'readonly');
        this._description.writeAttribute('readonly', 'readonly');
    }

    this._updateValueAndLabel(this._dom, 'input#resourceID', this._resource.name, 'label[for="resourceID"]');
    this._updateValueAndLabel(this._dom, 'input#type', this._resource.type, 'label[for="type"]');
    this._updateValueAndLabel(this._dom, 'input#createdDate', this._resource.date, 'label[for="createdDate"]');
    this._updateValueAndLabel(this._dom, 'input#userAccess', this._resource.permissionsToString(), 'label[for="userAccess"]');

    this._submitButton = this._dom.select('button.submit')[0];
    this._cancelButton = this._dom.select('button.cancel')[0];
    this._okButton = this._dom.select('button.ok')[0];
});

ResourceProperties.addMethod('_updateValueAndLabel', function(element, veSelector, value, leSelector) {
    var valueElement = element.select(veSelector)[0];

    valueElement.writeAttribute('id', null);
    valueElement.setValue(value);

    element.select(leSelector)[0].writeAttribute('for', valueElement.identify());

    return valueElement;
});

ResourceProperties.addMethod('_updateContentAndLabel', function(element, veSelector, content, leSelector) {
    var valueElement = element.select(veSelector)[0];

    valueElement.writeAttribute('id', null);
    valueElement.update(content);

    element.select(leSelector)[0].writeAttribute('for', valueElement.identify());

    return valueElement;
});

ResourceProperties.addMethod("_buttonClickHandler", function(e) {
    var button = matchAny(e.element(), [layoutModule.BUTTON_PATTERN], true);
    if (button == this._submitButton) {
        if (this._showMode) {
            this._hide();
        } else {
            if (this._isDataValid()) {
                if (this._changedCallback) {
                    var resource = this._resource.clone();
                    resource.label = this._label.getValue();
                    resource.description = this._description.getValue();

                    this._changedCallback(resource);
                }

                this._hide();
            }
        }
    } else if (button == this._cancelButton || button == this._okButton) {
        this._hide();
    }
});

ResourceProperties.addMethod("_isDataValid", function(e) {
    return ValidationModule.validate([
        {
            validator: ResourcesUtils.labelValidator,
            element: this._label
        },
        {
            validator: ResourcesUtils.descriptionValidator,
            element: this._description
        }
    ]);
});

ResourceProperties.addMethod("show", function(options) {
    document.body.insert(this._dom);

    if (options && options.cascade) {
        dialogs.popup.show(this._dom, false, options);
    } else {
        dialogs.popup.show(this._dom);
    }

    this._dom.observe('click', this._buttonClickHandler.bindAsEventListener(this));
});

ResourceProperties.addMethod("_hide", function() {
    dialogs.popup.hide(this._dom);

    this._dom.remove();
    this._dom.stopObserving('click');

    repositorySearch.dialogsPool.removePropertiesDialog(this._resource);
});

ResourceProperties.addMethod("isChanged", function() {
    return this._resource.label != this._label.getValue() || this._resource.description != this._description.getValue();

});


repositorySearch.showDeleteFolderConfirm = function(folder) {
    var result = confirm(repositorySearch.getMessage("SEARCH_DELETE_FOLDER_CONFIRM_MSG", {
        folderUri: folder.URI
    }));

    if (result) {
        var action = new repositorySearch.ServerAction.
                createFolderAction(repositorySearch.FolderAction.DELETE, {folder: folder});

        action.invokeAction();
    }
};

repositorySearch.showCreateFolderConfirm = function(folder) {
    var toFolder;
    var dialog = $('addFolder'), name = $('addFolderInputName'), description = $('addFolderInputDescription'),
            add = $('addFolderBtnAdd'), cancel = $('addFolderBtnCancel');

    var doShow = function(folder) {
        toFolder = folder;

        dialogs.popup.show(dialog);

        name.setValue(repositorySearch.messages["action.create.folder.name"]);

        accessibilityModule.disable();
        setTimeout(function() {
            name.focus();
            name.select();
        }, 500);
    };

    var doHide = function(event) {
        name.clear();
        description.clear();
        ValidationModule.hideError(name);

        dialogs.popup.hide(dialog);

        accessibilityModule.enable();
        event.stop();
    };

    var doValidate = function() {
        var isValid = ValidationModule.validate([
            {
                validator: ResourcesUtils.labelValidator,
                element: name
            },
            {
                validator: ResourcesUtils.descriptionValidator,
                element: description
            }
        ]);

        return isValid;
    };

    var doAdd = function(event) {
        if (add.readAttribute('disabled') === "disabled") { return; }

        new repositorySearch.ServerAction.createFolderAction(repositorySearch.FolderAction.CREATE, {
            toFolder: toFolder,
            label: name.getValue(),
            desc: description.getValue()
        }).invokeAction();

        doHide(event);
    };

    add.observe('click', function(event) {
        if (doValidate()) {
            doAdd(event);
        }
        event.stop();
    });
    cancel.observe('click', doHide);

    repositorySearch.showCreateFolderConfirm = doShow;
    doShow(folder);
};

repositorySearch.showDeleteResourceConfirm = function(resource) {
    var result = confirm(repositorySearch.getMessage("SEARCH_DELETE_CONFIRM_MSG", {
        resourceUri: resource.URIString
    }));
    if (result) {
        var action = new repositorySearch.ServerAction.
                createResourceAction(repositorySearch.ResourceAction.DELETE, {resources: [resource]});

        action.invokeAction();
    }
};

repositorySearch.showBulkDeleteResourcesConfirm = function(resources) {
    var result = confirm(repositorySearch.getMessage("SEARCH_BULK_DELETE_CONFIRM_MSG", {
        count: resources.length
    }));
    if (result) {
        var action = new repositorySearch.ServerAction.
                createResourceAction(repositorySearch.ResourceAction.DELETE, {resources: resources});

        action.invokeAction();
    }
};

repositorySearch.showResourceProperties = function(resource, options) {
    var resourceProperties = repositorySearch.dialogsPool.createOrGetPropertiesDialog(resource, {
        showMode: true
    });
    resourceProperties.show(options);
};

repositorySearch.editResourceProperties = function(resource, options) {
    var resourceProperties = repositorySearch.dialogsPool.createOrGetPropertiesDialog(resource, {
        changedCallback: function(resource) {
            var action = new repositorySearch.ServerAction.
                    createResourceAction(repositorySearch.ResourceAction.UPDATE, {resource: resource});

            action.invokeAction();
        }
    });
    resourceProperties.show(options);
};

repositorySearch.showFolderProperties = function(folder) {
    var folderProperties = repositorySearch.dialogsPool.createOrGetPropertiesDialog(folder, {
        showMode: true
    });
    folderProperties.show();
};

repositorySearch.editFolderProperties = function(folder) {
    var folderProperties = repositorySearch.dialogsPool.createOrGetPropertiesDialog(folder, {
        changedCallback: function(folder) {
            var action = new repositorySearch.ServerAction.
                    createFolderAction(repositorySearch.FolderAction.UPDATE, { folder: folder });

            action.invokeAction();
        }
    });
    folderProperties.show();
};

repositorySearch.editResourcePermissions = function(resource) {
    var dialog = repositorySearch.dialogsPool.createOrGetPermissionsDialog(resource);
    dialog.showAndWait();
};

repositorySearch.editFolderPermissions = function(folder) {
    var dialog = repositorySearch.dialogsPool.createOrGetPermissionsDialog(folder);
    dialog.showAndWait();
};

repositorySearch.showUploadThemeConfirm = function(folder) {
    var toFolder;
    var dialog = $('uploadTheme'), themeName = $('themeName'), zip = $('themeZip'),
            upload = $('uploadThemeBtnUpload'), cancel = $('uploadThemeBtnCancel');

    var doShow = function(folder) {
        toFolder = folder;

        dialogs.popup.show(dialog);

        themeName.setValue(repositorySearch.messages["RM_NEW_THEME_NAME"]);
        themeName.select();
        themeName.focus();
    };

    var doHide = function(event) {
        themeName.clear();
        zip.clear();

        dialogs.popup.hide(dialog);

        event.stop();
    };

    var doValidate = function() {
        var isValid = ValidationModule.validate([
            {
                validator: ResourcesUtils.labelValidator,
                element: themeName
            },
            {
                validator: ResourcesUtils.zipFileTypeValidator,
                element: zip
            }
        ]);

        return isValid;
    };

    var doUpload = function(event) {

        var options = {};
        options.themeName = themeName.getValue();
        options._eventId = 'uploadTheme';
        options._flowExecutionKey = repositorySearch.flowExecutionKey;
        options.folderUri = toFolder.URI;
        var callback = function(responseBody) {
            //zip var should be refreshed to point to correct file input
            zip = $('themeZip');
            if (responseBody) {
                try {
                    var respObj = responseBody.evalJSON();
                    if (respObj && respObj.status == 'ERROR') {
                        alert(respObj.data);
                    } else {
                        alert(repositorySearch.messages["RM_UPLOAD_THEME_ERROR"]);
                    }
                } catch (ex) {
                    alert(ex);
                }
            }
            repositorySearch.foldersPanel.refreshFolder(toFolder);
        }
        fileSender.upload(zip, 'searchFlow', options, callback);

        doHide(event);
    };

    upload.observe('click', function(event) {
        if (doValidate()) {
            doUpload(event);
        }
        event.stop();
    });
    cancel.observe('click', doHide);

    repositorySearch.showUploadThemeConfirm = doShow;
    doShow(folder);
};
