var JS = {};
JS.isProVersion = function () {

    return js_edition && js_edition == 'PRO';
}

var BaseUserAndRoleManager = Class.create({
    initialize: function(viewer, editor, creator, dataRetriever, dataUpdater, messageSource,
                         defaultSearchName, defaultTenantId, selectedItem) {

        this.selectedItem = selectedItem;

        this.viewer = viewer;
        this.editor = editor;
        this.creator = creator;

        this.viewer.hide();
        this.editor.hide();

        this.dataRetriever = dataRetriever;
        this.dataUpdater = dataUpdater;

        this.messageSource = messageSource;

        this.minHeigth = 300;

        this.tenantTreeId = 'tenantTree';
        this.managerBodyId = 'managerBody';
        this.managerTableId = 'managerTable';

        this.nothingSelected = $('nothingSelected');

        this.searchNameInput = new SearchTextBox("searchNameInput", this.messageSource.getMessage('defaultSearchText'));
        this.searchItemBtn = $('searchBtn');
        this.addItemBtn = new LinkButton('addItemBtn', 'toolbarLink', 'toolbarLinkHover', 'toolbarLinkDisabled')

        this.defaultSearchName = defaultSearchName;
        this.defaultTenantId = defaultTenantId;

        this.tenantTree = (JS.isProVersion()) ? new TenantTreePro(this.tenantTreeId, defaultTenantId) : new TenantTreeOS();
        this.itemList = new PaginatedListBox("items", null, 100);

        this.setUpDataRetriever();
        this.setUpDataUpdater();
        this.setUpItemSearch();
        this.setUpItemList();
        this.setUpViewer();
        this.setUpEditor();
        this.setUpCreator();
        this.setUpTooltip();
        this.resize();

        this.tenantTree.load();
    },

    setUpDataRetriever: function() {

        if (this.dataRetriever.onItemDetailsRetrieved == null) {

            this.dataRetriever.onItemDetailsRetrieved = function (data) {

                this.viewer.setTenantId(this.tenantTree.getSelectedTenant());
                this.viewer.show();
                this.viewer.setItem(data);
            }.bind(this);
        }

        if (this.dataRetriever.onErrorRetrieved == null) {

            this.dataRetriever.onErrorRetrieved = this.getDataRetrieverErrorHandler();
        }
    },

    setUpDataUpdater: function() {

        this.dataUpdater.onError = this.getDataRetrieverErrorHandler();

        if (this.dataUpdater.onDeleteItemSuccess == null) {

            this.dataUpdater.onDeleteItemSuccess = function () {

                this.viewer.hide();
                this.itemList.reload();
            }.bind(this);
        }

        if (this.dataUpdater.onDeleteItemError == null) {

            this.dataUpdater.onDeleteItemError = this.getDataRetrieverErrorHandler();
        }

        this.dataUpdater.onUpdateItemSuccess = function () {

            this.editor.hide();
            this.itemList.reload();
        }.bind(this);

        this.dataUpdater.onCreateItemSuccess = function () {

            this.itemList.reload();

//            this.viewer.setTenantId(this.tenantTree.getSelectedTenant());
//            this.viewer.show();
        }.bind(this);
    },

    setUpItemSearch: function() {
        var managerInstance = this;

        this.searchItemBtn.observe('click', function() {

            this.loadItems(0);

        }.bindAsEventListener(this));

        if (this.defaultSearchName && !this.defaultSearchName.blank()) {
            
            this.searchNameInput.setValue(this.defaultSearchName);
        }
        this.searchNameInput.onclear = function () {

            this.loadItems(0);

        }.bind(this);

        this.searchNameInput.getInput().observe('keyup', function(e) {

            if (enterKeyHit(e)) {

                this.loadItems(0);
            }
        }.bindAsEventListener(this));

        this.tenantTree.onTenantSelect = function() {

            managerInstance.loadItems(0);
        }.bind(this);

    },

    setUpItemList: function() {
        this.itemList.getList().multiple = false;
        this.itemList.setSelectedClassName('listItemSelected listItem');
        this.itemList.setOptionClassName('list_default listItem');

        var managerInstance = this;

        var updateItemList = function(firstResult, selected) {

            this.loadItems(firstResult);
        }

        this.itemList.onreload = updateItemList.bind(this);

        this.itemList.onnext = updateItemList.bind(this);

        this.itemList.onprev = updateItemList.bind(this);

        this.itemList.onclick = function () {

            var selectedValues = this.itemList.getSelectedValues();

            if (selectedValues.length > 0) {

                if (selectedValues[0] && !selectedValues[0].blank()) {

                    this.loadItemDetails(selectedValues[0]);
                } else {

                    this.itemList.getList().deselectAll();
                }
            }
        }.bind(this);
    },

    setUpViewer: function() {

        this.viewer.onedit = function (item) {

            this.editItem(item);
        }.bind(this);

        this.viewer.ondelete = function (item) {

            return this.deleteItem(item);
        }.bind(this);

        this.viewer.onbeforeshow = function () {

            this.nothingSelected.hide();

            if (this.editor.isEdit()) {

                this.editor.cancelEdit();
                return false;
            }

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

    setUpEditor: function() {
        this.editor.oncancel = function () {
            this.itemList.onclick();
        }.bind(this);

        this.editor.onbeforeshow = function () {

            this.viewer.hide();
            return true;
        }.bind(this);
    },

    setUpCreator: function() {

        this.addItemBtn.onclick = function () {

            var click = function() {
                var tenantId = this.tenantTree.getSelectedTenant();
                if (tenantId == BaseUserAndRoleManager.State.organizations) {

                    tenantId = null;
                }
                this.creator.setTenantId(tenantId);

                this.creator.show();
            }.bind(this);

            if (this.editor.isEdit()) {
                this.editor.discardEdit(click, null);
            } else {
                click();
            }

        }.bind(this);
    },

    setUpTooltip: function() {
        $('customTooltipTemplate').style.zIndex = 102;
    },

    loadItems: function(firstResult) {
        var loadItems = function() {
            this.viewer.hide();
            this.nothingSelected.show();

            var itemName = this.searchNameInput.getValue();
            var tenantId = this.tenantTree.getSelectedTenant();

//            var img = (itemName.blank()) ? BaseUserAndRoleManager.emptyImg : BaseUserAndRoleManager.clearSearchImg;
//            this.searchNameInput.setClearImage(img);

            this.dataRetriever.getItems(tenantId, itemName, firstResult);
        }.bind(this);

        if (this.editor.isEdit()) {
            this.editor.discardEdit(loadItems, null);
        } else {
            loadItems();
        }
    },

    loadItemDetails: function(itemName) {
        var loadItemDetails = function() {
            this.dataRetriever.getItemDetails(itemName);
        }.bind(this);

        var cancelLoadItemDetails = function() {
            this.itemList.getList().deselectAll();
        }.bind(this);

        if (this.editor.isEdit()) {
            this.editor.discardEdit(loadItemDetails, cancelLoadItemDetails);
        } else {
            loadItemDetails();
        }
    },

    editItem : function (item) {

        this.editor.setItem(item);
        this.editor.setTenantId(this.tenantTree.getSelectedTenant());
        this.editor.show();
    },

    deleteItem: function(item) {

        if (!item) {
            return;
        }

        this.dataUpdater.deleteItem(item);

        return true;
    },

    selectPreviousItem: function() {

        if (this.selectedItem) {

            var model = this.itemList.getModel();
            var index = model.getValueIndex(this.selectedItem);

            if (index > -1) {

                this.itemList.getList().selectOption(index);
            } else {

                this.selectedItem = null;    
            }
        }
    },

    resize : function () {
        var managerTable = $(this.managerTableId);
        managerTable.hide();

        var h = $(this.managerBodyId).clientHeight - ((isIE()) ? 75 : 70);

        if (h < this.minHeigth) {
            h = this.minHeigth;
        }
        var elements = [$(this.tenantTreeId), $(this.itemList.id), $(this.nothingSelected.id), $(this.viewer.id), $(this.editor.id)];
        var heights = [h, h, h, (isIE()) ? h : h + 2, (isIE()) ? h : h + 2];

        for (var i = 0; i < elements.length; i ++) {
            if (elements[i]) {

                elements[i].style.height = heights[i] + 'px';
            }
        }

        managerTable.show();
        this.itemList.resize();

        this.viewer.resize();
        this.editor.resize();

        this.searchNameInput.resize();
    },

    getBaseErrorHandler : function() {
        return function (ajaxAgent) {

            var sessionTimeout = ajaxAgent.getResponseHeader("LoginRequested");
            if (sessionTimeout) {
                var newloc = '.';
                document.location = newloc;
                return true;
            }

            var isErrorPage = ajaxAgent.getResponseHeader("JasperServerError");
            if (isErrorPage) {

                var msgBox = new MsgBox("", "Unknown error.");
                msgBox.show();

                return true;
            }

            return false;
        }
    },

    getDataRetrieverErrorHandler : function() {
        return function (error) {

            var msgBox = new MsgBox("", error.message);
            msgBox.show();
        }
    }


});

BaseUserAndRoleManager.clearSearchImg = 'images/clearValue.gif';
BaseUserAndRoleManager.emptyImg = 'images/pixel.gif';
BaseUserAndRoleManager.currentUser = "";
BaseUserAndRoleManager.currentUserRoles = [];

BaseUserAndRoleManager.State = {
    organizations : 'organizations',
    flowExecutionKey : '',
    tenantId : null
};

BaseUserAndRoleManager.Configuration = {
    userNameSeparator : "|",
    userDefaultRole : "ROLE_USER",
    userNameNotSupportedSymbols : "[\|]",
    roleNameNotSupportedSymbols : "[\|]",
    superuserRole : "ROLE_SUPERUSER",
    adminRole : "ROLE_ADMINISTRATOR"
}

BaseUserAndRoleManager.isCurrentUserSuperuser = function () {
    var isSuperuser = false;

    var superuserRole = (JS.isProVersion())
            ? BaseUserAndRoleManager.Configuration.superuserRole
            : BaseUserAndRoleManager.Configuration.adminRole;
    
    var roles = BaseUserAndRoleManager.currentUserRoles;

    roles.each(function(role) {
        isSuperuser = (role.roleName == superuserRole && !role.tenantId);

        if (isSuperuser) {
            throw $break;
        }
    });

    return isSuperuser;
}

var ItemViewer = Class.create({
    initialize : function (id, messageSource) {

        this.id = id;
        this.messageSource = messageSource;
        this.tenantPathMap = {};
        this.tenantId = null;

        this.viewer = $(this.id);
        this.toolbar = $(this.id + 'Toolbar');
        this.contentContainer = $(this.id + 'ContentContainer');

        this.toolbarBtnCss = ['toolbarBtn', 'toolbarBtn toolbarBtnOver', 'toolbarBtn toolbarBtnDowm', 'toolbarBtn toolbarBtnDisabled'];

        this.editItemBtn = new InputButton('editItemBtn', this.toolbarBtnCss[0], this.toolbarBtnCss[1],
                this.toolbarBtnCss[2], this.toolbarBtnCss[3]);

        this.deleteItemBtn = new InputButton('deleteItemBtn', this.toolbarBtnCss[0], this.toolbarBtnCss[1],
                this.toolbarBtnCss[2], this.toolbarBtnCss[3]);

        this.setUpActions();
    },

    setUpActions : function () {
        this.editItemBtn.onclick = function () {

            this.onedit(this.item);
        }.bind(this);

        this.deleteItemBtn.onclick = function () {
            var confirmDelete = this.getConfirmDelete();

            confirmDelete.onok = function () {

                return this.ondelete(this.item);
            }.bind(this);

            confirmDelete.show();
        }.bind(this);
    },

    getConfirmDelete : function () { /* Do Nothing*/ },

    setItem : function(item) {
        this.item = item;

        this.refresh();
    },

    refresh : function() { /* Do Nothing*/ },

    show : function() {

        var show = this.onbeforeshow();
        if (show) {

//            this.viewer.style.display = 'block';
            this.viewer.show();
            this.refresh();
            this.resize();
        }
    },

    hide : function() {

        this.viewer.hide();
    },

    isItemViewed : function(item) { /* Do Nothing*/ },

    _createLink : function(container, text) {

        var a = document.createElement('a');
        a.id = text;
        a.href = '#null';
        a.innerHTML = text;

//        Element.extend(a);
        if (container) {
            
            container.appendChild(a);
        }

        var link = new LinkButton(a.id, 'editorLink', 'editorLinkHover', 'editorLinkDisabled');
        
        return link;
    },

    setTenantPathMap : function (tenantPathMap) {

        this.tenantPathMap = tenantPathMap;
    },

    setTenantId : function (tenantId) {
        this.tenantId = tenantId;
    },

    resize : function() {
        var bordersHeight = isIE() ? 2 : 3;
        var contentHeight = parseInt(this.viewer.style.height) - $(this.toolbar.id).getHeight() - bordersHeight;
        this.contentContainer.style.height = contentHeight + "px";
    },
    
    onbeforeshow : function() { /* Do Nothing*/ },

    onedit : function(item) { /* Do Nothing*/ },

    ondelete : function(item) { /* Do Nothing*/ }
});

var ItemEditor = Class.create({
    initialize : function (id, messageSource, cancelConfirm) {

        this.id = id;
        this.messageSource = messageSource;
        this.tenantPathMap = {};

        this.cancelConfirm = cancelConfirm;

        this.originalItem = null;
        this.item = null;
        this.tenantId = null;

        this.edit = false;

        this.editor = $(this.id);
        this.toolbar = $(this.id + 'Toolbar');
        this.contentContainer = $(this.id + 'ContentContainer');

        this.validationImg = '<img class="validatorDot" src="images/invalidField.gif"/>';
        this.validationStack = new ValidationStack();

        this.linkButtonCss = ['editorLink', 'editorLinkHover', 'editorLinkDisabled'];
        this.toolbarBtnCss = ['toolbarBtn', 'toolbarBtn toolbarBtnOver', 'toolbarBtn toolbarBtnDowm', 'toolbarBtn toolbarBtnDisabled'];

        this.saveItemBtn = new InputButton('saveItemBtn', this.toolbarBtnCss[0], this.toolbarBtnCss[1],
                this.toolbarBtnCss[2], this.toolbarBtnCss[3]);
        this.cancelBtn = new InputButton('cancelEditBtn', this.toolbarBtnCss[0], this.toolbarBtnCss[1],
                this.toolbarBtnCss[2], this.toolbarBtnCss[3]);

        this.cancelBtn.onclick = function () {
            this.discardEdit();
        }.bind(this);

        this.saveItemBtn.onclick = function () {

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

    discardEdit : function(cancelSubmitted, cancelDiscarded) {

        var onOk = function () {
            this.cancelEdit(cancelSubmitted);
            return true;
         }.bind(this);

        var onCancel = function () {
            if (cancelDiscarded) {
                cancelDiscarded();
            }
            return true;                        
         }.bind(this);

         if (this.isItemChanged()) {

             this.cancelConfirm.onok = onOk;
             this.cancelConfirm.oncancel = onCancel;
             this.cancelConfirm.show();

             return false;
         } else {
             return onOk();
         }
    },

    show : function() {

        var show = this.onbeforeshow();
        if (show) {

            this.edit = true;

            this.editor.show();
            this.resize();
        }

    },

    hide : function() {
        this.originalItem = null;
        this.item = null;

        this.edit = false;

        this.editor.hide();
    },

    setItem : function(item) {
        this.item = item;

        this.resetValidationState();
        this.refresh();
    },

    getItem : function() {

        return this.item;
    },

    setTenantId : function (tenantId) {
        this.tenantId = tenantId;
    },

    setTenantPathMap : function (tenantPathMap) {

        this.tenantPathMap = tenantPathMap;
    },

    resetValidationState : function () { /* Do Nothing*/ },

    refresh : function () { /* Do Nothing*/ },

    isItemChanged : function () {
        return false;
    },

    isEdit : function(user) {

        return this.edit;
    },

    isRequiredFieldsEmpty : function () {
        return false;
    },

    allowSave : function () {
        var editorInstance = this;

        function enableSave () {

            editorInstance.saveItemBtn.setDisabled(false);
        }

        setTimeout(enableSave, 500);
    },

    cancelEdit : function(cancelSubmitted) {
        this.hide();
        this.oncancel();
        if (cancelSubmitted) {
            cancelSubmitted();
        }
    },

    saveChanges : function () {

        this.onsave(this.originalItem, this.getItem());
    },

    resize : function() {
        var bordersHeight = isIE() ? 2 : 3;
        var contentHeight = parseInt(this.editor.style.height) - $(this.toolbar.id).getHeight() - bordersHeight;
        this.contentContainer.style.height = contentHeight + "px";
    },

    onbeforeshow : function() { /* Do Nothing*/ },

    onsave : function(originalItem, newItem) { /* Do Nothing*/ },

    oncancel : function() { /* Do Nothing*/ }
    
});

var ItemCreator = Class.create(ModalDialog, {
    initialize : function (id, messageSource) {

        this.id = id;
        this.messageSource = messageSource;

        this.dialogDiv = $(this.id);

        this.submitBtnId = this.id + 'SubmitBtn';
        this.cancelBtnId = this.id + 'CancelBtn';
        this.validationImg = '<img class="validatorDot" src="images/invalidField.gif"/>';

        this.submitBtn = $(this.submitBtnId);
        this.cancelBtnId = $(this.cancelBtnId);

        this.buttons = {};

        this.defaultButtonId = this.submitBtnId;
        this.escButtonId = this.cancelBtnId;

        this.tenantId = null;
        this.validationStack = new ValidationStack();

        this.submintClicked = false;

        this._setUpValidationStack();
        this._setUpDialogButtons();
    },

    _setUpValidationStack : function () {
        this.validationStack.onsuccess = function () {

            if (this.submintClicked) {

                this.onsubmit(this.getItem());
                this.hide();
            } else {

                this.submitBtn.disabled = this.isRequiredFieldsEmpty();
            }
        }.bind(this)

        this.validationStack.onunsuccess = function () {

            this.submitBtn.disabled = true;
        }.bind(this)
    },

    _setUpDialogButtons : function () {

        var buttons = {};

        buttons[this.submitBtnId] = new ModalDialog.Button(this.submitBtnId, function (e) {

            this.submintClicked = true;

            var validationStackState = this.validationStack.getState();
            if (validationStackState == ControlValidator.State.SUCCESS) {

                this.onsubmit(this.getItem());
                return true;
            } else if (validationStackState == ControlValidator.State.UNSUCCESS) {

                this.submitBtn.disabled = true;
                return false;
            } else {

                return false;
            }

        }.bind(this));

        buttons[this.cancelBtnId] = new ModalDialog.Button(this.cancelBtnId, function (e) {
            this.submintClicked = false;

            this.oncancel();
            return true;
        }.bind(this));

        this.setButtons(buttons);
    },

    isRequiredFieldsEmpty : function () {
        return false;
    },

    setTenantId : function (tenantId) {
        this.tenantId = tenantId;
    },

    getItem : function () { /* Do Nothing */ },

    submit : function (item) {

    },

    onsubmit : function (item) { /* Do Nothing */ },

    oncancel : function () { /* Do Nothing */ },

    refreshDialogState: function(creatorInstance) {
        creatorInstance.submintClicked = false;
        creatorInstance.submitBtn.disabled = creatorInstance.isRequiredFieldsEmpty();


        var rdsWrapper = function() {
            creatorInstance.refreshDialogState(creatorInstance);
        };
        setTimeout(rdsWrapper, 500);
    }
});

var ItemExistValidator  = Class.create(ControlValidator, {

    initialize : function ($super, id, controlToValidate, event, errorMessage, text, dataRetriever) {

        $super(id, controlToValidate, event, errorMessage, text);

        this.tenantId = null;
        this.originalValue = "";
        this.dataRetriever = dataRetriever;
    },

    setTenantId : function (tenantId) {
        this.tenantId = tenantId;
    },

    setOriginalValue : function (originalValue) {
        this.originalValue = originalValue;
    },

    evaluateIsValid : function($super) {

        if (this.originalValue != this.getValue(this.controlToValidate)) {

            $super();
        } else {

            this.setState(ControlValidator.State.SUCCESS);
            this.onsuccess();
            return true;
        }
    },

    evaluateIsValid : function() {

        var value = this.getValue(this.controlToValidate);
        if (!value.blank() && (this.originalValue != value)) {

            this.setState(ControlValidator.State.IN_PROGRESS);

            this.dataRetriever.onIsItemExistSuccess = function (data) {

                if (data.isExist) {

                    this.setState(ControlValidator.State.UNSUCCESS);
                    this.highlight();
                    this.onunsuccess();
                    return false;
                } else {

                    this.setState(ControlValidator.State.SUCCESS);
                    this.onsuccess();
                    return true;
                }
            }.bind(this);

            this.dataRetriever.isItemExist(value, this.tenantId);
        } else {

            this.setState(ControlValidator.State.SUCCESS);
            this.onsuccess();
            return true;
        }
    }

});

var Assigner = Class.create(ModalDialog, {

    initialize : function (id, dataRetriever, dataUpdater, messageSource) {

        this.id = id;
        this.dialogDiv = $(this.id);

        this.messageSource = messageSource;
        this.item = null;
        this.tenantId = null;
        this.tenantPathMap = {};

        this.doneBtnId = 'assignerDone';
        this.revertBtnId = 'assignerRevert';
        this.buttons = {};

        this.defaultButtonId = this.doneBtnId;
        this.escButtonId = this.revertBtnId;

        this.assignedTo = $('assignerAssignedTo');

        this.dataRetriever = dataRetriever;
        this.dataUpdater = dataUpdater;

        this.assignedListId = "assignerAssignedItems";
        this.availableListId = "assignerAvailableItems";

        this.assignedList = new SearchListBox(this.assignedListId, null, this.messageSource.getMessage('assignerDefaultSearchText'), 100);
        this.availableList = new SearchListBox(this.availableListId, null, this.messageSource.getMessage('assignerDefaultSearchText'), 100);

        var rightCss = 'right';
        var leftCss = 'left';
        var stateCss = ['up', 'over', 'down', 'disabled'];
        var addBtnCss = [];
        var removeBtnCss = [];

        stateCss.each(function (state) {
            addBtnCss.push('swapButton' + ' ' + rightCss + ' ' + (rightCss + state));
            removeBtnCss.push('swapButton' + ' ' + leftCss + ' ' + (leftCss + state));
        });

        this.addBtn = new DivButton('assignerAddBtn', addBtnCss[0], addBtnCss[1], addBtnCss[2], addBtnCss[3]);
        this.removeBtn = new DivButton('assignerRemoveBtn', removeBtnCss[0], removeBtnCss[1], removeBtnCss[2], removeBtnCss[3]);

        this._setUpDialogButtons();
        this._setUpLists();
//        this._setUpUserDataRetriever();
//        this._setUpRolesSearsh();
        this._setUpAddRemoveButtons();

        this.addBtn.setDisabled(true);
        this.removeBtn.setDisabled(true);

    },

    _setUpDialogButtons : function () {

        var buttons = {};

        buttons[this.doneBtnId] = new ModalDialog.Button(this.doneBtnId, function (e) {

            this.done();
            return true;
        }.bind(this));

        buttons[this.revertBtnId] = new ModalDialog.Button(this.revertBtnId, function (e) {

            this.onrevert();
            return true;
        }.bind(this));

        this.setButtons(buttons);
    },

    _setUpLists : function () {

        disableSelection($(this.assignedListId));
        disableSelection($(this.availableListId));

        var listCss = 'new_tabletextfieldorlist';
        this.assignedList.setListStyle(listCss);
        this.availableList.setListStyle(listCss);

        var inputCss = ' searchInput searchListBoxInput';
        this.assignedList.setInputStyle(listCss + inputCss);
        this.availableList.setInputStyle(listCss + inputCss);


        var itemCss = 'listItemSelected listItem';
        this.assignedList.getList().setSelectedClassName(itemCss);
        this.assignedList.getList().setOptionClassName(itemCss);

        this.availableList.getList().setSelectedClassName(itemCss);
        this.availableList.getList().setOptionClassName(itemCss);

        this.assignedList.getList().onclick = function () {

            var selectedValues = this.assignedList.getList().getSelectedValues();
            var isItemsSelected = selectedValues.length > 0;

            if (isItemsSelected && (selectedValues[0] == undefined)) {

                this.assignedList.getList().deselectAll();
                isItemsSelected = false;
            }

            this.removeBtn.setDisabled(!isItemsSelected);
        }.bind(this);

        this.availableList.getList().onclick = function () {

            var selectedValues = this.availableList.getList().getSelectedValues();
            var isItemsSelected = selectedValues.length > 0;

            if (isItemsSelected && (selectedValues[0] == undefined)) {

                this.availableList.getList().deselectAll();
                isItemsSelected = false;
            }

            this.addBtn.setDisabled(!isItemsSelected);
        }.bind(this);
    },

    _setUpAddRemoveButtons : function () {

        var doRemove = function() {

            var selectedValues = this.assignedList.getList().getSelectedValues();

            if (selectedValues.length > 0) {

                this.remove(selectedValues);
            }

            this.addBtn.setDisabled(true);
            this.removeBtn.setDisabled(true);
        }.bind(this);

        var doAdd = function() {

            var selectedValues = this.availableList.getList().getSelectedValues();

            if (selectedValues.length > 0) {

                this.add(selectedValues);
            }

            this.addBtn.setDisabled(true);
            this.removeBtn.setDisabled(true);
        }.bind(this);

        this.removeBtn.onclick = doRemove;
        this.assignedList.getList().ondblclick = doRemove;

        this.addBtn.onclick = doAdd;
        this.availableList.getList().ondblclick = doAdd;

    },

    show : function($super) {
        $super();

        this.assignedList.resize();
        this.availableList.resize();

        this.assignedList.loadItems("", 0);        
        this.availableList.loadItems("", 0);
    },

    getSelectedItems : function(list) {
        var items = [];

        var selected = list.getSelected();
        var listModel = list.getModel();

        selected.each(function(index) {
            var item = listModel.getItemAt(index);

            if (item) {

                items.push(item);
            }
        });

        return items;
    },

    setAssignedTo : function (value) {

        this.assignedTo.value = value;
        this.assignedTo.title = value;
    },

    setItem : function (item) {

        this.item = item;
    },

    setTenantId : function (tenantId) {

        this.tenantId = tenantId;
    },

    ondone : function (roles) {
        /*Do Nothing*/
    },

    onrevert : function () {
        /*Do Nothing*/
    },

    sortRoles : function (roles) {


        roles.sort(function (r1, r2) {
            var n1 = r1.roleName;
            var n2 = r2.roleName;

            return (n1 == n2) ? 0 : ((n1 < n2) ? -1 : 1);
        });

    },

    add : function (itemsNames) {
        return true;
    },

    remove : function (itemsNames) {
        return true;
    },

    done : function() {

        this.ondone();
    },

    setTenantPathMap : function (tenantPathMap) {

        this.tenantPathMap = tenantPathMap;
    }

});

var SearchListBox = Class.create({
    initialize : function(id, dataRetriever, defaultText) {

        this.id = id;
        this.preffix = 'SearchListBox';
        this.defaultText = defaultText;

        this._defSearchPanelId = this.preffix + 'SearchPanel';
        this._defInputId = this.preffix + 'Input';
        this._defBtnId = this.preffix + 'Btn';
        this._defListId = this.preffix + 'List';

        this.searchPanelId = this.id + this._defSearchPanelId;
        this.inputId = this.id + this._defInputId;
        this.btnId = this.id + this._defBtnId;
        this.listId = this.id + this._defListId;

        this.sInput = null;
        this.sBtn = null;
        this.list = null;

        this.container = $(this.id);

        if (this.container) {

            this.container.innerHTML = SearchListBox.HTML_TEMPLATE;
            $(this._defSearchPanelId).id = this.searchPanelId;
            $(this._defInputId).id = this.inputId;
            $(this._defBtnId).id = this.btnId;
            $(this._defListId).id = this.listId;
        }

        this.searchPanel =  $(this.searchPanelId);
        this.searchInput = new SearchTextBox(this.inputId, this.defaultText);
        this.searchBtn = $(this.btnId);
        this.itemList = new PaginatedListBox(this.listId, null, 100);

        this.dataRetriever = dataRetriever;

        this.setUpSearch();
        this.setUpList();
        this.resize();
    },

    setUpSearch: function() {

        this.searchBtn.observe('click', function() {

            this.loadItems(this.searchInput.getValue(), 0);

        }.bindAsEventListener(this));

        this.searchInput.onclear = function () {

            this.loadItems("", 0);

        }.bind(this);

        this.searchInput.getInput().observe('keyup', function(e) {

            if (enterKeyHit(e)) {

                this.loadItems(this.searchInput.getValue(), 0);
            }
        }.bindAsEventListener(this));
    },

    setUpList: function() {
        this.itemList.setSelectedClassName('listItemSelected listItem');
        this.itemList.setOptionClassName('list_default listItem');

        var updateItemList = function(firstResult, selected) {

            this.loadItems(this.searchInput.getValue(), firstResult);
        }

        this.itemList.onreload = updateItemList.bind(this);

        this.itemList.onnext = updateItemList.bind(this);

        this.itemList.onprev = updateItemList.bind(this);

        this.itemList.onclick = function () {

            var selectedValues = this.itemList.getSelectedValues();

            if (selectedValues.length > 0) {

                if (selectedValues[0] && !selectedValues[0].blank()) {

                    this.onItemClick();
                } else {

                    this.itemList.getList().deselectAll();
                }
            }
        }.bind(this);
    },

    getList : function() {

        return this.itemList.getList();
    },

    setInputStyle : function(className) {

        $(this.inputId).className = className;
    },

    setBtnStyle : function() {
    },

    setListStyle : function(className) {

        $(this.listId).className = className;
    },

    resize : function() {
        this.searchInput.resize();
        
        var cH = parseInt(this.container.style.height);
        cH = cH ? cH : $(this.container.id).getHeight();  
        var sH = this.searchPanel.style.display == "block" ? parseInt(this.searchPanel.style.height) : 0;  
        var lH = (cH - sH);

        $(this.listId).style.height = (lH > 190 ? lH : 190) + 'px';
        this.itemList.resize();
    },

    getListModel : function () {

        return this.itemList.getModel();
    },

    setListModel : function (model) {

        this.itemList.setModel(model);

        var maxResults = model.getMaxResult();
        var totalCount = model.getTotalResult();

        var filterWord = this.searchInput.getValue();

        if (filterWord.blank()) {
            this.searchPanel.style.display = ((totalCount <= maxResults) || (totalCount == 0)) ? 'none' : 'block';
        }
        this.resize();
    },

    getSearchWord : function (searchWord, firstResult) {

        return this.searchInput.getValue();
    },

    setSearchWord : function (searchWord) {

        return this.searchInput.setValue(searchWord);
    },

    clearSearch : function () {

        return this.searchInput.clear();
    },

    reload : function () {

        this.itemList.reload();
    },

    loadItems : function (searchWord, firstResult) {},

    onItemClick : function () {}
});

SearchListBox.HTML_TEMPLATE =
        '<div id="SearchListBoxSearchPanel" style="overflow-x:hidden;height:30px">' +
            '<div id="SearchListBoxInput" style="float:left;" class=""></div>' +
            '<input id="SearchListBoxBtn" style="float:right;position:relative;" class="dialogButton searchBtn" type="button" value="Search" />' +
            '<div style="clear:both;"></div>' +
        '</div>' +
        '<div id="SearchListBoxList" class="panelContent panelBorder"></div>';

var HoverBehavior = Class.create({
    initialize: function() {

        $A(arguments).each(function(arg) {

            $$(arg).each(function(tag) {

                Event.observe(tag, 'mouseover', function() {
                    if (tag.className.indexOf("listItemSelected")<0)
                    Element.addClassName(tag, 'listItemHover');
                });

                Event.observe(tag, 'mouseout', function() {

                    Element.removeClassName(tag, 'listItemHover');
                });
            });
        });
    }
});
