jscape.account = jscape.account || {};

/** @class */
jscape.PersonalInfoData = Class.extend(
    /** @lends {jscape.PersonalInfoData.prototype} */
{
    /** @constructor */
    initialize: function(name, username, email, company, phone) {
        this.name = name;
        this.username = username;
        this.email = email;
        this.company = company;
        this.phone = phone;
    }
});
jscape.PersonalInfoData.fromJSON = function(data) {
    return data ? new jscape.PersonalInfoData(data.name, data.username, data.email, data.company, jscape.Phone.fromJSON(data.phone)) : null;
};

/** @class */
jscape.account.PersonalInfoModule = jscape.ApplicationModule.extend(
    /** @lends {jscape.account.PersonalInfoModule.prototype} */
{
    onCreate: function(username) {
        this._super.apply(this, arguments);

        this.controller = new jscape.account.PersonalInfoController(username);
    },

    onStart: function() {
        this.controller.start();
    },

    onResume: function() {
        this.controller.onResume();
    }
});

/** @class */
jscape.account.PersonalInfoController = Class.extend(
    /** @lends {jscape.account.PersonalInfoController.prototype} */
{
    username: null,

    /** @constructor */
    initialize: function(username) {
        this.username = username;

        this.view = new jscape.account.PersonalInfoView();
        this.passwordController = new jscape.account.ChangePasswordController();

        this._initValidators();
    },

    start: function() {
        this.view.show(this);
    },

    onResume: function () {
        this.view.refresh();
    },

    onRefresh: function() {
        return jscape.API.getPersonalInfo(this.username)
                .done($.proxy(function(data) { this._setupView(data); }, this));
    },

    onChangePassword: function () {
        return this.passwordController.start(this.username)
                .done($.proxy(this.onRefresh, this));
    },

    onApply: function () {
        var data = this._createUserData();
        return jscape.API.setPersonalInfo(this.username, data)
                .done($.proxy(function() { this._setupView(data); }, this))
                .done($.proxy(this._fireApplySuccess, this, window.R.string.USER_SUCCESS_UPDATED));
    },

    onDiscard: function () {
        return this.onRefresh();
    },

    _createUserData: function() {
        return new jscape.UserData(this.view.getName(),
                                   this.username,
                                   this.view.getEmail(),
                                   this.view.getCompany(),
                                   this.view.getPhone());
    },

    _setupView: function(data) {
        if (data) {
            this.view.setName(data.name);
            this.view.setUsername(data.username);
            this.view.setEmail(data.email);
            this.view.setCompany(data.company);
            this.view.setPhone(data.phone);
        }
    },

    _initValidators: function() {
        var v = new jscape.Validator();
        v.rule("pi_password_compliance", $.proxy(this._passwordCompliant, this), window.R.string.USER_ERROR_PASSWORD_NON_COMPLIANT);
        v.rule("pi_password_confirm", $.proxy(this._passwordConfirmed, this), window.R.string.USER_ERROR_CONFIRM_PWD);
    },

    _passwordCompliant: function (value, params) {
        var accountName = params && params.length ? params[0] : null;
        var result = jscape.API.testPasswordCompliance(accountName, value);
        if ($.isPlainObject(result)) {
            if (result.valid === false && result.message) {
                new jscape.Validator().ruleMessage("pi_password_compliance", result.message);
            }
            return !!result.valid;
        }
        return true;
    },

    _passwordConfirmed: function (value, params) {
        if (params && params.length) {
            var t = $(params[0]);
            if (t.length) {
                return $.data(t[0], "passwordbox")
                        ? value == t.passwordbox("getValue")
                        : t.val() == value;
            }
        }
        return false;
    },

    _fireApplySuccess: function (message) {
        $(document).triggerHandler("broadcast", [message]);
    }
});

