(function( $ ) {

function blankLoginForm() {
    return {
        errors: [],
        data: {
            username: '',
            rememberMe: true
        }
    };
}

$.widget( "ui.loginManager", {  

    options: {
        // Selectors
        loginPanel: '#login',
        loginTemplate: '#login-template',
        signIn: '.site-utils .login',
        signUpPanel: '#create-account',
        signUp: '#login .create-account'
    },

    _init: function() {
        var self = this;

        this.signUpPanelIsActive = false;

        $.template('login', $(this.options.loginTemplate));

        self.deferredLogin = null;
        self.deferredLogout = null;
        self.deferredSignUp = null;

        $( self.options.loginPanel ).dialog({
            modal: true,
            autoOpen: false,
            close: function (event, ui ) {
                if (!self.signUpPanelIsActive) {
                    self._rejectLogin();
                }
            }
        });

        self._renderForm(blankLoginForm());

        $(self.options.signUpPanel).createAccount({
            signedUp: function (event, profile) {
                self.signUpPanelIsActive = false;
                self._resolveLogin(profile);
                self._userLoggedIn(profile);
            }
        });
    },

    _rejectLogin: function () {
        if (this.deferredLogin) {
            this.deferredLogin.reject({});
            this.deferredLogin = null;
        }
        this._closeLoginPanel();
    },

    _rejectLogout: function () {
        if (this.deferredLogout) {
            this.deferredLogout.reject({});
            this.deferredLogout = null;
        }
    },

    _resolveLogin: function (profile) {
        if (this.deferredLogin) {
            this.deferredLogin.resolve(profile);
            this.deferredLogin = null;
        }

        this._closeLoginPanel();
    },

    _resolveLogout: function () {
        if (this.deferredLogout) {
            this.deferredLogout.resolve({});
            this.deferredLogout = null;
        }
    },

    _renderForm: function (loginForm) {
        $.tmpl('login', loginForm).appendTo($(this.options.loginPanel).empty());

        this._bindLoginFormSubmitHandler();
        this._bindSignUpClickHandler();
    },

    _bindLoginFormSubmitHandler: function () {
        var self = this;

        function loginFormSuccess(result) {
            if (result.errors && result.errors.length) {
                self._renderForm(result);
            }
            else {
                self._resolveLogin(result);
            }
        }

        function loginFormFailure(xhr) {
            var result = $.parseJSON(xhr.responseText);
            if (result) {
                self._renderForm(result);
            }
            else {
                self._rejectLogin();
            }
        }

        $(self.options.loginPanel).find('form').submit(function () {
            var $form = $(this),
                toUrl = $form.attr('action'),
                serializedFormData = $form.serialize();

            $.post(toUrl, serializedFormData).then(loginFormSuccess, loginFormFailure);

            return false;
        }); 
    },

    _bindSignUpClickHandler: function () {
        var self = this;

        $( self.options.signUp ).click( function () {
            self.createAccount();
            return false;
        });
    },

    _unbindSignUpClickHandler: function () {
        $(self.options.signUp).unbind('click');
    },

    destroy: function() {
        $.Widget.prototype.destroy.apply(this, arguments);

        if( this.deferredLogin ) {
            this.deferredLogin.reject( {} );
            this.deferredLogin = null;
        }

        if( this.deferredLogout ) {
            this.deferredLogout.reject( {} );
            this.deferredLogout = null;
        }

        $(this.options.signUpPanel).createAccount('destroy');

        $( this.options.loginPanel )
            .dialog( 'destroy' )
            .find( 'form' ).unbind( 'submit' );

        this._unbindSignUpClickHandler();
    },

    _userLoggedIn: function (profile) {
        this.element.trigger('loggedIn.loginManager', [profile]);
    },

    _userLoggedOut: function () {
        this.element.trigger('loggedOut.loginManager');
    },

    login: function () {
        var self = this;

        if( !this.deferredLogin ) {
            this.deferredLogin = $.Deferred();
            this.deferredLogin.then(function (profile) {
                self._userLoggedIn(profile);
            });

            this._openLoginPanel();
        }

        return this.deferredLogin.promise();
    },

    logout: function () {
        var self = this;

        if( !this.deferredLogout ) {
            this.deferredLogout = $.post('/auth/signOut');
            this.deferredLogout.then(
                function () {
                    self._userLoggedOut();
                    self.deferredLogout = null;
                },
                function () {
                    self.deferredLogout = null;
                }
            );
        }

        return this.deferredLogout.promise();
    },

    createAccount: function () {
        var self = this;

        self.signUpPanelIsActive = true;
        self._closeLoginPanel();
        $(self.options.signUpPanel)
            .createAccount('signUp')
            .fail(function () {
                self.signUpPanelIsActive = false;
                self._rejectLogin();
            });
    },

    _openLoginPanel: function () {
        $( this.options.loginPanel ).dialog( 'open' );
    },

    _closeLoginPanel: function () {
        if ($(this.options.loginPanel).dialog('isOpen')) {
            $( this.options.loginPanel ).dialog( 'close' );
        }
    }
}); 

})( jQuery );

