/*

Siesta 5.6.1
Copyright(c) 2009-2022 Bryntum AB
https://bryntum.com/contact
https://bryntum.com/products/siesta/license

*/
/**
@class Siesta.Project.Browser.ExtJSCore

This is a role (mixin), representing the shared functionality between Ext JS and SenchaTouch projects.

*/
Role('Siesta.Project.Browser.ExtJSCore', {

    has : {
        /**
         * @cfg {Object} loaderPath
         *
         * The path used to configure the Ext.Loader 'paths' config to resolve JS namespaces to file paths, for dynamic loading of Ext JS classes.
         * For more information, please see the Ext docs: http://docs.sencha.com/extjs/apidocs/#!/api/Ext.Loader-cfg-paths
         *
         * See also {@link #requires}.
         *
         * By default the value will be set right before the test starts. If you need to set it earlier (during preloading phase),
         * use {@link #getLoaderPathHook} method.
         *
         * This option can be also specified in the test file descriptor.
         *
         * **Note**, that the value of this config will not be inherited from the parent tests group, if test has {@link Siesta.Project.Browser#pageUrl} option set.
         */
        loaderPath              : null,

        /**
         * @cfg {Array[String]} requires
         *
         * The array of class names, to be dynamically loaded with `Ext.require` call, before the test starts. Naturally, requires
         * the correct value for the {@link #loaderPath} to be set.
         *
         * This option can be also specified in the test file descriptor.
         */
        requires                : null,

        /**
         * @cfg {Boolean} waitForExtComponentQueryReady
         *
         * Setting this configuration option to "true" will cause Siesta to wait until the `Ext.ComponentQuery` class is loaded on the page,
         * before starting the test.
         *
         * This option can (and probably should) be also specified in the test file descriptor.
         */
        waitForExtComponentQueryReady       : true,


        // Set to true to fail t.knownBugInStatements, useful when running against Ext JS nightly builds
        failKnownBugIn          : false,

        recorderClass               : function () {
            return Siesta.Recorder.ExtJS
        }
    },


    override : {

        getNewTestConfiguration : function (desc, scopeProvider, contentManager, launchState) {
            var config              = this.SUPERARG(arguments)

            config.loaderPath       = this.getDescriptorConfig(desc, 'loaderPath')
            config.requires         = this.getDescriptorConfig(desc, 'requires')

            config.waitForExtComponentQueryReady = this.getDescriptorConfig(desc, 'waitForExtComponentQueryReady')

            return config
        },


        buildSandboxHashStructure : function () {
            var structure           = this.SUPERARG(arguments)

            structure.push('loaderPath', 'requires')

            return structure
        },


        buildHostPageUrlStopsInheriting : function () {
            var res         = this.SUPER()

            res.loaderPath  = true

            return res
        }
    },


    methods : {

        createViewport       : function(config) {
           return Ext.create("Siesta.Project.Browser.UI.Viewport", config);
        },


        generateLoaderPathHook : function () {
            // Such tedious check to allow setting the paths without crash for Ext JS versions < 4
            // (which may have own "Ext.Loader" object)
            return function (StartTest, Ext, loaderPath) {
                if (!loaderPath || StartTest.loaderPathHookInstalled || !Ext || !Ext.Loader || !Ext.Loader.setPath) return

                StartTest.loaderPathHookInstalled   = true

                Ext.Loader.setPath(loaderPath)
            }
        },


        /**
         * Returns a string presentation of the ExtJS/SenchaTouch hook for setting "Ext.Loader" paths,
         * suitable to be used in the test's {@link Siesta.Project#preload preloads}.
         * This will allow you to install the hook at the earliest possible point,
         * right after preloading Ext and before "requiring" any classes.
         *
         * The value for the paths should be provided in the {@link #loaderPath} config.
         * The inheritance of the value from groups is supported as usually, except the tests with
         * {@link Siesta.Project.Browser#pageUrl} option set.
         *
         * Typical usage will be:
         *

    var project = new Siesta.Project.Browser.ExtJS();

    project.configure({
        loaderPath              : { 'My' : 'js', 'My.Namespace' : 'js/somepath' },

        preload                 : [
            'http://cdn.sencha.io/ext-4.2.0-gpl/ext-all.js',
            {
                // inject the loader paths right after ExtJS and before the application file
                text    : project.getLoaderPathHook()
            },
            'app.js'
        ]
    });

         *
         * @return {String}
         */
        getLoaderPathHook : function () {
            var hook     = function (installationHook) {
                var parentWindow        = window.opener || window.parent
                var project             = parentWindow.Siesta.my.activeHarness

                eval('(' + installationHook + ')')(StartTest, Ext, project.getDescriptorConfig(project.getScriptDescriptor(StartTest.id), "loaderPath"))
            }

            return ';(' + hook.toString() + ')(' + JSON.stringify(this.generateLoaderPathHook().toString()) + ')'
        }
    }
})