/** @class */
jscape.account.PersonalInfoView = Class.extend(
    /** @lends {jscape.account.PersonalInfoView.prototype} */
{
    /** @constructor */
    initialize: function() {
        this.form = $("form[name=personalinfofields]").form({onChange: $.proxy(this._onChange$Form, this)});

        this.name = $("input[name=name]", this.form).textbox({width: "50%"});
        this.login = $("input[name=login]", this.form).textbox({disabled: true, readonly: true, width: "40%"});
        this.email = $("input[name=email]", this.form).textbox({validType: {any: ["variable", "multi_value['email',',']"]}, invalidMessage: window.R.string.USER_ERROR_BAD_EMAIL, width: "40%"});
        this.company = $("input[name=company]", this.form).textbox({width: "40%"});

        this.phoneCode = $("input[name=phonecode]", this.form).textbox({width: 60, validType: "pattern['^[\\\\d]+$']", invalidMessage: window.R.string.USER_ERROR_BAD_PHONE});
        this.phoneNumber = $("input[name=phonenum]", this.form).textbox({width: 160, validType: "pattern['^[\\\\d- ]+$']", invalidMessage: window.R.string.USER_ERROR_BAD_PHONE});
        this.phoneExtension = $("input[name=phoneext]", this.form).textbox({width: 70, validType: "pattern['^[\\\\d- ]+$']", invalidMessage: window.R.string.USER_ERROR_BAD_PHONE});

        this.applyButton = $("a[role=button][name=apply]", this.form).linkbutton({disabled: true, onClick: $.proxy(this._onClick$ApplyButton, this)});
        this.discardButton = $("a[role=button][name=discard]", this.form).linkbutton({onClick: $.proxy(this._onClick$DiscardButton, this)});
        this.changePasswordButton = $("a[role=button][name=changepwd]", this.form).linkbutton({onClick: $.proxy(this._onClick$ChangePasswordButton, this)});
        if (this.changePasswordButton.linkbutton("options").disabled) {
            this.changePasswordButton.closest(".easyui-tooltip")
                    .tooltip({showDelay: 0, onShow: function () { $(this).tooltip("tip").addClass("tooltip-tip-black"); }});
        }
    },

    show: function(listener) {
        this.listener = listener || jscape.account.PersonalInfoView.LISTENER;
    },

    refresh: function() {
        this.listener.onRefresh();
    },

    getName: function() {
        return this.name.textbox("getValue");
    },

    setName: function(value) {
        this.name.textbox("setValue", value);
    },

    setUsername: function(value) {
        this.login.textbox("setValue", value);
    },

    getEmail: function() {
        return this.email.textbox("getValue");
    },

    setEmail: function(value) {
        this.email.textbox("setValue", value);
    },

    getCompany: function() {
        return this.company.textbox("getValue");
    },

    setCompany: function(value) {
        this.company.textbox("setValue", value);
    },

    getPhone: function() {
        return this.phoneCode.textbox("isValid") && this.phoneNumber.textbox("isValid")
                ? new jscape.Phone(this.phoneCode.textbox("getValue"), this.phoneNumber.textbox("getValue"), this.phoneExtension.textbox("getValue"))
                : null;
    },

    setPhone: function(phone) {
        this.phoneCode.textbox("setValue", phone ? phone.code : "");
        this.phoneNumber.textbox("setValue", phone ? phone.number : "");
        this.phoneExtension.textbox("setValue", phone ? phone.extension : "");
    },

    _onChange$Form: function() {
        this.applyButton.linkbutton(this.form.form("validate") ? "enable" : "disable");
    },

    _onClick$ChangePasswordButton: function() {
        this.changePasswordButton.linkbutton("disable");
        this.listener.onChangePassword()
                .always($.proxy(function () { this.changePasswordButton.linkbutton("enable"); }, this));
    },

    _onClick$ApplyButton: function() {
        this.applyButton.linkbutton("disable");
        this.listener.onApply()
                .always($.proxy(function () { this.applyButton.linkbutton("enable"); }, this));
    },

    _onClick$DiscardButton: function() {
        this.discardButton.linkbutton("disable");
        this.listener.onDiscard()
                .always($.proxy(function () { this.discardButton.linkbutton("enable"); }, this));
    }
});
jscape.account.PersonalInfoView.LISTENER = {
    onChangePassword: $.noop,
    onRefresh: $.noop,
    onApply: $.noop,
    onDiscard: $.noop
};