var RoleEditor = Class.create(ItemEditor, {
    initialize : function ($super, messageSource, dataRetriever, dataUpdater) {

        var cancelConfirm = new ConfirmMsgBox(
                "roleEditorCancelConfirmation",
                messageSource.getMessage('cancelItemEditHeader'),
                messageSource.getMessage('cancelItemEditMessage'),
                messageSource.getMessage('cancelItemEditOk'),
                messageSource.getMessage('cancelItemEditCancel'));

        $super('roleEditor', messageSource, cancelConfirm);
        this.dataRetriever = dataRetriever;
        this.dataUpdater = dataUpdater;

        this.roleChanged = false;
        this.saveClicked = false;

        this.roleNameInputId = 'roleEditorRoleNameInput';
        this.filteredRoleName = new FilteredTextBox(this.roleNameInputId,
                new RegExp(BaseUserAndRoleManager.Configuration.userNameNotSupportedSymbols, "g"));
        this.roleName = this.filteredRoleName.getElement();;

        this.usersCount = $('roleEditorUsersCount');

        this.editUsersBtn = new LinkButton('editUsersBtn', this.linkButtonCss[0], this.linkButtonCss[1],
                this.linkButtonCss[2]);

        this.userAssigner = new UserAssigner(dataRetriever, this.dataUpdater, messageSource);
        this.userAssigner.setTenantPathMap(this.tenantPathMap);

        this.roleNameValidator = new ItemExistValidator(
                'roleEditorRoleNameValidator',
                this.roleNameInputId,
                'blur',
                this.messageSource.getMessage('roleNameIsAlreadyInUse'),
                this.validationImg,
                dataRetriever);

        this.validationSummary = new ValidationSummary('roleEditorValidationSummary');
        this.validationSummary.registrValidator(this.roleNameValidator);

        this.validationStack = new ValidationStack();
        this.validationStack.addValidator(this.roleNameValidator);

        this.slb = new SearchListBox('roleEditorUsers', null, messageSource.getMessage('defaultUserSearchText'));
        this.slb.setInputStyle('new_tabletextfieldorlist searchInput searchListBoxInput');
        this.slb.setListStyle('new_tabletextfieldorlist ');

        this._setUpValidation();
        this.setUpUserList();
        this.setUpDataRetriever();
        this.setUpEditUsers();
    },

    setUpUserList : function() {

        this.slb.loadItems = function (searchWord, firstResult) {

            if (this.originalItem && this.originalItem.roleName) {

                this.dataRetriever.getRoleUsers(this.originalItem, searchWord, this.tenantId, firstResult);
            }
        }.bind(this);
    },

    usersDataRetrieved: function (data) {

        if (this.slb.getSearchWord().blank()) {
            this.usersCount.innerHTML = data.totalResult;
        }

        var model =
                new UserListModel(data.users, data.firstResult, data.maxResult, data.totalResult, this.tenantPathMap);

        model.getNoItemsMessage = function () {

            return this.messageSource.getMessage('noUsersFound');

        }.bind(this);

        this.slb.setListModel(model);

        new HoverBehavior('#roleEditorUsers td.list_default', '#roleEditorUsers td.listItemDisabled');
    },
    
    setUpDataRetriever : function() {

        this.dataRetriever.addUsersRetrievedListener(this); 
    },

    _setUpValidation : function() {

//        this.roleNameValidator.onsuccess = function () {
//
//            var disable = this.isRequiredFieldsEmpty();
//            if (disable) {
//
//                this.saveItemBtn.setDisabled(disable);
//            } else {
//
//                this.allowSave();
//            }
//        }.bind(this);

//        this.roleNameValidator.onunsuccess = function () {
//
//            this.saveItemBtn.setDisabled(true);
//        }.bind(this);

        this.validationStack.onsuccess = function() {

            if (this.saveClicked) {

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

                var disable = this.isRequiredFieldsEmpty();
                if (disable) {

                    this.saveItemBtn.setDisabled(disable);
                } else {

                    this.allowSave();
                }
            }

            this.saveClicked = false;
        }.bind(this);

        this.validationStack.onunsuccess = function () {
            this.saveClicked = false;
            
            this.saveItemBtn.setDisabled(true);
        }.bind(this);
    },

    setUpEditUsers : function() {
        this.editUsersBtn.onclick = function () {
            this.saveClicked = false;

            this.userAssigner.setItem(this.originalItem);
            this.userAssigner.setAssignedTo(RoleUtil.getRoleNameWithoutTenant(this.getItem().roleName));
            this.userAssigner.setTenantId(this.tenantId);
            this.userAssigner.show();

        }.bind(this);

        this.userAssigner.onrevert = function() {

            this.dataUpdater.revertUsersChanges(this.item);
        }.bind(this);

        this.userAssigner.ondone = function() {

            this.slb.loadItems("", 0);
        }.bind(this);

        this.userAssigner.onchange = function() {

            this.roleChanged = true;
        }.bind(this);
    },

    setItem : function($super, role) {

        $super(RoleUtil.clone(role));
        this.saveClicked = false;
        this.originalItem = RoleUtil.clone(role);

        this.roleNameValidator.setOriginalValue(this.originalItem.roleName);
        this.roleNameValidator.setTenantId(this.originalItem.tenantId);
    },

    setUsersCount : function(count) {

        this.usersCount.innerHTML = count;
    },

    setSearchUserName : function(userName) {

        this.slb.setSearchWord(userName);
    },

    setUsersModel : function(model) {

        this.slb.setListModel(model);
    },

    getItem : function() {

        var role = this.item;
        if (role) {

            role.roleName = this.roleName.value;
        }

        return this.item;
    },

    refresh : function() {

        var role = this.item;
        if (role) {

            this.roleName.value = RoleUtil.getRoleNameWithoutTenant(role.roleName);

            this.saveItemBtn.setDisabled(false);

            if (!role.tenantId) {

                this.setRoleNameDisabled(!BaseUserAndRoleManager.isCurrentUserSuperuser());
                this.editUsersBtn.setDisabled(!BaseUserAndRoleManager.isCurrentUserSuperuser());
            } else {

                this.setRoleNameDisabled(false);
                this.editUsersBtn.setDisabled(false);
            }

            this.slb.clearSearch();
//            this.resize();
        } else {

            this.roleName.value = '';
        }
    },

    setRoleNameDisabled : function(disabled) {
        this.roleName.readOnly = disabled;

        if (disabled) {
            if (!this.roleName.hasClassName('disabledInput')) {
                this.roleName.addClassName('disabledInput');
            }
        } else {
            if (this.roleName.hasClassName('disabledInput')) {
                this.roleName.removeClassName('disabledInput');
            }
        }
    },

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

        var padding = isIE() ? 53 : 50;
        var h = ($(this.contentContainer.id).getHeight() - $('roleEditorRoleDetails').getHeight() - padding);
        $('roleEditorUsers').style.height = ((h > 0) ? h : 0) + 'px';

        this.slb.resize();
    },

    isRequiredFieldsEmpty : function () {
        return this.roleName.value.blank();
    },

    resetValidationState : function() {
        this.roleNameValidator.setState(ControlValidator.State.UNKNOWN);        
    },

    _setRolesList : function(element, roles) {

        var editorInstance = this;

        element.innerHTML = '';

        if (roles) {

            var i = 0;
            roles.each(function (role) {


                var r = document.createTextNode(role.roleName);
                element.appendChild(r)

                if (i < roles.length - 1) {
                    element.appendChild(document.createTextNode(", "));
                }

                i ++;
            });
        }
    },

    isItemChanged : function () {
        return !RoleUtil.equals(this.originalItem, this.getItem()) || this.roleChanged ;
    },

    show : function($super) {

        this.dataUpdater.onInitEditSuccess = function() {

            $super();
            this.slb.loadItems("", 0);
        }.bind(this);

        this.dataUpdater.initEdit(this.item);
        this.roleChanged = false;
    },

    cancelEdit : function(onSuccess) {
        this.saveClicked = false;

        this.dataUpdater.onCancelEditSuccess = function () {

            this.hide();
            this.oncancel();
            if (onSuccess) {
                onSuccess();
            }
        }.bind(this);

        this.dataUpdater.cancelEdit(this.originalItem);
    },

    setTenantPathMap : function ($super, tenantPathMap) {

        $super(tenantPathMap);
        this.userAssigner.setTenantPathMap(tenantPathMap);
    },

    saveChanges : function () {
        this.saveClicked = true;

        if (this.validationStack.getState() != ControlValidator.State.IN_PROGRESS) {

            this.validationStack.evaluateIsValid();
        }
    }
});


