context = window
PLAYBACK_MONITOR_MODE = context.JK.PLAYBACK_MONITOR_MODE
EVENTS = context.JK.EVENTS
logger = context.JK.logger

mixins = []

# this check ensures we attempt to listen if this component is created in a popup
reactContext = if window.opener? then window.opener else window
# make sure this is actually us opening the window, not someone else (by checking for MixerStore)
if window.opener?
  try
    m = window.opener.MixerStore
  catch e
    reactContext = window

MixerStore = reactContext.MixerStore
MixerActions = reactContext.MixerActions
MediaPlaybackStore = reactContext.MediaPlaybackStore
SessionActions = reactContext.SessionActions
MediaPlaybackActions = reactContext.MediaPlaybackActions
JamTrackStore = reactContext.JamTrackStore

mixins.push(Reflux.listenTo(MixerStore,"onInputsChanged"))
mixins.push(Reflux.listenTo(MediaPlaybackStore, 'onMediaStateChanged'))
mixins.push(Reflux.listenTo(JamTrackStore, 'onJamTrackStateChanged'))


@MediaControls = React.createClass({

  mixins: mixins
  tempos : [ 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 63, 66, 69, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 126, 132, 138, 144, 152, 160, 168, 176, 184, 192, 200, 208 ]

  onJamTrackStateChanged: (jamTrackState) ->
    if window.unloaded
      return

    if window.closed
      return

    @monitorControls(@state.controls, @state.mediaSummary, jamTrackState)
    @setState({jamTrackState: jamTrackState})

  onMediaStateChanged: (changes) ->
    if window.unloaded
      return
    if window.closed
      return

    if changes.playbackStateChanged
      if @state.controls?
        if changes.playbackState == 'play_start'
          @state.controls.onPlayStartEvent()
        else if changes.playbackState == 'play_stop'
          @state.controls.onPlayStopEvent()
        else if changes.playbackState == 'play_pause'
          @state.controls.onPlayPauseEvent();
    if changes.positionUpdateChanged
      if @state.controls?
        @state.controls.executeMonitor(changes.positionMs, changes.durationMs, changes.isPlaying)
    if changes.currentTimeChanged
      @setState({time: changes.time})

  onInputsChanged: (sessionMixers) ->
    if window.unloaded
      return

    session = sessionMixers.session
    mixers = sessionMixers.mixers

    if @state.controls?
      mediaSummary = mixers.mediaSummary
      metro = mixers.metro

      @monitorControls(@state.controls, mediaSummary, @state.jamTrackState)

      state = {mediaSummary: mediaSummary, metro: metro}
      try
        @setState(state)
      catch e
        logger.error('MediaControls: unable to set state', state, e)
      try
        @updateMetronomeDetails(metro, @state.initializedMetronomeControls)
      catch e
        logger.error('MediaControls: unable to update metronome details', e)

  updateMetronomeDetails: (metro, initializedMetronomeControls) ->
    logger.debug("MediaControls: setting tempo/sound/cricket", metro)
    $root = jQuery(this.getDOMNode())
    $root.find("select.metro-tempo").val(metro.tempo)
    $root.find("select.metro-sound").val(metro.sound)

    if initializedMetronomeControls
      mode = if metro.cricket then 'cricket' else 'self'
      logger.debug("settingcricket", mode)
      $root.find('#metronome-playback-select').metronomeSetPlaybackMode(mode)

  monitorControls: (controls, mediaSummary, jamTrackState) ->

    if mediaSummary.mediaOpen || mediaSummary.jamTrack? || jamTrackState?.jamTrack?
      if mediaSummary.jamTrackOpen || mediaSummary.jamTrack? || jamTrackState?.jamTrack?
        controls.startMonitor(PLAYBACK_MONITOR_MODE.JAMTRACK)
      else if mediaSummary.backingTrackOpen
        controls.startMonitor(PLAYBACK_MONITOR_MODE.MEDIA_FILE)
      else if mediaSummary.metronomeOpen
        controls.startMonitor(PLAYBACK_MONITOR_MODE.METRONOME)
      else if mediaSummary.recordingOpen
        controls.startMonitor(PLAYBACK_MONITOR_MODE.MEDIA_FILE)
      else
        logger.debug("unable to determine mediaOpen type", mediaSummary)
        controls.startMonitor(PLAYBACK_MONITOR_MODE.MEDIA_FILE)
    else
      controls.stopMonitor()

  metronomePlaybackModeChanged: (e, data) ->

    mode = data.playbackMode # will be either 'self' or 'cricket'

    logger.debug("setting metronome playback mode: ", mode)
    isCricket = mode == 'cricket';
    SessionActions.metronomeCricketChange(isCricket)


  onMetronomeChanged: () ->

    @setMetronomeFromForm()

  setMetronomeFromForm: () ->
    $root = jQuery(this.getDOMNode())
    tempo = $root.find("select.metro-tempo:visible option:selected").val()
    sound = $root.find("select.metro-sound:visible option:selected").val()

    t = parseInt(tempo)
    s = null
    if  tempo == NaN || tempo == 0 || tempo == null
      t = 120

    if sound == null || typeof(sound)=='undefined' || sound == ""
      s = "Beep"
    else
      s = sound

    logger.debug("Setting tempo and sound:", t, s)
    MixerActions.metronomeChanged(t, s, 1, 0)

  render: () ->


    tempo_options = []
    for tempo in @tempos
      tempo_options.push(`<option value={tempo}>{tempo}</option>`)

    `<div className="media-controls has-mix">

      <div className="jam-track-get-ready">
        <div className="spinner-small"></div>
        <span>Get Ready!</span>
      </div>

      <div className="play-buttons">
        <a className="play-button" href="#">
          <img src="/assets/content/icon_playbutton.png" width="20" height="20" className="playbutton" />
          <img src="/assets/content/icon_pausebutton.png" width="20" height="20" className="pausebutton" />
        </a>
        <a className="stop-button" href="#">
          <img src="/assets/content/icon_stopbutton.png" width="20" height="20" className="stopbutton" />
        </a>
      </div>

      <div className="metronome-playback-options">
        <span id="metronome-playback-select"></span>
      </div>

      <div className="metronome-options">
        <div className="metronome-selects">
          <div class="metronome-field">
            <select className="metronome-select metro-sound" title="Metronome Sound" name="metronome_sound">
              <option value="Beep">Knock</option>
              <option value="Click">Tap</option>
              <option value="Snare">Snare</option>
              <option value="Kick">Kick</option>
            </select>
            <label htmlFor="metronome_sound">Sound:</label>
          </div>
          <div class="metronome-field">
            <select className="metronome-select metro-tempo" title="Metronome Tempo" name="metronome_tempo">
              {tempo_options}
            </select>
            <label htmlFor="metronome_tempo">Tempo:</label>
          </div>
        </div>
      </div>

      <div className="recording-time start-time">{this.state.time}</div>
        <div className="recording-playback">
          <div className="recording-slider"><img src="/assets/content/slider_playcontrols.png" height="16" width="5" /></div>
        </div>
        <div className="recording-time duration-time">0:00</div>

      <div className="recording-current">0:00</div>

      <div className="playback-mode-buttons icheckbuttons">
        <input type="radio" name="playback-mode" defaultChecked="checked" value="preview-to-all" className="preview-to-all" /><label htmlFor="playback-mode-preview-all" className="radio-text">Preview to All</label>
        <input type="radio" name="playback-mode" value="preview-to-me" className="preview-to-me" /><label htmlFor="playback-mode-preview-me" className="radio-text">Preview Only to Me</label>
      </div>
    </div>`


  getInitialState: () ->
    {controls: null, mediaSummary: {}, initializedMetronomeControls: false, time: '0:00'}

  tryPrepareMetronome: (metro) ->
    if @state.mediaSummary.metronomeOpen && !@state.initializedMetronomeControls
      $root = jQuery(this.getDOMNode())
      $root.on("change", ".metronome-select", @onMetronomeChanged)
      $root.find('#metronome-playback-select').metronomePlaybackMode({positions:['bottom'], offsetParent:$('#minimal-container')}).on(EVENTS.METRONOME_PLAYBACK_MODE_SELECTED, @metronomePlaybackModeChanged)
      @updateMetronomeDetails(metro, true)
      @setState({initializedMetronomeControls: true})

  shouldComponentUpdate:() ->
    return !window.unloaded

  componentDidUpdate: (prevProps, prevState) ->
    @tryPrepareMetronome(@state.metro)

  componentDidMount: () ->


    $root = jQuery(this.getDOMNode())
    controls = context.JK.PlaybackControls($root, {mediaActions: MediaPlaybackActions})
    controls.setDisabled(@props.disabled)

    mediaSummary = MixerStore.mixers.mediaSummary
    metro = MixerStore.mixers.metro
    jamTrackState = JamTrackStore.getState()

    @monitorControls(controls, mediaSummary, jamTrackState)

    @tryPrepareMetronome(metro)

    @setState({mediaSummary: mediaSummary, controls: controls, metro: metro, jamTrackState: jamTrackState})

  componentWillUpdate: (nextProps) ->

    @state.controls.setDisabled(nextProps.disabled) if @state.controls?
})