(function () {
    'use strict';
    /*global TICloudAgent*/
    var DsProgressDialog = (function () {
        function DsProgressDialog($q, $window, ticAlerts, ufConsole, ufProgess, ufDialog, ufDS, ufContext) {
            this.$q = $q;
            this.$window = $window;
            this.ticAlerts = ticAlerts;
            this.ufConsole = ufConsole;
            this.ufProgess = ufProgess;
            this.ufDialog = ufDialog;
            this.ufDS = ufDS;
            this.ufContext = ufContext;
            this.types = this.ufConsole.msgTypes;
            this.actionContext = {
                configureDS: 'Configuring Debug Server',
                deconfigureDS: 'Deconfiguring Debug Server',
                disconnectAllCores: 'Disconnect all connected cores',
                program: 'Load Program',
                verify: 'Verify Program',
                flashOperation: 'Flash Operation',
                readMemory: 'Read Memory',
                exportMemoryAsCoff: 'Export Memory As Coff',
                exportMemoryAsBin: 'Export Memory As Coff',
                evaluate: 'Evaluate Expression',
                getTargetInfo: 'Query Target Information',
                getResets: 'Query Reset Information',
                performReset: 'Perform Reset Operation'
            };
            // TI Cloud Agent relies on a global Q for promises
            // For compatability set that to the angular $q service instead of pulling it from ticloudagent
            $window.Q = $q;
        }
        DsProgressDialog.prototype.createTargetSupportProgressHandler = function (targetSupport, progressDialog) {
            function progressHandler(event) {
                progressDialog.handleEvent(event);
            }
            targetSupport.addListener('progress', progressHandler); // progress dialog
            return function () {
                targetSupport.removeListener('progress', progressHandler); // progress dialog
            };
        };
        DsProgressDialog.prototype.createConsoleHandler = function (type) {
            var _this = this;
            return function (event) {
                if (event.message) {
                    _this.ufConsole.addMessage(event.type, event.message);
                }
            };
        };
        DsProgressDialog.prototype.createDSEventHandlers = function (ds, progressDialog) {
            var statusConsoleHandler = this.createConsoleHandler(this.types.STATUS);
            var gelConsoleHandler = this.createConsoleHandler(this.types.GEL);
            function updateProgressHandler(event) {
                // console.log(JSON.stringify(event));
                progressDialog.handleEvent(event, ds.progress.cancel.bind(ds.progress));
            }
            var openDialogs = {};
            var currentUfDialog = this.ufDialog;
            function newDialogHandler(event) {
                function buttonClicked(button) {
                    return ds.dialogs.setButtonResponse(event.id, button);
                }
                function closeClicked() {
                    return ds.dialogs.dismiss(event.id);
                }
                currentUfDialog.createDialog(event, buttonClicked, closeClicked)
                    .then(function (newDialog) {
                    openDialogs[event.id] = newDialog;
                });
            }
            function dismissDialogHandler(event) {
                if (openDialogs[event.id]) {
                    openDialogs[event.id].close();
                    openDialogs[event.id] = null;
                }
            }
            function fileExportEventHandler(event) {
                if (event) {
                    var eventObj = event.event;
                    if (eventObj && eventObj.data) {
                        var byteArray = new Uint8Array(eventObj.data);
                        var blob = new Blob([byteArray], { type: 'application/octet-stream' });
                        var defaultName = 'temp_file';
                        if (eventObj.defaultName) {
                            defaultName = eventObj.defaultName;
                        }
                        saveAs(blob, defaultName);
                    }
                }
            }
            ds.addListener('fileExportEvent', fileExportEventHandler);
            ds.addListener('statusMessage', statusConsoleHandler);
            ds.addListener('gelOutput', gelConsoleHandler);
            ds.progress.addListener('update', updateProgressHandler); // progress dialog
            ds.dialogs.willHandleDialogs(true);
            ds.dialogs.addListener('new', newDialogHandler);
            ds.dialogs.addListener('dismissed', dismissDialogHandler);
            return function () {
                ds.removeListener('fileExportEvent', fileExportEventHandler);
                ds.removeListener('statusMessage', statusConsoleHandler);
                ds.removeListener('gelOutput', gelConsoleHandler);
                ds.progress.removeListener('update', updateProgressHandler);
                ds.dialogs.removeListener('new', newDialogHandler);
                ds.dialogs.removeListener('dismissed', dismissDialogHandler);
            };
        };
        DsProgressDialog.prototype.createAgentInitProgressEvent = function (msg, isFirstUpdate, isComplete) {
            var name = 'Please Wait...';
            return {
                id: -1,
                name: name,
                subActivity: msg,
                isFirstUpdate: isFirstUpdate,
                isComplete: isComplete
            };
        };
        DsProgressDialog.prototype.createDoneProgressEvent = function () {
            var name = 'Done';
            return {
                subActivity: name,
                percent: 100,
                isCancellable: false
            };
        };
        DsProgressDialog.prototype.getProgressEventHandler = function (progressDialog) {
            var _this = this;
            return function (input) {
                var msg = input[0] ? input[0] : input;
                return progressDialog.handleEvent(_this.createAgentInitProgressEvent(msg, true, false));
            };
        };
        DsProgressDialog.prototype.getTargetSupportProgressEventsHandler = function (progressDialog) {
            var _this = this;
            return function (agent) {
                return _this.createTargetSupportProgressHandler(agent.TargetSupport, progressDialog);
            };
        };
        DsProgressDialog.prototype.getDSHandlers = function (progressDialog) {
            var _this = this;
            return function (agent) {
                return _this.createDSEventHandlers(agent.DS, progressDialog);
            };
        };
        DsProgressDialog.prototype.setupDialogHandlers = function (progressDialog) {
            this.ufDS.registerProgressEventHandler(this.getProgressEventHandler(progressDialog));
            this.ufDS.registerDSHandler(this.getDSHandlers(progressDialog));
            this.ufDS.registerTargetSupportHandler(this.getTargetSupportProgressEventsHandler(progressDialog));
        };
        DsProgressDialog.prototype.initDSWithGUIHandlers = function () {
            var _this = this;
            var progressDialog;
            return this.ufProgess.createProgress('Initializing DS GUI Handlers')
                .then(function (newProgressDialog) {
                progressDialog = newProgressDialog;
            })
                .then(function () {
                _this.setupDialogHandlers(progressDialog);
            })
                .catch(function (error) {
                if (error.message) {
                    return _this.ticAlerts.showError(error.message);
                }
            })
                .finally(function () {
                _this.ufDS.unregisterEventsHandlers();
                progressDialog.close();
            });
        };
        DsProgressDialog.prototype.getDSCore = function (coreName) {
            var _this = this;
            return {
                run: function (action) {
                    var argsToActionFunc = [];
                    for (var _i = 1; _i < arguments.length; _i++) {
                        argsToActionFunc[_i - 1] = arguments[_i];
                    }
                    var progressDialog;
                    var dsCoreRet;
                    return _this.ufProgess.createProgress(_this.actionContext[action])
                        .then(function (newProgressDialog) {
                        progressDialog = newProgressDialog;
                    })
                        .then(function () {
                        _this.setupDialogHandlers(progressDialog);
                        var dsCore = _this.ufDS.getDSCore(coreName);
                        if (action) {
                            return dsCore[action].apply(dsCore, argsToActionFunc);
                        }
                    })
                        .then(function (ret) {
                        dsCoreRet = ret;
                        return progressDialog.handleEvent(_this.createDoneProgressEvent());
                    })
                        .then(function () {
                        return dsCoreRet;
                    })
                        .finally(function () {
                        _this.ufDS.unregisterEventsHandlers();
                        progressDialog.close();
                    });
                }
            };
        };
        DsProgressDialog.prototype.getCurrentDSCore = function () {
            return this.getDSCore(this.ufContext.getCurrentCore().name);
        };
        DsProgressDialog.prototype.runDSRootOp = function (action) {
            var _this = this;
            var argsToActionFunc = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                argsToActionFunc[_i - 1] = arguments[_i];
            }
            var progressDialog;
            return this.ufProgess.createProgress(this.actionContext[action])
                .then(function (newProgressDialog) {
                progressDialog = newProgressDialog;
            })
                .then(function () {
                _this.setupDialogHandlers(progressDialog);
                if (action && _this.ufDS.dsImpl) {
                    return _this.ufDS.dsImpl[action].apply(_this.ufDS.dsImpl, argsToActionFunc);
                }
            })
                .then(function () {
                return progressDialog.handleEvent(_this.createDoneProgressEvent());
            })
                .finally(function () {
                _this.ufDS.unregisterEventsHandlers();
                progressDialog.close();
            });
        };
        DsProgressDialog.prototype.configureDS = function () {
            return this.runDSRootOp('configureDS');
        };
        DsProgressDialog.prototype.deconfigureDS = function () {
            return this.runDSRootOp('deconfigureDS');
        };
        DsProgressDialog.prototype.disconnectAllCores = function () {
            return this.runDSRootOp('disconnectAllCores');
        };
        DsProgressDialog.$inject = ['$q', '$window', 'ticAlerts', 'ufConsole', 'ufProgess', 'ufDialog', 'ufDS', 'ufContext'];
        return DsProgressDialog;
    }());
    angular.module('uniflash').service('ufDsProgressDialog', DsProgressDialog);
})();