var UserAssigner = Class.create(Assigner, {

    initialize : function ($super, dataRetriever, dataUpdater, messageSource) {

        $super('userAssigner', dataRetriever, dataUpdater, messageSource);
        this.roleName = null;

        this.availableList.loadItems = function (searchWord, firstResult) {

            if (this.item && this.item.roleName) {

                this.dataRetriever.getAvailableItems(this.item, searchWord, this.tenantId, firstResult);
            }
        }.bind(this);

        this.dataRetriever.onAvailableItemsRetrieved = function (data) {

            this.availableList.setListModel(this.getUserListModel(data));
            new HoverBehavior('#assignerAvailableItems td.list_default', '#assignerAvailableItems td.listItemDisabled');
        }.bind(this);

        this.assignedList.loadItems = function (searchWord, firstResult) {

            if (this.item && this.item.roleName) {

                this.dataRetriever.getAssignedItems(this.item, searchWord, this.tenantId, firstResult);
            }
        }.bind(this);

        this.dataRetriever.onAssignedItemsRetrieved = function (data) {

            this.assignedList.setListModel(this.getUserListModel(data));
            new HoverBehavior('#assignerAssignedItems td.list_default', '#assignerAssignedItems td.listItemDisabled');
        }.bind(this);

        this.dataUpdater.onChangeItemsSuccess = function (data) {

            this.availableList.setListModel(this.getUserListModel(data.availableUserList));
            this.assignedList.setListModel(this.getUserListModel(data.assignedUserList));
        }.bind(this);
    },

    add : function (itemsNames) {

        this.dataUpdater.changeItems(
                this.item, this.tenantId,
                this.getListParams(this.availableList), this.getListParams(this.assignedList),
                itemsNames, []);

        this.onchange();
    },

    remove : function (itemsNames) {

        this.dataUpdater.changeItems(
                this.item, this.tenantId,
                this.getListParams(this.availableList), this.getListParams(this.assignedList),
                [], itemsNames);

        this.onchange();
    },

    getListParams : function(list) {

        return {
            searchWord : list.getSearchWord(),
            firstResult : list.getList().getModel().getFirstResult()
        }
    },

    getUserListModel : function (data) {

        var model =
                new UserListModel(data.users, data.firstResult, data.maxResult, data.totalResult, this.tenantPathMap);

        model.getNoItemsMessage = function () {

            return this.messageSource.getMessage('noUsersFound');

        }.bind(this);

        return model;
    },

    show : function($super){

        this.dataUpdater.onInitChangeUsersSuccess = function() {

            $super();
        }

        this.dataUpdater.initChangeUsers(this.item);
    },

    onchange : function () {

    }
});
