/*

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

*/
Ext.define('Siesta.Project.Browser.UI.ViewportController', {
    extend                    : 'Ext.app.ViewController',
    alias                     : 'controller.viewport',

    requires                    : [
        'Siesta.Project.Browser.UI.TestGridContextMenu',
        'Ext.window.Toast'
    ],

    mixins : [
        'Siesta.Project.Browser.UI.CanCopyToClipboard'
    ],

    control                   : {
        testgrid : {
            selectionchange         : 'onTestGridSelectionChange',
            checkchange             : 'onTestGridCheckChange',
            itemcontextmenu         : 'onTestFileContextMenu',
            itemdblclick            : 'onTestFileDoubleClick',
            itemclick               : 'onTestFileClick',
            resize                  : 'onTestGridResize',
            optionchange            : 'onTestGridOptionChange',
            buttonclick             : 'onTestGridToolbarClick',
            framesizechange         : 'onFrameSizeChange'
        },

        'testnamecolumn treefilter' : { change : { fn : 'onFilterChange', buffer : 300 } },

        'testgridcontextmenu #uncheckOthers' : { click : 'uncheckOthers' },
        'testgridcontextmenu #runThis'       : { click : 'runThisFile' },
        'testgridcontextmenu #uncheckAll'    : { click : 'uncheckAll' },
        'testgridcontextmenu #checkAll'      : { click : 'checkAll' },
        'testgridcontextmenu #expandAll'     : { click : 'expandAll' },
        'testgridcontextmenu #collapseAll'   : { click : 'collapseAll' },
        'testgridcontextmenu #filterToCurrentGroup'   : { click : 'filterToCurrentGroup' },
        'testgridcontextmenu #filterToFailed'   : { click : 'filterToFailed' },
        'testgridcontextmenu #viewSource'   : { click : 'viewSource' },

        'testgridcontextmenu #linkSelect'               : { click : 'linkSelect' },
        'testgridcontextmenu #linkFilterAutoLaunch'     : { click : 'linkFilterAutoLaunch' },

        resultpanel : {
            viewdomchange  : 'onDomPanelVisibilityChange',
            runbuttonclick : 'runTest'
        }
    },

    disableRunButtonTimeout             : null,
    disableRunButtonInterval            : 150,


    onFilterChange : function () {
        var viewport    = this.getView();

        viewport.saveState()
    },


    filterToFailed : function () {
        var viewport    = this.getView();

        var filter      = []

        viewport.forEachTestFile(function (testFileRecord) {
            var test = testFileRecord.get('test')

            if (test && test.isFailed()) filter.push(testFileRecord.get('title'))
        })

        if (filter.length) viewport.slots.filesTree.setFilterValue(filter.join(' | '))
    },


    filterToCurrentGroup : function () {
        var viewport    = this.getView();
        var desc        = viewport.currentFile.get('descriptor')

        if (desc.parent) viewport.slots.filesTree.setFilterValue(desc.parent.group + '>')
    },


    // Test Grid events
    onTestGridSelectionChange : function (selModel, selectedRecords) {

        if (selectedRecords.length) {
            var viewport    = this.getView();
            var testFile    = selectedRecords[0]
            var test        = testFile.get('test')

            if (test) {
                // magic global for users to ease access to the currently selected tests
                T           = test

                viewport.slots.resultPanel.showTest(test, testFile.get('assertionsStore'))
            }

            if (testFile.isLeaf()) {
                Ext.History.add(testFile.data.url);
            }
        }
    },


    onTestGridCheckChange : function (testFile, checked) {
        var viewport = this.getView();

        viewport.setNodeChecked(testFile, checked)
    },


    onTestFileContextMenu : function (view, testFile, el, index, event) {
        var viewport = this.getView();
        if (viewport.isReadOnlyReport) return

        viewport.currentFile = testFile

        if (!viewport.contextMenu) {
            viewport.contextMenu = new Siesta.Project.Browser.UI.TestGridContextMenu();
        }

        viewport.contextMenu.showAt(event.getXY());

        event.preventDefault();
    },


    onTestFileDoubleClick : function (view, testFile) {
        var viewport    = this.getView();
        if (viewport.isReadOnlyReport) return

        var testsStore  = viewport.testsStore

        if (testsStore.isTreeFiltered() && !testFile.isLeaf()) {
            var childDesc = []

            testFile.cascadeBy(function (node) {
                if (node != testFile && node.isLeaf() && testsStore.isNodeFilteredIn(node))
                    childDesc.push(node.get('descriptor'))
            })

            viewport.project.launch(childDesc);
        } else
            viewport.launchTest(testFile);
    },


    onTestFileClick : function (view, testFile, p3, p4, event) {
        var viewport        = this.getView();
        if (viewport.isReadOnlyReport) return

        var referenceUrl    = viewport.project.getDescriptorConfig(testFile.get('descriptor'), 'referenceUrl')

        if (referenceUrl && event.ctrlKey) {
            var popup       = window.open(referenceUrl, "_blank")

            if (!popup) Ext.toast("Popups are disabled in the browser", "Can't open new tab")
        }
    },


    onTestGridResize : function () {
        // preserve min width of the assertion grid
        this.getView().slots.resultPanel.ensureLayout();
    },


    onTestGridOptionChange : function (component, optionName, optionValue) {
        var viewport = this.getView();

        viewport.setOption(optionName, optionValue)

        viewport.saveState()
    },


    onTestGridToolbarClick : function (hdr, button, action) {
        var viewport = this.getView();

        switch (action) {
            case 'run-checked':
                viewport.runChecked();
                break;
            case 'run-failed':
                viewport.runFailed();
                break;
            case 'run-all':
                viewport.runAll();
                break;
            // note, that this button does not exists
            case 'stop':
                viewport.stopSuite(button);
                break;
        }
    },


    onFrameSizeChange : function(slider, width, height, landscape) {
        var viewport = this.getView();

        if (!landscape) {
            var w = width;
            width = height;
            height = w;
        }

        $('.tr-iframe').width(width);
        $('.tr-iframe').height(height);

        viewport.project.viewportHeight = height;
        viewport.project.viewportWidth = width;
    },
    // EOF Test Grid events


    // Test Grid Context Menu events
    uncheckOthers    : function () {
        var viewport        = this.getView();
        var currentFile     = viewport.currentFile

        viewport.uncheckAllExcept(currentFile)
        viewport.setNodeChecked(currentFile, true)
    },


    linkFilterAutoLaunch : function () {
        var viewport        = this.getView();
        var currentFile     = viewport.currentFile

        var match           = /([^\/]*)$/.exec(currentFile.get('descriptor').url)

        var url             = location.protocol + '//' + location.host + location.pathname + '?'
            + 'filter=' + encodeURIComponent(match[ 1 ]) + '&autolaunch=1'
        var success         = this.copyToClipboard(url)

        if (success) {
            Ext.toast("Url copied to clipboard", 'Success')
        } else {
            Ext.Msg.show({
                message         : 'Please select & copy this url manually:<br>' + url,
                title           : 'Copy to clipboard failed',
                modal           : false
            })
        }
    },


    linkSelect : function () {
        var viewport        = this.getView();
        var currentFile     = viewport.currentFile

        var url             = location.protocol + '//' + location.host + location.pathname + '#' + currentFile.get('descriptor').url
        var success         = this.copyToClipboard(url)

        if (success) {
            Ext.toast("Url copied to clipboard", 'Success')
        } else {
            Ext.Msg.show({
                message         : 'Please select & copy this url manually:<br>' + url,
                title           : 'Copy to clipboard failed',
                modal           : false
            })
        }
    },


    runThisFile : function () {
        var viewport = this.getView();

        viewport.project.launch([ viewport.currentFile.get('descriptor') ])
    },

    uncheckAll : function () {
        var viewport = this.getView();

        viewport.uncheckAllExcept()
    },

    checkAll : function () {
        var viewport = this.getView();

        viewport.testsStore.forEach(function (node) {
            viewport.setNodeChecked(node, true, true)
        })
    },

    expandAll : function () {
        var viewport = this.getView();

        viewport.slots.filesTree.expandAll()
    },

    collapseAll : function () {
        var viewport = this.getView();

        viewport.slots.filesTree.collapseAll()
    },

    viewSource : function() {
        var testRecord      = this.getView().currentFile;
        var test            = testRecord.get('test');
        var win             = window.open('', 'siesta-source');
        var head            = win.document.documentElement.getElementsByTagName('head')[0];
        var body            = win.document.body;

        head.innerHTML = '<title>' + testRecord.get('title') + '</title>'

        if (test) {
            body.innerHTML      = '<pre>' + test.getSource() + '</pre>';
        } else {
            $.ajax(testRecord.get('url'), {
                success: function(text) {
                    body.innerHTML  = '<pre>' + text + '</pre>';
                }
            });
        }
    },
    // EOF Test Grid Context Menu events

    // Result Panel events
    onDomPanelVisibilityChange : function (g, value) {
        var viewport = this.getView();

        viewport.setOption('viewDOM', value);
        viewport.saveState();
    },


    runTest : function () {
        // launch the "viewport.runTest();" immediately, but ignore any further calls to this method
        // during the following 100ms
        var me          = this

        if (me.disableRunButtonTimeout != null) return

        me.disableRunButtonTimeout  = setTimeout(function () {
            me.disableRunButtonTimeout    = null
        }, me.disableRunButtonInterval)

        var viewport    = me.getView();

        viewport.runTest();
    }
    // EOF Result Panel events
})