const debug = require('debug')('hardware:indicator')
const EventEmitter = require('events')
const gpio = require('raspi-gpio')
const rx = require('rxjs/Rx')

// Common flash EventEmitter
let flashEmitter = new EventEmitter()
setInterval(() => {
  flashEmitter.emit('flash')
}, 500)

module.exports = class Indicator {
  constructor (name, pinId) {
    this.name = name
    this.pinId = pinId
    this.isFlashing = false
    this.isEnabled = false

    // Need to find a way to bind 'this' to eventhandler
    // Create a method to send a series
    this.subject = new rx.Subject()
    this.subscription = this.subject.concatMap(event => {
      return rx.Observable.from([event]).delay(event.delay)
    }).subscribe(() => { this._eventHandler() })

    this.nOutputPin = new gpio.DigitalOutput(this.pinId)
    this.nOutputPin.write(gpio.HIGH)

    // Setup flash handler common to all Indicator instances
    flashEmitter.on('flash', () => { this._flashHandler() })
    debug(this.name + ' indicator output constructed on pin ID ' + this.pinId)
  }

  // PUBLIC ENABLE INTERFACE

  get enabled () {
    return this.isEnabled
  }

  enable () {
    this.isEnabled = true
    this.nOutputPin.write(gpio.LOW)
    debug(this.name + ' indicator output enabled on pin ID ' + this.pinId)
  }

  disable () {
    this.isEnabled = false
    this.nOutputPin.write(gpio.HIGH)
    debug(this.name + ' indicator output disabled on pin ID ' + this.pinId)
  }

  toggleEnable () {
    this.isEnabled = !this.isEnabled
    this._togglePin()
    debug(this.name + ' indicator output toggled to ' + (this.enabled ? 'enabled' : 'disabled') + ' on pin ID ' + this.pinId)
  }

  // PUBLIC FLASHING INTERFACE

  get flashing () {
    return this.isFlashing
  }

  flash () {
    this.isFlashing = true
    debug(this.name + ' indicator flashing enabled for pin ID ' + this.pinId)
  }

  steady () {
    this.isFlashing = false

    // Restore state if the indicator is already enabled
    if (this.isEnabled) {
      this.nOutputPin.write(gpio.LOW)
    }
    debug(this.name + ' indicator flashing disabled for pin ID ' + this.pinId)
  }

  toggleFlash () {
    this.isFlashing = !this.isFlashing

    // Restore state if the indicator is already enabled
    if (this.isEnabled) {
      this.nOutputPin.write(gpio.LOW)
    }
    debug(this.name + ' indicator flashing toggled to ' + (this.flashing ? 'enabled' : 'disabled') + ' on pin ID ' + this.pinId)
  }

  // PUBLIC EVENT METHODS
  get next () {
    return this.subject.next
  }

  // "PRIVATE METHODS"

  _flashHandler () {
    if (this.isEnabled && this.isFlashing) {
      this._togglePin()
    }
  }

  _togglePin () {
    this.nOutputPin.value === gpio.HIGH ? this.nOutputPin.write(gpio.LOW) : this.nOutputPin.write(gpio.HIGH)
  }

  _eventHandler (event) {
    switch (event.type) {
      case 'TOGGLE':
        this.toggleEnable()
        break
      case 'ENABLE':
        this.enable()
        break
      case 'DISABLE':
        this.disable()
        break
      case 'TOGGLE_FLASH':
        this.toggleFlash()
        break
      case 'FLASH':
        this.flash()
        break
      case 'STEADY':
        this.steady()
        break
      default:
        console.error('ERROR: Invalid Event Type')
    }
  }
}

@@ -452,97 +452,272 @@
  // 
-Need to find a way to bind 'this' to eventh
+Create an Observable Sequence to play indicator sequences%0A    let rxH
 andler
+ = %7B
 %0A    
-// Create a method to send a series
+  TOGGLE: this.toggleEnable,%0A      ENABLE: this.enable,%0A      DISABLE: this.disable,%0A      TOGGLE_FLASH: this.toggleFlash,%0A      FLASH: this.flash,%0A      STEADY: this.steady%0A    %7D%0A
 %0A   
@@ -749,16 +749,17 @@
 bject()%0A
+%0A
     this
@@ -890,39 +890,195 @@
 be((
+event
 ) =%3E %7B
- this._eventHandler() %7D)%0A
+%0A      if (event.type in rxHandler) %7B%0A        rxHandler%5Bevent.type%5D(event)%0A      %7D else %7B%0A        console.error('ERROR: Invalid Event Type')%0A      %7D%0A    %7D)%0A%0A    // Setup Output
 %0A   
@@ -3097,495 +3097,7 @@
 %0A  %7D
-%0A%0A  _eventHandler (event) %7B%0A    switch (event.type) %7B%0A      case 'TOGGLE':%0A        this.toggleEnable()%0A        break%0A      case 'ENABLE':%0A        this.enable()%0A        break%0A      case 'DISABLE':%0A        this.disable()%0A        break%0A      case 'TOGGLE_FLASH':%0A        this.toggleFlash()%0A        break%0A      case 'FLASH':%0A        this.flash()%0A        break%0A      case 'STEADY':%0A        this.steady()%0A        break%0A      default:%0A        console.error('ERROR: Invalid Event Type')%0A    %7D%0A  %7D
 %0A%7D%0A

Refactor indicator observables