package Pcore::Ext::Lib::Core::Viewport;

use Pcore -l10n;

sub EXT_controller : Extend('Ext.app.ViewController') : Type('controller') {
    return {
        listen => {
            global => {
                mask           => 'mask',
                unmask         => 'unmask',
                unmatchedRoute => 'onUnmatchedRoute',
                remoteEvent    => 'onRemoteEvent',
                login          => 'onLogin',
                logout         => 'onLogout',
                requestError   => 'onRequestError',
                setLocale      => 'onSetLocale',
            },
        },

        # FASHION THEME
        baseColor   => undef,
        accentColor => undef,
        darkMode    => \0,

        init => func [], <<"JS",
            var me = this;

            me.mask();

            if (!!window.Fashion) {
                var theme = {"dark-mode": me.darkMode ? "true" : "false"};
                if (me.baseColor) theme["base-color-name"] = me.baseColor;
                if (me.accentColor) theme["accent-color-name"] = me.accentColor;

                Fashion.css.setVariables(theme);
            };

            Ext.util.History.hashbang = true;

            // set token and disconnect
            APP.getApplication().api.auth(this.getToken());

            Ext.route.Router.suspend();

            me.doLogin(null, null, function(res) {
                if (res.isSuccess()) {

                    // store session data
                    me.getViewModel().set('session', res.data || {});

                    me.setLocale(res.data.locale, function () {
                        Ext.route.Router.resume();
                    });
                }
                else {
                    me.unmask();

                    Ext.create({
                        xtype: 'dialog',
                        modal: false,
                        html: $l10n->{'Error connecting to the server'} + '<br/>' + $l10n->{'Try again.'},
                        buttons: [{
                            text: 'retry',
                            handler: 'onRetry'
                        }]
                    }).show();
                }
            });

            me.callParent(arguments);
JS

        # MASK
        mask => func [], <<'JS',
            this.getView().setMasked({
                transparent: true,
                html: '<img src="/static/loader4.gif" width="100"/>',
            });
JS

        unmask => func [], <<'JS',
            this.getView().unmask();
JS

        # EVENTS
        onUnmatchedRoute => func ['hash'], <<"JS",
            this.redirectTo('', {replace: true});
JS

        onRequestError => func ['res'], <<"JS",
                Ext.toast("Error: " + res.reason, 3000);
JS

        # TOKEN
        setToken => func [ 'token', 'persistent' ], <<'JS',
            this.removeToken();

            if (persistent) {
                localStorage.token = token;
            }
            else {
                sessionStorage.token = token;
            }
JS

        getToken => func [], <<'JS',
            return sessionStorage.token || localStorage.token;
JS

        removeToken => func [], <<'JS',
            localStorage.removeItem('token');
            sessionStorage.removeItem('token');
JS

        # LOCALE
        onSetLocale => func ['locale'], <<"JS",

            // already using required locale
            if (Ext.L10N.getCurrentLocale() == locale) return;

            // store user locale in profile, if user is authenticated
            if (this.getViewModel().get('session').is_authenticated) this.doUpdateLocale(locale);

            var me = this;

            me.setLocale(locale, function () {
                me.redirectTo(Ext.util.History.getToken(), {force: true});
            });
JS

        setLocale => func [ 'locale', 'cb' ], <<'JS',
            if (locale == Ext.L10N.getCurrentLocale()) {
                cb();
            }
            else {
                var me = this;

                // store locale in local storage
                localStorage.locale = locale;

                this.loadLocale(locale, function () {
                    Ext.L10N.setLocale(locale);

                    // redraw interface
                    me.clearInterface();

                    cb();
                });
            }
JS

        loadLocale => func [ 'locale', 'cb' ], <<'JS',
            if (Ext.L10N.hasLocale(locale)) {
                cb();

                return;
            }

            Ext.Loader.loadScript({
                url: 'locale.js?locale=' + locale,
                onLoad: function () {
                    cb();
                }
            });
JS

        clearInterface => func [], <<'JS',
            var view = this.getView();

            view.getItems().each(function(item) {
                view.remove(item);
            });
JS

        # LOGIN
        onLogin => func [ 'username', 'password', 'persistent' ], <<"JS",
            var me = this;

            me.mask();

            me.doLogin(username, password, function (res) {
                me.unmask();

                if (res.isSuccess()) {

                    // store API token
                    me.setToken(res.data.token, persistent);

                    // set token and disconnect
                    APP.getApplication().api.auth(res.data.token);

                    // store session data
                    me.getViewModel().set('session', res.data);

                    me.setLocale(res.data.locale, function () {
                        me.clearInterface();

                        me.redirectTo(Ext.util.History.getToken(), {force: true});
                    });
                }
                else {
                    Ext.fireEvent('requestError', res);
                }
            });
JS

        onLogout => func [], <<"JS",
            this.doLogout();

            // drop API token
            this.removeToken();

            // set token and disconnect
            APP.getApplication().api.auth(null);

            // clear session data
            this.getViewModel().set('session', {});

            this.clearInterface();

            // redirect
            this.redirectTo(Ext.util.History.getToken(), {force: true});
JS
    };
}

1;
__END__
=pod

=encoding utf8

=head1 NAME

Pcore::Ext::Lib::Core::Viewport

=head1 SYNOPSIS

=head1 DESCRIPTION

=head1 ATTRIBUTES

=head1 METHODS

=head1 SEE ALSO

=cut
