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

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

        $super('userEditor', messageSource, cancelConfirm);

        this.content = $('userEditorContent');
        this.externalContent = $('externalUserEditorContent');


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

        this.userName = $('userNameInput');
        this.fullName = $('fullNameInput');
        this.email = $('emailInput');
        this.roles = $('rolesInEditor');
        this.attributes = $('userEditorAttributes');
        this.enabled = $('userEnabledInput');
        this.password = $('passwordInput');
        this.confirmPassword = $('confirmPasswordInput');

        this.externalUserUserName = $('externalUserUserName');
        this.externalUserFullName = $('externalUserFullName');
        this.externalUserEmail = $('externalUserEmail');
        this.externalUserExternalRoles = $('externalUserExternalRoles');
        this.externalUserRoles = $('externalUserRoles');
        this.externalAttributes = $('externalAttributes');
        this.externalUserEnabled = $('externalUserEnabledInput');

        this.rolesEditor = new RoleAssigner(dataRetriever, dataUpdater, messageSource);

        this.emailValidator = null;
        this.passwordRequiredValidator = null;
        this.confirmPasswordRequiredValidator = null;
        this.passwordCompareValidator = null;

        this.validationChain = null;
        this.validationSummary = null;

        this._setUpGeneral();
        this._setUpValidation();
    },

    _setUpGeneral : function(user) {

        this.editRulesBtn.onclick = function () {

            var user = this.item;
            var userCopy = UserUtil.clone(user);

            var un = UserUtil.getUserNameWithTenant(userCopy.userName, userCopy.tenantId);

            this.rolesEditor.setItem(userCopy);
            this.rolesEditor.setAssignedTo(userCopy.userName);
            this.rolesEditor.setTenantId(this.tenantId);

            this.rolesEditor.show();
        }.bind(this);
        
        this.exteranlEditRulesBtn.onclick = function () {

            var user = this.item;
            var userCopy = UserUtil.clone(user);
            var un = UserUtil.getUserNameWithTenant(userCopy.userName, userCopy.tenantId);

            this.rolesEditor.setItem(userCopy);
            this.rolesEditor.setAssignedTo(userCopy.userName);
            this.rolesEditor.setTenantId(this.tenantId);

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

    _setUpForInternalUser : function(user) {

        this.rolesEditor.ondone = function (roles) {

            this.item.roles = roles;
            this._setRolesList(this.roles, roles);
        }.bind(this);
    },

    _setUpForExternalUser : function(user) {

        this.rolesEditor.ondone = function (roles) {

//            var user = this.item;
//            var isExternal = this.user.external;
//            var externalRoles = UserUtil.getExternalRoles(user);

//            user.roles = externalRoles.concat(roles);
//            this._setRolesList(this.externalUserRoles, roles);
            this.item.roles = roles;
            this._setRolesList(this.externalUserExternalRoles, UserUtil.getExternalRoles(this.item));
            this._setRolesList(this.externalUserRoles, UserUtil.getAssignedRoles(this.item));
        }.bind(this);
    },

    _setUpValidation : function(user) {
        var editorInstance = this;

        var rfcRegex = "^[^\\~\\`\\(\\)\\[\\]\\{\\}\\:\"\\;\'\/\\?\\<\\>\\+\\=\\\\|\\!\\@\\#\\$\\%\\^\\&\\*]+@(\\w+\\.)(\\w+)(\\.\\w+)*";

        this.emailValidator = new RegularExpressionValidator(
                'emailValidator',
                new RegExp(rfcRegex),
                'emailInput',
                'blur',
                this.messageSource.getMessage('invalidEmail'),
                this.validationImg);

        this.passwordCompareValidator = new CompareValidator(
                'confirmPasswordValidator',
                CompareValidator.Operator.EQUALS,
                'confirmPasswordInput',
                'blur',
                'passwordInput',
                this.messageSource.getMessage('invalidConfirmPassword'),
                this.validationImg, false);

        this.validationSummary = new ValidationSummary('userEditorValidationSummary');
        this.validationSummary.registrValidator(this.emailValidator);
        this.validationSummary.registrValidator(this.passwordCompareValidator);

        var onsuccessListener = function () {

            var disable = editorInstance.validationStack.hasUnuccess() || editorInstance.isRequiredFieldsEmpty();
            if (disable) {

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

                editorInstance.allowSave();
            }
        }

        var onunsuccessListener = function () {

            editorInstance.saveItemBtn.setDisabled(true);
        }

        this.emailValidator.onsuccess = onsuccessListener;
        this.emailValidator.onunsuccess = onunsuccessListener;
        this.passwordCompareValidator.onsuccess = onsuccessListener;
        this.passwordCompareValidator.onunsuccess = onunsuccessListener;

        this.validationStack = new ValidationStack();
        this.validationStack.addValidator(this.emailValidator);
        this.validationStack.addValidator(this.passwordCompareValidator);
    },

    setItem : function($super, user) {

        $super(UserUtil.clone(user));
        this.originalItem = UserUtil.clone(user);
    },

    getItem : function() {
        var user = this.item;
        if (user) {
            
            if (!user.external) {
                user.fullName = this.fullName.value;
                user.email = this.email.value;
                user.enabled = this.enabled.checked;
                user.password = this.password.value;
                user.confirmPassword = this.confirmPassword.value;
            }
        }

        return this.item;
    },

    refresh : function() {

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

            if (user.external) {

                this.content.hide();
                this.externalContent.style.display = 'block';

                this.externalUserUserName.innerHTML = UserUtil.getUserNameWithoutTenant(user.userName);
                this.externalUserFullName.innerHTML = user.fullName;
                this.externalUserEmail.innerHTML = user.email;

                this._setRolesList(this.externalUserExternalRoles, UserUtil.getExternalRoles(user));
                this._setRolesList(this.externalUserRoles, UserUtil.getAssignedRoles(user));

                this._setUpForExternalUser();

                this._createAttributes(this.externalAttributes);

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

                this.externalContent.hide();
                this.content.style.display = 'block';

                this.userName.value = UserUtil.getUserNameWithoutTenant(user.userName);
                this.fullName.value = user.fullName;
                this.email.value = user.email;

                if (user.password) {

                    this.password.value = user.password;
                    this.confirmPassword.value = user.password;
                } else {

                    this.password.value = '';
                    this.confirmPassword.value = '';
                }

                this.enabled.checked = (user.enabled);

                this._setRolesList(this.roles, user.roles);

                this._setUpForInternalUser();

                this._createAttributes(this.attributes);

                this.saveItemBtn.setDisabled(this.isRequiredFieldsEmpty());
            }
        } else {
            this.userName.value = '';
            this.fullName.value = '';
            this.email.value = '';

            this.roles.innerHTML = '';
            this.attributes.innerHTML = '';

            this.externalUserUserName.innerHTML = '';
            this.externalUserFullName.innerHTML = '';
            this.externalUserEmail.innerHTML = '';

            this.externalUserEnabled.checked = false;

            this.externalUserExternalRoles.innerHTML = '';
            this.externalUserRoles.innerHTML = '';

            this.externalAttributes.innerHTML = '';
        }
    },

    resetValidationState : function() {
        this.emailValidator.setState(ControlValidator.State.UNKNOWN);
        this.passwordCompareValidator.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 ++;
            });
        }
    },

    _createAttributes : function(element) {
        var attributesHtml = UserUtil.attributesToString(this.item.attributes);

        element.innerHTML = (attributesHtml.blank()) ? '&nbsp;' : attributesHtml;
    },

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

    saveChanges : function () {

        var user = this.item;
        if (user.external) {

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

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

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

var RoleAssigner = Class.create(Assigner, {

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

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

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

            if (this.item) {
                var roles = [];

                this.item.roles.each(function(role) {

                    roles.push(RoleUtil.getRoleNameWithTenant(role.roleName, role.tenantId));
                });

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

        this.dataRetriever.onAvailableItemsRetrieved = function (data) {

            this.availableList.setListModel(this.getRoleListModel(data));

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

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

            if (this.item) {

                this.assignedList.setListModel(this.getRoleListModel(this.getAssignedRolesData()));
            }

            this.addHover();
        }.bind(this);
//
//        this.dataRetriever.onAssignedItemsRetrieved = function (data) {
//
//            this.assignedList.setListModel(this.getUserListModel(data));
//        }.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) {
        var availableRoles = this.availableList.getList().getModel().roles;

        var roles = [];
        itemsNames.each(function (itemName) {

            availableRoles.each(function (role) {

                var name = RoleUtil.getRoleNameWithTenant(role.roleName, role.tenantId);
                if (name == itemName) {

                    roles.push(role);
                }
            });
        });
    
        this.item.roles = this.item.roles.concat(roles);

        this.assignedList.setListModel(this.getRoleListModel(this.getAssignedRolesData()));
        this.addHover();

        this.availableList.reload();
    },

    remove : function (itemsNames) {

        var selected = this.assignedList.getList().getSelected();

        for (var i = selected.length - 1; i > -1; i --) {
            var index = selected[i];

            this.item.roles.splice(index, 1);
        }

        this.assignedList.setListModel(this.getRoleListModel(this.getAssignedRolesData()));
        this.addHover();

        this.availableList.reload();
    },

    getListParams : function(list) {

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

    getAssignedRolesData : function () {

        var roles = UserUtil.getAssignedRoles(this.item);
        return {
            roles : roles,
            firstResult : 0,
            maxResult : roles.length,
            totalResult : roles.length
        };
    },

    getRoleListModel : function (data) {

        var model =
                new RoleListModel(data.roles, data.firstResult, data.maxResult, data.totalResult, this.tenantPathMap);

        model.getNoItemsMessage = function () {

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

        }.bind(this);

        return model;
    },

    done : function() {

        this.ondone(this.item.roles);
    },

    addHover : function() {

        new HoverBehavior('#assignerAssignedItems td.list_default', '#assignerAssignedItems td.listItemDisabled');
    }

});
