// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
define(
    [ 'fs/presenter/users/UsersPresenter',
      'fs/view/users/UsersViewUtil',
      'hp/view/FormStateView',
      'hp/core/Localizer',
      'hp/core/UrlFragment',
      'hp/model/Session',
      'hp/core/Notifications',
      'jquery',
      'hp/view/ModalDialogView',
      'hp/lib/jquery.hpToggle',
      'jquery',
      'lib/jquery.validate'],

function(presenter, UsersViewUtil, FormStateView, Localizer, urlFragment, session, Notifications) { "use strict";

      var UsersEditView = (function() {

          var FORM = '#fs-user-edit-form',
              EDIT = '#fs-user-edit',
              CANCEL = "#fs-user-edit-cancel",
              ERROR = '#hp-error-text',
              NAME = '#fs-user-edit-loginname',
              FULLNAME = '#fs-user-edit-fullname',
              CURRENT_PASSWD = '#fs-usersettings-currentpasswd',
              NEW_PASSWD = '#fs-user-edit-newpasswd',
              NEW_PASSWD_HELP = '#fs-user-initpasswd-help',
              CONFIRM_PASSWD = '#fs-user-edit-confirmpasswd',
              EMAIL = '#fs-user-edit-email',
              OFFICE_PHONE = '#fs-user-edit-officephone',
              MOBILE_PHONE = '#fs-user-edit-mobilephone',
              ROLE_VALIDATOR = '#fs-user-edit-role-validator',
              ROLES_LIST = '#fs-user-edit-roles-list',
              ROLES = ROLES_LIST + ' input[type="checkbox"]',
              HEADER = '#fs-user-edit-header',
              INIT_PASSWD_OPTIONAL_HINT = '#fs-user-initpasswd-optional',
              CONFIRM_PASSWD_OPTIONAL = '#fs-user-confirmpasswd-optional',
              ROLE_LIST ='#fs-edit-user-roles',
              ROLES_LIST_SELF = '#fs-usersettings-roles-list',
              ROLE_SWITCH = '#fs-edit-user-role-switch',
              ROLE_SELECT_NAME = 'fs-edit-user-role-name',
              ROLE_SWITCH_RADIO = 'input[name=fs-edit-user-role-name]:checked',
              ROLE_SPECIALIZED_CHECKBOXES = "input[type='checkbox'][id^='fs-user-edit-role']",
              SPECIALIZED_VALUE = 'specialized',
              FULL_VALUE = 'full',
              READONLY_VALUE = 'readonly',
              FULL_BUTTONSET = '#fs-edit-user-role-name-full',
              READONLY_BUTTONSET = '#fs-edit-user-role-name-readonly',
              SPECIALIZED_BUTTONSET ='#fs-edit-user-role-name-specialized',
              CURRENT_PWD_DIV= '#fs-currentpasswd-id',
              NEWORINITIALPWD_LABEL='#fs-user-edit-neworinitialpwd',
              FULLNAME_OPTIONAL = '#fs-user-edit-fullname-optional',
              EMAIL_OPTIONAL = '#fs-user-edit-email-optional',
              OFFICEPHONE_OPTIONAL = '#fs-user-edit-officephone-optional',
              MOBILEPHONE_OPTIONAL = '#fs-user-edit-mobilephone-optional',
              INFRASTRUCTURE_ADMINISTRATOR = 'Infrastructure administrator',
              READ_ONLY = 'Read only';



        /**
         * Constructor
         */
        function UsersEditView() {

            var validator;
            // prevent double click
            var isSubmitted;
            var formStateView = new FormStateView();
            var firstRoleTemplate = null, roleTemplate = null;
            var canModifyAnyUser = false;
            var isSpecialized;
            var userLoggedIn = '' ;
            var allRadio = false;
            var oneRole= false;
            var taskName ;
            var numberOfClicks = 0;
            var isSelf = false;
            var COUNT = '#hp-form-changes-control .hp-count';
            var changeCount = 0;

            /**
             * @private
             */
            function checkRoles() {
              $(ROLE_VALIDATOR).val("");
                var result = false;
                if(isSelf){
                  $(ROLE_VALIDATOR).val("set");
                  result = true;
                }else{
                    if (isSpecialized ) {
                        $(ROLES).each(function(index, role) {
                            if ($(role).is(':checked')) {
                              $(ROLE_VALIDATOR).val("set");
                                result = true;
                            }
                        });
                    }else {
                      $(ROLE_VALIDATOR).val("set");
                        result = true;
                    }
                }
                return result;
            }

            /**
             * @private To check the checkbox or uncheck the checkbox of a role
             * under 'Specialized' radio button if only 1 specialized role is
             * present in list.
             *
             */
            function autoCheckSpecializedRole(boolValue){
                var theRoles = $(ROLES);
                if (theRoles.length === 1){
                    theRoles.prop('checked',boolValue).trigger('change');
                }
            }

            /**
             * @private
             */
            function onSpecializedUserClick() {
                isSpecialized = true;
                $(ROLE_VALIDATOR).val("");
                $(SPECIALIZED_BUTTONSET).attr("checked", true);
                $(ROLES_LIST).show();
                autoCheckSpecializedRole(true);
            }

            /**
             * @private
             */
            function onFullOrReadonlyUserClick() {
                isSpecialized = false;
                $(ROLE_VALIDATOR).val("set");
                autoCheckSpecializedRole(false);
                $(ROLES_LIST).hide();
            }

            /**
             * set the roles retrieved from database
             * @param retrievedRoles
             */
            function userRoleChangedSelf(retrievedRoles) {
                var retrievedRolesList = (retrievedRoles.hasOwnProperty('members') ?
                        retrievedRoles.members : retrievedRoles);
                var rolesList = $(ROLES_LIST_SELF);
                rolesList.empty();
                $.each(retrievedRolesList, function(index, role) {
                    var roleValue = role.roleName ? role.roleName : 'noname';
                    var roleDisplay = UsersViewUtil.getLocalizedRoleDisplay(roleValue);
                    var label = $('<label/>');
                    label.text(roleDisplay);
                    rolesList.append(label);
                    if (index !== retrievedRolesList.length - 1){
                        $('<br/>').appendTo(rolesList);
                    }
                });
            }


            /**
             * @private Function that retrieves the roles currently displayed user
             * in master pane and details page, and updates the values in edit page html.
             */
            function userRoleChanged(theRolesList) {
                var roleList = presenter.getRetrievedRoles()? presenter.getRetrievedRoles() : theRolesList;
                if (isSelf){
                    userRoleChangedSelf(roleList);
                }else{
                    var roles = (roleList.hasOwnProperty('members') ? roleList.members : roleList);

                    $.each(roles, function(index, theRole) {
                        var userRole = theRole.roleName ? theRole.roleName.replace(/_/, ' ') : 'noname';
                        if (allRadio || oneRole){
                            $('#'+userRole.replace(' ','-')).attr("checked", true); //the id is the orole name as in DB - spaces repalced by hyphen
                        }else if (userRole === INFRASTRUCTURE_ADMINISTRATOR){
                            onFullOrReadonlyUserClick();
                            $(FULL_BUTTONSET).attr("checked", true);
                        }else if (userRole === READ_ONLY){
                            onFullOrReadonlyUserClick();
                            $(READONLY_BUTTONSET).attr("checked", true);
                        }
                        else{
                            onSpecializedUserClick();
                            $(SPECIALIZED_BUTTONSET).attr("checked", true);
                            $(ROLES).each(function(index, role) {
                                if ($(role).val().toLowerCase() === userRole.toLowerCase()) {
                                    $(role).attr("checked", true).trigger('change');
                                }
                            });
                        }
                    });
                }
            }

            /**
             * @private To construct the roles section in the page,
             * based on what roles are available in the appliance
             */
            function updateRoles() {
                if(isSelf)
                {
                    $(ROLE_SWITCH).hide();
                    $(ROLE_LIST).hide();
                    $(ROLE_VALIDATOR).val("set");
                    $(ROLES_LIST_SELF).show();
                }
                else{
                    var roles = presenter.getRoles(),
                        rolesList = $(ROLES_LIST);

                    $(rolesList).empty();

                    $(ROLE_SWITCH).show();
                    $(ROLE_LIST).show();
                    $(ROLES_LIST_SELF).hide();

                    if (roles.length == 1){
                        $(ROLE_VALIDATOR).val("set");
                        oneRole = true;
                    }

                    if (allRadio || oneRole){
                        isSpecialized = true;
                        $(ROLE_SWITCH).empty();
                    }
                    var counter = 0;//counter as in else case case we need to know the right order

                    $.each(roles, function(index, role) {//iterating through all available roles
                        var roleValue =  role.roleName ? role.roleName.replace(/_/, ' ') : 'noname';
                        var roleDisplay = UsersViewUtil.getLocalizedRoleDisplay(roleValue);

                        if(allRadio || oneRole){
                            var radio = $("<input type='radio'>");
                            var id = roleValue.replace(' ','-');//id is the role as in DB, space replaced by hyphen
                            radio.attr("name", ROLE_SELECT_NAME)
                                 .attr("id", id)
                                 .attr("value", roleValue);
                            var label = $('<label/>');
                            label.attr("for", id);
                            label.text(roleDisplay);
                            $(ROLE_SWITCH).append(radio);
                            $(ROLE_SWITCH).append(label);
                            if (index !== roles.length - 1){
                               $(ROLE_SWITCH).append($('<br/>'));
                            }
                        }else {
                              //because full and read only are in the toggle
                              if (role.roleName !== 'No_Privileges' &&
                                  role.roleName !== INFRASTRUCTURE_ADMINISTRATOR &&
                                  role.roleName !== READ_ONLY) {

                                  var item = (counter === 0) ? firstRoleTemplate.clone() : roleTemplate.clone();
                                  var idChkbox = 'fs-user-edit-role-' + counter;
                                  var labelChkbox = roleDisplay;
                                  item.attr('id', '');
                                  item.show();
                                  $('input[type="checkbox"]', item).attr('id', idChkbox)
                                      .val(role.roleName)
                                      .attr('name', role.roleName);
                                  $('label:eq(1)', item).text(labelChkbox)
                                      .attr('for', idChkbox);
                                  rolesList.append(item);
                                  counter = counter + 1;
                              }
                          }
                      });
                      if (allRadio || oneRole){
                          $(ROLE_LIST).empty(); //dont show the list of checkboxes
                      }else{
                          $(ROLE_SPECIALIZED_CHECKBOXES).on('change',function(){
                              if(checkRoles()){
                                  $(ROLE_VALIDATOR).val("set");
                                  $(ROLE_VALIDATOR).next().hide();//the auto generated error label
                              }else{
                                  $(ROLE_VALIDATOR).val("");
                              }
                          });
                          autoCheckSpecializedRole(true);
                      }
                  }
                  if(presenter.getRetrievedRoles()){//set the roles if available in resource
                      userRoleChanged();
                  }
                  formStateView.reset();
            }

            /**
             * @private
             */
            function reset() {
                $(NAME).val("");
                $(FULLNAME).val("");
                $(NEW_PASSWD).val("");
                $(CONFIRM_PASSWD).val("");
                if (isSelf){
                    $(CURRENT_PASSWD).val("");
                }
                $(EMAIL).val("");
                $(OFFICE_PHONE).val("");
                $(MOBILE_PHONE).val("");
                $(ROLES).prop("checked", false);
                $(ROLE_VALIDATOR).val("");
                validator.resetForm();
                formStateView.reset();
                numberOfClicks = 0;
                isSubmitted = false;
                isSelf = false;
                updateRoles();
                changeCount = 0;
            }

            /**
             * Get all other users logged in
             */

            function otherUserLoggedIn(){
                var list = presenter.getOtherUsersLoggedInList();
                var count = list.length;
                var reterivedUser = presenter.getRetrievedUser().userName;
                var status = false;

                for ( var i = 0; i < count; i++) {
                    if(list[i] == reterivedUser){
                        status =true;
                        userLoggedIn = reterivedUser;
                    }
                }
                return status;
            }

            function onUserModifiedSuccess(user) {
                var username, alertMsg;
                username = user.userName;
                alertMsg = Localizer.getString('fs.users.edit.success', [ username ]);
                formStateView.setMessage({summary:alertMsg, status:'ok', changing : false});
                reset();
                //window.location = '#/user/show';
                presenter.getUser(user.userName);
                //because after notification message is shown, the show page
                //does not refresh to show new data

                if(presenter.getOtherUsersLoggedInList().length > 0 && otherUserLoggedIn()){
                    alertMsg += Localizer.getString('fs.users.common.loggedIn');
                    userLoggedIn = '';
                }

                var userEditComplete = {
                    summary : Localizer.getString('fs.users.edit.update'),
                    sourceName : username,
                    uri : taskName,
                    sourceUri : "/rest/users/"+username,
                    changing : false,
                    status : "ok",
                    details : alertMsg
                };
                Notifications.add(userEditComplete, true);
                $(CANCEL).trigger('click');

            }

            /**
             * @private
             */
            function onUserModifiedError(errorMessage) {
                var modifyMsg = Localizer.getString('fs.users.edit.error', [$(NAME).val()]);
                var errorMsg = Localizer.formatRestError(modifyMsg,
                        errorMessage);
                formStateView.setMessage({summary: modifyMsg, status: 'error',
                    details: errorMsg});
                var userEditError = {
                    summary : Localizer.getString('fs.users.edit.update'),
                    sourceName : $(NAME).val(),
                    sourceUri : "/rest/users/"+ $(NAME).val(),
                    uri : taskName,
                    changing : false,
                    status : "error",
                    details : errorMsg
                };
                Notifications.add(userEditError, true);
                isSubmitted = false;
            }

            /**
             * @private
             */
            function onEditUserClick() {
                if ($(FORM).valid() && isSubmitted == false) {
                    numberOfClicks = numberOfClicks + 1 ;
                    isSubmitted = true;
                    var alertMsg = Localizer.getString('fs.users.edit.editMsg', [ $(NAME).val() ]);
                    formStateView.setMessage({summary:alertMsg, status:'info', changing : true});
                    if(numberOfClicks == 1){
                        taskName = $(NAME).val() +'-editUserTask-' + (new Date()).getTime();
                    }
                    var userEditProgress = {
                        summary : Localizer.getString('fs.users.edit.update'),
                        sourceName : $(NAME).val(),
                        uri : taskName,
                        changing : true,
                        status : "info",
                        details : alertMsg
                    };
                    Notifications.add(userEditProgress, false);
                    var roles = [];
                    var replace = false;
                    var caller ;
                    var currentPassword = null;
                    if(isSelf){
                        currentPassword = $(CURRENT_PASSWD).val();
                        caller = "self";
                    }else{
                        //if only one role also we show radio button, no harm
                        if (allRadio || oneRole){
                            roles.push($(ROLE_SWITCH_RADIO).val());
                        }
                        else if(isSpecialized)
                        {
                            $(ROLES).each(function(index, role) {
                                if ($(role).is(':checked')) {
                                    roles.push($(role).val());
                                }
                            });
                        }
                        else if($(ROLE_SWITCH_RADIO).val() === FULL_VALUE){
                            roles.push(INFRASTRUCTURE_ADMINISTRATOR);
                        }else if ($(ROLE_SWITCH_RADIO).val() === READONLY_VALUE){
                            roles.push(READ_ONLY);
                        }

                         replace = presenter.isReplace(roles);
                         caller = "other";
                    }
                    //current password is null
                    presenter.modifyUser($(NAME).val(), $(FULLNAME).val(), currentPassword,
                            $(NEW_PASSWD).val(), roles, $(EMAIL).val(), $(
                            OFFICE_PHONE).val(), $(MOBILE_PHONE).val(), replace, caller);
                }

                return false;

            }
            /**
             * @private
             */
            function userRolesError(errorMessage) {
                var roleMsg = Localizer.getString('fs.users.show.roleserror');
                formStateView.setMessage({summary: roleMsg, status: 'error',
                    errorMessage: errorMessage});
            }

            /**
             * called when selected user in masterpane changes
             * @param user
             */
            function userChanged(userObj) {
                isSpecialized = true;
                presenter.usersLoggedIn();
                var user = presenter.getRetrievedUser()?presenter.getRetrievedUser() : userObj;

                if(user.userName.toLowerCase() === session.getUser().toLowerCase()){
                    isSelf = true;
                    $(CURRENT_PWD_DIV).show();
                    $(NEW_PASSWD).val("");
                    $(CONFIRM_PASSWD).val("");
                    $(NEWORINITIALPWD_LABEL).text(Localizer.getString("fs.users.edit.newpasswd"));
                    $(CONFIRM_PASSWD_OPTIONAL).hide();
                    $(INIT_PASSWD_OPTIONAL_HINT).hide();
                }else{
                    isSelf = false;
                    $(CURRENT_PWD_DIV).hide();
                    $(NEW_PASSWD).val("********");
                    $(CONFIRM_PASSWD).val("********");
                    $(NEWORINITIALPWD_LABEL).text(Localizer.getString("fs.users.add.initialpasswd"));
                    $(INIT_PASSWD_OPTIONAL_HINT).removeAttr("style");//unhiding, not forcing a show()
                    $(CONFIRM_PASSWD_OPTIONAL).show();
                }
                $(HEADER).html(Localizer.getString('fs.users.edit.link')+' '+user.userName);
                $(ERROR).hide();
                $(NAME).val(user.userName);
                $(FULLNAME).val(user.fullName);
                $(NAME).prop("disabled", "true");
                $(EMAIL).val(user.emailAddress);
                $(OFFICE_PHONE).val(user.officePhone);
                $(MOBILE_PHONE).val(user.mobilePhone);
                $(FORM).show();
            }


            /**
             * @private
             * called when own profile must be edited- event is caught
            */
            function myUserChangedSuccess(user) {
                userChanged(user);
                updateRoles();
            }

            /**
             * @private
             */
            function myUserChangedError(errorMessage) {
                var userMsg = Localizer.getString('fs.users.show.error');
                formStateView.setMessage({summary: userMsg, status: 'error',
                    errorMessage: errorMessage});
            }

            function getProductConfigSuccess(productConfigs){
                UsersViewUtil.setProductConfigs(productConfigs);
                UsersViewUtil.checkRequired(FULLNAME_OPTIONAL,EMAIL_OPTIONAL,MOBILEPHONE_OPTIONAL,OFFICEPHONE_OPTIONAL);
                if (UsersViewUtil.getPropertyValue(
                    UsersViewUtil.configs[UsersViewUtil.ROLES_TEMPLATE]) === "exclusive"){
                    allRadio = true;
                }
                updateRoles();
                var passwordArgs = [];
                passwordArgs[0] = function(){return UsersViewUtil.getPropertyValue(
                        UsersViewUtil.configs[UsersViewUtil.PASSWORD_MINLENGTH],
                        UsersViewUtil.MIN_PASSWORD_LENGTH);};
                $(NEW_PASSWD_HELP).text(Localizer.getString(
                    "fs.users.validations.passwordHintDynamic", passwordArgs));
            }

            function getProductConfigError(errorInfo){
                UsersViewUtil.setProductConfigs({});
            }

            function initForm() {

                isSubmitted = false;
                var args=[];
                args[0] = UsersViewUtil.MIN_PASSWORD_LENGTH;
                var validRoleValidation = Localizer.getString('fs.users.validations.roleValidation');
                var validMatchPasswd = Localizer.getString('fs.users.edit.matchpasswd');
                var validPhoneNum = Localizer.getString('fs.users.validations.phonenumValidation');
                var validPassword = Localizer.getString('fs.users.validations.passwordValidation');
                var validFullname = Localizer.getString('fs.users.validations.fullnameValidation');
                var validCurrentPasswd = Localizer.getString('fs.users.validations.matchcurrpasswd');
                var fieldRequired = Localizer.getString('fs.users.validations.fieldRequired');

                validator = $(FORM).validate({
                    rules : {
                        fullname : {
                            required :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.FULLNAME_REQUIRED],false);} ,
                            cicUserEditFullNameCheck : FULLNAME,
                            minlength :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.FULLNAME_MINLENGTH], UsersViewUtil.MIN_NAME_LENGTH);},
                            maxlength : function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.FULLNAME_MAXLENGTH],UsersViewUtil.MAX_NAME_LENGTH);}
                        },
                        email : {
                            required :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.EMAIL_REQUIRED],false);} ,
                            email : EMAIL,
                            maxlength :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.EMAIL_MAXLENGTH],UsersViewUtil.MAX_EMAIL_LENGTH);}
                        },
                        currentpasswd : {
                            cicUserSelfEditCheckPasswdString : CURRENT_PASSWD,
                            cicUserSelfEditCheckCurrPass : CURRENT_PASSWD,
                            maxlength :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.PASSWORD_MAXLENGTH],UsersViewUtil.MAX_PASSWORD_LENGTH);}
                        },
                        newpasswd : {
                            cicUsersEditCheckPasswdString : NEW_PASSWD,
                            cicUsersEditCheckPwdLength : function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.PASSWORD_MINLENGTH],UsersViewUtil.MIN_PASSWORD_LENGTH);},
                            cicUserSettingsEditCheckReqd : NEW_PASSWD,
                            maxlength :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.PASSWORD_MAXLENGTH],UsersViewUtil.MAX_PASSWORD_LENGTH);}
                        },
                        confirmpasswd : {
                            cicUsersEditMatchPasswd : NEW_PASSWD
                        },
                        officephone : {
                            required :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.OFFICE_REQUIRED],false);} ,
                            cicUsersEditOfficePhoneNumCheck : OFFICE_PHONE,
                            maxlength :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.OFFICE_MAXLENGTH],UsersViewUtil.MAX_NUMBER_LENGTH);} ,
                            minlength :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.OFFICE_MINLENGTH],UsersViewUtil.MIN_NUMBER_LENGTH);}
                        },
                        mobilephone : {
                            required :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.MOBILE_REQUIRED],false);} ,
                            cicUsersEditMobilePhoneNumCheck : MOBILE_PHONE,
                            maxlength :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.MOBILE_MAXLENGTH],UsersViewUtil.MAX_NUMBER_LENGTH);} ,
                            minlength :  function(){return UsersViewUtil.getPropertyValue(
                                    UsersViewUtil.configs[UsersViewUtil.MOBILE_MINLENGTH],UsersViewUtil.MIN_NUMBER_LENGTH);}
                        },
                        role_validator : {required : true}

                    },
                    messages : {
                      role_validator : {
                            required : validRoleValidation
                        }

                    }
                });

                $.validator.addMethod("userRoleValidation", function(value, element, param) {
                    return checkRoles();
                }, validRoleValidation);

                //No special characters allowed <>;,"'&\/|+.:
                $.validator.addMethod("cicUserSelfEditCheckPasswdString",
                    function(value, element, param) {
                        var result = true;

                        if(isSelf){
                            var regex =  UsersViewUtil.getPropertyValue(UsersViewUtil.configs[UsersViewUtil.PASSWORD_VALID],"^[^<>;,\"'&\\\\/|+:= ]+$") ;
                            var isValidPwd = new RegExp(regex).test(value);
                            result = (value.length == 0 || isValidPwd);
                            if(!result){
                                $(CONFIRM_PASSWD_OPTIONAL).hide();
                            }
                        }
                        return result;
                    },
                    function (){ return UsersViewUtil.getPropertyValue(
                            UsersViewUtil.configs[UsersViewUtil.PASSWORD_ERRORMSG], validPassword);
                      });

                //check current password
                $.validator.addMethod("cicUserSelfEditCheckCurrPass",
                    function(value, element, param) {
                        var result = true;
                        if (isSelf && value.length == 0 &&
                            ((($(NEW_PASSWD).val() && $(NEW_PASSWD).val().length > 0)) ||
                                ($(CONFIRM_PASSWD).val() && ($(CONFIRM_PASSWD).val().length >0)))){
                            result = false;
                            $(CONFIRM_PASSWD_OPTIONAL).hide();
                        }
                        return result;
                    },
                validCurrentPasswd);

                $.validator.addMethod("cicUserSettingsEditCheckReqd",
                    function(value, element, param) {
                        var result = true;
                        if (isSelf){
                            if (value.length == 0 &&
                                ((($(CURRENT_PASSWD).val() && $(CURRENT_PASSWD).val().length > 0)) &&
                                    ($(CONFIRM_PASSWD).val() && ($(CONFIRM_PASSWD).val().length >0)))){
                                result = false;
                            }
                        }
                        return result;
                    },
                    fieldRequired);

                // check for fullname contain letters ' . - and space
                $.validator.addMethod("cicUserEditFullNameCheck",
                    function(value, element, param) {
                        var regex =  UsersViewUtil.getPropertyValue(UsersViewUtil.configs[UsersViewUtil.FULLNAME_VALID],"^[a-zA-Z0-9 ._'\-]+$");
                        var isValidFullname = new RegExp(regex).test(value);
                        return (isValidFullname || value.length == 0);
                    },
                    function (){ return UsersViewUtil.getPropertyValue(
                            UsersViewUtil.configs[UsersViewUtil.FULLNAME_ERRORMSG], validFullname);
                        }
                );

                jQuery.validator.addMethod("cicUsersEditMatchPasswd", function(value, element, param) {
                    // bind to the blur event of the target in order to revalidate whenever the target field is updated
                    var target = $(param).unbind(".validate-equalTo")
                        .bind("blur.validate-equalTo", function() {
                            $(element).valid();
                        });
                    var result = (value == target.val());
                    return result;
                    },
                validMatchPasswd);

                //function to check length of password. Since it is optional field,
                //user can leave the dummy value there and modify other details.
                //If he removes the dummy characters somehow, it will still not prompt for pwd
                jQuery.validator.addMethod("cicUsersEditCheckPwdLength", function(
                        value, element, param) {
                    args[0] = function(){return UsersViewUtil.getPropertyValue(
                            UsersViewUtil.configs[UsersViewUtil.PASSWORD_MINLENGTH],UsersViewUtil.MIN_PASSWORD_LENGTH);};
                    return ((value.length >= param) || (value.length == 0));
                    },
                    function (){ return Localizer.getString('fs.users.validations.checkLengthDynamic', args);});

             // check for  special characters
                jQuery.validator.addMethod("cicUsersEditMobilePhoneNumCheck", function(value,
                    element, param) {
                    var regex =  UsersViewUtil.getPropertyValue(UsersViewUtil.configs[UsersViewUtil.MOBILE_VALID],"^[^\"'&=<>]+$") ;
                    var isValidPh = new RegExp(regex).test(value);
                    return (value.length == 0 || isValidPh);
                    },
                    function (){ return UsersViewUtil.getPropertyValue(
                            UsersViewUtil.configs[UsersViewUtil.MOBILE_ERRORMSG], validPhoneNum);
                    }
                );

                // check for  special characters
                jQuery.validator.addMethod("cicUsersEditOfficePhoneNumCheck", function(value,
                    element, param) {
                    var regex =  UsersViewUtil.getPropertyValue(UsersViewUtil.configs[UsersViewUtil.OFFICE_VALID],"^[^\"'&=<>]+$") ;
                    var isValidPh = new RegExp(regex).test(value);
                    return (value.length == 0 || isValidPh);
                    },
                    function (){ return UsersViewUtil.getPropertyValue(
                            UsersViewUtil.configs[UsersViewUtil.OFFICE_ERRORMSG], validPhoneNum);
                    }
                );

                jQuery.validator.addMethod("cicUsersEditCheckPasswdString", function(
                        value, element, param) {
                    var regex =  UsersViewUtil.getPropertyValue(UsersViewUtil.configs[UsersViewUtil.PASSWORD_VALID],"^[^<>;,\"'&\\\\/|+:= ]+$") ;
                    var isValidPwd = new RegExp(regex).test(value);
                        if(isSelf){
                            return (value.length == 0 || isValidPwd);
                        }else{
                            return (isValidPwd || value === "********");
                        }
                    },
                    function (){ return UsersViewUtil.getPropertyValue(
                          UsersViewUtil.configs[UsersViewUtil.PASSWORD_ERRORMSG], validPassword);
                    });

            }

            function displayRoles() {
                if ($(ROLE_SWITCH_RADIO).val() === SPECIALIZED_VALUE){
                    onSpecializedUserClick();
                }
                else{
                    onFullOrReadonlyUserClick();
                }
            }

            function registerEvents() {
                //presenter.on("rolesChanged", updateRoles);
                presenter.on("userChangedSuccess", myUserChangedSuccess);
                presenter.on("userChangedError", myUserChangedError);
                presenter.on("userRoleChanged", userRoleChanged);
                presenter.on("userRolesError", userRolesError);
                presenter.on("userModifiedSuccess", onUserModifiedSuccess);
                presenter.on("userModifiedError", onUserModifiedError);
                presenter.on("userSelfModifiedSuccess", onUserModifiedSuccess);
                presenter.on("userSelfModifiedError", onUserModifiedError);
                presenter.on("getProductConfigSuccess", getProductConfigSuccess);
                presenter.on("getProductConfigError", getProductConfigError);
            }

            function removeEvents() {
                //presenter.off("rolesChanged", updateRoles);
                presenter.off("userChangedSuccess", myUserChangedSuccess);
                presenter.off("userChangedError", myUserChangedError);
                presenter.off("userRoleChanged", userRoleChanged);
                presenter.off("userRolesError", userRolesError);
                presenter.off("userModifiedSuccess", onUserModifiedSuccess);
                presenter.off("userModifiedError", onUserModifiedError);
                presenter.off("userSelfModifiedSuccess", onUserModifiedSuccess);
                presenter.off("userSelfModifiedError", onUserModifiedError);
                presenter.off("getProductConfigSuccess", getProductConfigSuccess);
                presenter.off("getProductConfigError", getProductConfigError);
            }

            function onEditUserCancelClick(){
              isSubmitted = true;
            }

            function onChangeOfRole(){
                displayRoles();
                if(checkRoles()){
                    $(ROLE_VALIDATOR).next().hide();//the auto generated error label
                }
             }
            /**
             * @public
             */

            this.init = function() {
                // Remove the template for a role from the DOM (used for
                // cloning later)
                firstRoleTemplate = $('#fs-user-edit-first-role-template').detach();
                roleTemplate = $('#fs-user-edit-role-template').detach();
                initForm();

                formStateView.init({
                    form : FORM,
                    autoTrack : true
                });
                isSpecialized = true;
                $(ROLES_LIST).show();

                //check if session user can perform this action
                canModifyAnyUser = session.canPerformAction("users", "Update");

                $(EDIT).on('click', function(ev) {
                    //check if the user clicks OK without editing the text fields
                    changeCount = $(COUNT).text();
                    if ($.trim(changeCount) == 0){
                        $(CANCEL).trigger('click');
                    }else{
                        onEditUserClick();
                        ev.preventDefault();
                    };
                });

                $(ROLE_SWITCH).buttonset();
                $(ROLES_LIST).show();
                onSpecializedUserClick();

                $(ROLE_SWITCH).change(function() {
                   onChangeOfRole();
                });


                $(CANCEL).on('click', function(ev) {
                    onEditUserCancelClick();
                    formStateView.reset();
                });

                presenter.selectionChange();
                registerEvents();
                presenter.getProductConfig();
            };


            /**
             * @public
             */
            this.resume = function() {
                reset();
                onSpecializedUserClick();
                presenter.selectionChange();
                registerEvents();
                presenter.getProductConfig();
            };

            this.pause = function() {
                removeEvents();
                formStateView.reset();
            };

          }

          return new UsersEditView();
      }());

    return UsersEditView;
});
