var uniflash;
(function (uniflash) {
    var views;
    (function (views) {
        'use strict';
        function createMainViewStateProvider($stateProvider) {
            var stateProvider = $stateProvider;
            var mainViewStateProvider = stateProvider.state('main', {
                url: '/main/:deviceXMLFile/:connectionXMLFile',
                templateUrl: 'main/main.html',
                controller: MainStateController,
                controllerAs: 'vm',
                resolve: {
                    sessionInit: sessionInit
                },
                params: { forceSessionInit: false, lp: false },
                abstract: true // never come here directly
            });
            // This is the resolve function it will make sure that main view will not render
            // until the session has been loaded
            sessionInit.$inject = ['ufSession', '$stateParams'];
            function sessionInit(ufSession, $stateParams, $location) {
                return ufSession.startIfNeeded($stateParams.deviceXMLFile, $stateParams.connectionXMLFile, $stateParams.forceSessionInit, $stateParams.lp);
            }
            MainStateController.$inject = ['$state', 'ufTargetConfig', 'ufPropertiesDB', 'ufContext', 'ufConsoleInternal', 'ufDsProgressDialog', 'ufPropertiesValue', 'ufSession'];
            function MainStateController($state, ufTargetConfig, ufPropertiesDB, ufContext, ufConsoleInternal, ufDsProgressDialog, ufPropertiesValue, ufSession) {
                var vm = this;
                vm.ufPropertiesDB = ufPropertiesDB;
                vm.ufContext = ufContext;
                vm.ufConsoleInternal = ufConsoleInternal;
                vm.ufPropertiesValue = ufPropertiesValue;
                ufTargetConfig.getDevice($state.params.deviceXMLFile)
                    .then(function (device) {
                    vm.deviceName = device.id;
                    return ufTargetConfig.getConnection(device.connectionIndices, $state.params.connectionXMLFile);
                }).then(function (connection) {
                    vm.connectionName = connection.id;
                });
                /*
                vm.serial;
                ufTargetConfig.getConfigurables($state.params.deviceXMLFile, $state.params.connectionXMLFile).then( function() {
                     if ( ufTargetConfig.getConfigurableObj('SEPK.POD_PORT') && (ufTargetConfig.getConfigurableObj('SEPK.POD_PORT').value === 'Select by serial number') ) {
                         vm.serial = ufTargetConfig.getConfigurableObj('SEPK.POD_PORT_SEPK.POD_SERIAL').value;
                     }
                });
                */
                vm.getDeviceInfo = function () {
                    var dsCore = ufDsProgressDialog.getDSCore(ufContext.getCurrentCore().name);
                    return dsCore.run('getTargetInfo');
                };
                vm.downloadCCXML = function () {
                    var filename = vm.deviceName + '.ccxml';
                    var blob = new Blob([ufSession.getCCXML()]);
                    saveAs(blob, filename);
                };
            }
            return mainViewStateProvider;
        }
        // We need to implement a provider, so views can register at angular application init time
        // at this time various views can register themselves with us
        var MainViewProvider = (function () {
            function MainViewProvider($stateProvider) {
                var _this = this;
                this.viewDescriptors = [];
                this.$get = ['$state', 'ufSession', function ($state, ufSession, _) {
                        return new MainViewService($state, ufSession, _this.mainViewStateProvider);
                    }];
                // create the main ( top level ) angular ui router view 
                this.mainViewStateProvider = new ViewStateProvider(createMainViewStateProvider($stateProvider), null);
            }
            MainViewProvider.$inject = ['$stateProvider'];
            return MainViewProvider;
        }());
        views.MainViewProvider = MainViewProvider;
        var ViewNodeLookup = (function () {
            function ViewNodeLookup() {
            }
            ViewNodeLookup.add = function (viewType, viewNode) {
                var key = uniflash.RegisteredViews[viewType];
                ViewNodeLookup.viewNodesLookup[key] = viewNode;
            };
            ViewNodeLookup.get = function (viewType) {
                var key = uniflash.RegisteredViews[viewType];
                return ViewNodeLookup.viewNodesLookup[key];
            };
            ViewNodeLookup.viewNodesLookup = {};
            return ViewNodeLookup;
        }());
        // object to encapsulate angular ui router view state
        var ViewStateProvider = (function () {
            function ViewStateProvider($stateProvider, viewDescriptor) {
                this.$stateProvider = $stateProvider;
                this.viewDescriptor = viewDescriptor;
                this.childProviders = [];
            }
            //Add a view heirarchy , get back the added child node
            ViewStateProvider.prototype.addViewState = function (viewToAdd) {
                // register ui router views
                var internalStateProvider = this.$stateProvider.state(getState(viewToAdd.name), {
                    url: '/' + viewToAdd.name + (viewToAdd.isCoreSensitive ? '/:coreName' : ''),
                    templateUrl: viewToAdd.templateUrl,
                    controller: function () {
                        var vm = this;
                        vm.title = viewToAdd.title;
                    },
                    controllerAs: 'vm'
                });
                var viewStateProvider = new ViewStateProvider(internalStateProvider, viewToAdd);
                this.childProviders.push(viewStateProvider);
                return viewStateProvider;
            };
            ViewStateProvider.prototype.getViewNode = function (cores, $state) {
                var viewNode;
                if (!this.viewDescriptor) {
                    viewNode = new ViewNode(null, null, null);
                }
                else {
                    viewNode = !this.viewDescriptor.isCoreSensitive ? createViewNode(this.viewDescriptor, $state)
                        : createCoreSensitiveViewNode(this.viewDescriptor, cores, $state);
                }
                _.each(this.childProviders, function (childProvider) {
                    viewNode.childViewNodes.push(childProvider.getViewNode(cores, $state));
                });
                if (this.viewDescriptor) {
                    ViewNodeLookup.add(this.viewDescriptor.viewType, viewNode);
                }
                return viewNode;
            };
            return ViewStateProvider;
        }());
        var MainViewService = (function () {
            function MainViewService($state, ufSession, mainViewStateProvider) {
                this.$state = $state;
                this.ufSession = ufSession;
                this.mainViewStateProvider = mainViewStateProvider;
            }
            // Based on the views, create navigational view nodes
            MainViewService.prototype.getMainViewNode = function () {
                return this.mainViewStateProvider.getViewNode(this.ufSession.queryConfig().cores, this.$state);
            };
            MainViewService.prototype.go = function (viewType, coreName) {
                var viewNode = ViewNodeLookup.get(viewType);
                // assume only core sensetive views have children
                if (viewNode.childViewNodes.length > 0) {
                    viewNode = coreName ? _.findWhere(viewNode.childViewNodes, { displayName: coreName })
                        : viewNode.childViewNodes[0];
                }
                viewNode.clickHandler();
                this.viewNodeClickedListener(viewNode);
            };
            // register the navigation pane to be notified of view changes
            MainViewService.prototype.registerNavPaneListener = function (listener) {
                var _this = this;
                this.viewNodeClickedListener = listener;
                return function () {
                    //unregister
                    _this.viewNodeClickedListener = null;
                };
            };
            return MainViewService;
        }());
        views.MainViewService = MainViewService;
        function createViewNode(viewDescriptor, $state) {
            return new ViewNode(viewDescriptor.name, viewDescriptor.title, createClickHandler($state, getState(viewDescriptor.name)));
        }
        // A core sensetive view
        function createCoreSensitiveViewNode(viewDescriptor, cores, $state) {
            var state = getState(viewDescriptor.name);
            var clickHandler = cores.length === 1 ?
                createClickHandler($state, state, cores[0].name) : null;
            var viewNode = new ViewNode(viewDescriptor.name, viewDescriptor.title, clickHandler);
            if (cores.length > 1) {
                _.each(cores, function (core) {
                    var childViewNode = new ViewNode(core.name, core.name, createClickHandler($state, state, core.name));
                    childViewNode.level = 1;
                    viewNode.childViewNodes.push(childViewNode);
                });
            }
            return viewNode;
        }
        // This is the public interface used by the UI code
        // to render the views
        var ViewNode = (function () {
            function ViewNode(displayName, title, clickHandler) {
                if (clickHandler === void 0) { clickHandler = null; }
                this.displayName = displayName;
                this.title = title;
                this.clickHandler = clickHandler;
                this.childViewNodes = [];
                this.active = false;
                this.level = 0;
                this.showView = true;
            }
            ViewNode.prototype.hasChildren = function () {
                return this.childViewNodes.length > 0;
            };
            return ViewNode;
        }());
        views.ViewNode = ViewNode;
        function getState(name) {
            return 'main.' + name;
        }
        function createClickHandler($state, state, coreName) {
            if (coreName === void 0) { coreName = null; }
            return function () {
                $state.go(state, coreName ? {
                    coreName: coreName
                } : null);
            };
        }
        angular.module('uniflash').provider('ufMainView', MainViewProvider);
    })(views = uniflash.views || (uniflash.views = {}));
})(uniflash || (uniflash = {}));
