/* @flow */

import { CompositeDisposable } from 'atom'
import Commands from './commands'
import StatusBar from './status-bar'
import BusySignal from './busy-signal'
import Intentions from './intentions'
import type { Linter, LinterMessage, MessagesPatch } from './types'

let Panel
let Editors
let TreeView

export default class LinterUI {
  name: string;
  panel: ?Panel;
  signal: BusySignal;
  editors: ?Editors;
  treeview: TreeView;
  commands: Commands;
  messages: Array<LinterMessage>;
  statusBar: StatusBar;
  intentions: Intentions;
  subscriptions: CompositeDisposable;
  idleCallbacks: Set<number>;

  constructor() {
    this.name = 'Linter'
    this.idleCallbacks = new Set()
    this.signal = new BusySignal()
    this.commands = new Commands()
    this.messages = []
    this.statusBar = new StatusBar()
    this.intentions = new Intentions()
    this.subscriptions = new CompositeDisposable()

    this.subscriptions.add(this.signal)
    this.subscriptions.add(this.commands)
    this.subscriptions.add(this.statusBar)

    const obsShowPanelCB = window.requestIdleCallback(function observeShowPanel() {
      this.subscriptions.add(atom.config.observe('linter-ui-default.showPanel', (showPanel) => {
        this.idleCallbacks.delete(obsShowPanelCB)
        if (!Panel) {
          Panel = require('./panel')
        }
        if (showPanel && !this.panel) {
          this.panel = new Panel()
          this.panel.update(this.messages)
        } else if (!showPanel && this.panel) {
          this.panel.dispose()
          this.panel = null
        }
      }))
    }.bind(this))
    this.idleCallbacks.add(obsShowPanelCB)

    const obsShowDecorationsCB = window.requestIdleCallback(function observeShowDecorations() {
      this.subscriptions.add(atom.config.observe('linter-ui-default.showDecorations', (showDecorations) => {
        this.idleCallbacks.delete(obsShowDecorationsCB)
        if (!Editors) {
          Editors = require('./editors')
        }
        if (showDecorations && !this.editors) {
          this.editors = new Editors()
          this.editors.update({ added: this.messages, removed: [], messages: this.messages })
        } else if (!showDecorations && this.editors) {
          this.editors.dispose()
          this.editors = null
        }
      }))
    }.bind(this))
    this.idleCallbacks.add(obsShowDecorationsCB)
  }
  render(difference: MessagesPatch) {
    const editors = this.editors

    this.messages = difference.messages
    if (editors) {
      if (editors.isFirstRender()) {
        editors.update({ added: difference.messages, removed: [], messages: difference.messages })
      } else {
        editors.update(difference)
      }
    }
    // Initialize the TreeView subscription if necessary
    if (!this.treeview) {
      if (!TreeView) {
        TreeView = require('./tree-view')
      }
      this.treeview = new TreeView()
      this.subscriptions.add(this.treeview)
    }
    this.treeview.update(difference.messages)

    if (this.panel) {
      this.panel.update(difference.messages)
    }
    this.commands.update(difference.messages)
    this.intentions.update(difference.messages)
    this.statusBar.update(difference.messages)
  }
  didBeginLinting(linter: Linter, filePath: string) {
    this.signal.didBeginLinting(linter, filePath)
  }
  didFinishLinting(linter: Linter, filePath: string) {
    this.signal.didFinishLinting(linter, filePath)
  }
  dispose() {
    this.idleCallbacks.forEach(callbackID => window.cancelIdleCallback(callbackID))
    this.idleCallbacks.clear()
    this.subscriptions.dispose()
    if (this.panel) {
      this.panel.dispose()
    }
    if (this.editors) {
      this.editors.dispose()
    }
  }
}

@@ -1120,107 +1120,8 @@
 ) %7B%0A
-      this.subscriptions.add(atom.config.observe('linter-ui-default.showPanel', (showPanel) =%3E %7B%0A  
     
@@ -1166,26 +1166,24 @@
 elCB)%0A      
- 
- 
 if (!Panel) 
@@ -1176,34 +1176,32 @@
   if (!Panel) %7B%0A
-  
         Panel = 
@@ -1217,35 +1217,130 @@
 ./panel')%0A      
-  %7D
+%7D%0A      this.subscriptions.add(atom.config.observe('linter-ui-default.showPanel', (showPanel) =%3E %7B
 %0A        if (sho
@@ -1730,119 +1730,8 @@
 ) %7B%0A
-      this.subscriptions.add(atom.config.observe('linter-ui-default.showDecorations', (showDecorations) =%3E %7B%0A  
     
@@ -1782,26 +1782,24 @@
 nsCB)%0A      
- 
- 
 if (!Editors
@@ -1794,34 +1794,32 @@
 if (!Editors) %7B%0A
-  
         Editors 
@@ -1843,27 +1843,134 @@
 ors')%0A      
-  %7D
+%7D%0A      this.subscriptions.add(atom.config.observe('linter-ui-default.showDecorations', (showDecorations) =%3E %7B
 %0A        if 

Move one-time setup out of the observe functions