(function () {
    'use strict';

    window.Whisper = window.Whisper || {};

    Whisper.AppView = Backbone.View.extend({
        initialize: function(options) {
          this.inboxView = null;
          this.installView = null;

          this.applyTheme();
          this.applyHideMenu();
        },
        events: {
            'click .openInstaller': 'openInstaller', // NetworkStatusView has this button
            'openInbox': 'openInbox',
            'change-theme': 'applyTheme',
            'change-hide-menu': 'applyHideMenu',
        },
        applyTheme: function() {
            var theme = storage.get('theme-setting') || 'android';
            this.$el.removeClass('ios')
                    .removeClass('android-dark')
                    .removeClass('android')
                    .addClass(theme);
        },
        applyHideMenu: function() {
            var hideMenuBar = storage.get('hide-menu-bar', false);
            window.setAutoHideMenuBar(hideMenuBar);
            window.setMenuBarVisibility(!hideMenuBar);
        },
        openView: function(view) {
          this.el.innerHTML = "";
          this.el.append(view.el);
          this.delegateEvents();
        },
        openDebugLog: function() {
            this.closeDebugLog();
            this.debugLogView = new Whisper.DebugLogView();
            this.debugLogView.$el.appendTo(this.el);
        },
        closeDebugLog: function() {
          if (this.debugLogView) {
            this.debugLogView.remove();
            this.debugLogView = null;
          }
        },
        openImporter: function() {
          window.addSetupMenuItems();
          this.resetViews();
          var importView = this.importView = new Whisper.ImportView();
          this.listenTo(importView, 'light-import', this.finishLightImport.bind(this));
          this.openView(this.importView);
        },
        finishLightImport: function() {
          var options = {
            hasExistingData: true
          };
          this.openInstaller(options);
        },
        closeImporter: function() {
          if (this.importView) {
            this.importView.remove();
            this.importView = null;
          }
        },
        openInstaller: function(options) {
          options = options || {};

          // If we're in the middle of import, we don't want to show the menu options
          //   allowing the user to switch to other ways to set up the app. If they
          //   switched back and forth in the middle of a light import, they'd lose all
          //   that imported data.
          if (!options.hasExistingData) {
            window.addSetupMenuItems();
          }

          this.resetViews();
          var installView = this.installView = new Whisper.InstallView(options);
          this.openView(this.installView);
        },
        closeInstaller: function() {
          if (this.installView) {
            this.installView.remove();
            this.installView = null;
          }
        },
        openStandalone: function() {
          if (window.config.environment !== 'production') {
            window.addSetupMenuItems();
            this.resetViews();
            this.standaloneView = new Whisper.StandaloneRegistrationView();
            this.openView(this.standaloneView);
          }
        },
        closeStandalone: function() {
          if (this.standaloneView) {
            this.standaloneView.remove();
            this.standaloneView = null;
          }
        },
        resetViews: function() {
          this.closeInstaller();
          this.closeImporter();
          this.closeStandalone();
        },
        openInbox: function(options) {
          options = options || {};
          // The inbox can be created before the 'empty' event fires or afterwards. If
          //   before, it's straightforward: the onEmpty() handler below updates the
          //   view directly, and we're in good shape. If we create the inbox late, we
          //   need to be sure that the current value of initialLoadComplete is provided
          //   so its loading screen doesn't stick around forever.

          // Two primary techniques at play for this situation:
          //   - background.js has two openInbox() calls, and passes initalLoadComplete
          //     directly via the options parameter.
          //   - in other situations openInbox() will be called with no options. So this
          //     view keeps track of whether onEmpty() has ever been called with
          //     this.initialLoadComplete. An example of this: on a phone-pairing setup.
          _.defaults(options, {initialLoadComplete: this.initialLoadComplete});

          console.log('open inbox');
          this.closeInstaller();

          if (!this.inboxView) {
            // We create the inbox immediately so we don't miss an update to
            //   this.initialLoadComplete between the start of this method and the
            //   creation of inboxView.
            this.inboxView = new Whisper.InboxView({
              model: self,
              window: window,
              initialLoadComplete: options.initialLoadComplete
            });
            return ConversationController.loadPromise().then(function() {
                this.openView(this.inboxView);
            }.bind(this));
          } else {
            if (!$.contains(this.el, this.inboxView.el)) {
                this.openView(this.inboxView);
            }
            window.focus(); // FIXME
            return Promise.resolve();
          }
        },
        onEmpty: function() {
          var view = this.inboxView;

          this.initialLoadComplete = true;
          if (view) {
            view.onEmpty();
          }
        },
        onProgress: function(count) {
          var view = this.inboxView;
          if (view) {
            view.onProgress(count);
          }
        },
        openConversation: function(conversation) {
          if (conversation) {
            this.openInbox().then(function() {
              this.inboxView.openConversation(null, conversation);
            }.bind(this));
          }
        },
    });
})();