context = window
logger = context.JK.logger
ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
rest = context.JK.Rest()

mixins = []


# make sure this is actually us opening the window, not someone else (by checking for MixerStore)
# 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

if true # /iPhone|iPad|iPod|android/i.test(navigator.userAgent)
  # iPad or iPhone
  reactContext = window

AppActions = reactContext.AppActions
JamTrackPlayerActions = reactContext.JamTrackPlayerActions
JamTrackPlayerStore = reactContext.JamTrackPlayerStore
UserStore = reactContext.UserStore

mixins.push(Reflux.listenTo(JamTrackPlayerStore, 'onJamTrackPlayerStoreChanged'))
mixins.push(Reflux.listenTo(UserStore, 'onUserChanged'))


@PopupJamTrackPlayer = React.createClass({

  mixins: mixins

  computeWeight: (jam_track_track) ->
    weight = switch
      when jam_track_track.track_type == 'Master' then 0
      when jam_track_track.track_type == 'Click' then 10000
      else
        jam_track_track.position

  onJamTrackPlayerStoreChanged: (changes) ->
    #logger.debug("PopupMediaControls: jamtrack changed", changes)
    @setState({jamTrackState: changes})

  onUserChanged: (changes) ->
    @setState({user: changes.user})

  showMetronome: (e) ->
    e.preventDefault()

    SessionActions.showNativeMetronomeGui()

  getInitialState: () ->
    state = {}
    state.jamTrackState = JamTrackPlayerStore.getState()
    state.showCustomMixes = true
    state.showMyMixes = true
    state.user = UserStore.getState().user
    return state

  close: () ->
    window.close()

  help: (e) ->
    e.preventDefault()

    AppActions.openExternalUrl($(e.target).attr('href'))

  render: () ->
    closeLinkText = null
    header = null
    extraControls = null

    jamTrack = @state.jamTrackState?.jamTrack
    mediaType = "JamTrack"
    mediaName = jamTrack?.name
    closeLinkText = 'CLOSE JAMTRACK'
    helpLink = 'https://jamkazam.desk.com/customer/portal/articles/2138903-using-custom-mixes-to-slow-tempo-change-pitch'

    selectedMixdown = jamTrack?.activeMixdown
    selectedStem = jamTrack?.activeStem

    if selectedMixdown?
      jamTrackTypeHeader = 'Custom Mix'

      disabled = true
      if selectedMixdown.client_state?
        switch selectedMixdown.client_state
          when 'download_fail'
            customMixName = `<h5>{selectedMixdown.name}<img src="/assets/content/icon-mix-fail@2X.png"/></h5>`
          when 'downloading'
            customMixName = `<h5>Loading selected mix... <img src="/assets/shared/spinner.gif"/></h5>`
          when 'ready'
            customMixName = `<h5>{selectedMixdown.name}</h5>`
            disabled = false
      else
        if selectedMixdown.myPackage
          customMixName = `<h5>Creating mixdown... <img src="/assets/shared/spinner.gif"/></h5>`
        else
          customMixName = `<h5>{selectedMixdown.name}<img src="/assets/content/icon-mix-fail@2X.png"/></h5>`

    else if selectedStem?
      if selectedStem.instrument
        instrumentId = selectedStem.instrument.id
        instrumentDescription = selectedStem.instrument.description
        part = "(#{selectedStem.part})" if selectedStem.part? && selectedStem.part != instrumentDescription
        part = '' unless part

      jamTrackTypeHeader = 'Track'

      trackName = "#{instrumentDescription} #{part}"

      disabled = true
      if selectedStem.client_state?
        switch selectedStem.client_state
          when 'downloading'
            customMixName = `<h5>Loading {trackName}... <img src="/assets/shared/spinner.gif"/></h5>`
          when 'download_fail'
            customMixName = `<h5>{trackName}<img src="/assets/content/icon-mix-fail@2X.png"/></h5>`
          when 'ready'
            customMixName = `<h5>{trackName}</h5>`
            disabled = false
      else
        customMixName = `<h5>{trackName}<img src="/assets/content/icon-mix-fail@2X.png"/></h5>`

    else
      if jamTrack?.client_state == 'downloading'
        downloader = `<img src="/assets/shared/spinner.gif"/>`
      else if jamTrack?.client_state == 'download_fail'
        downloader = `<img src="/assets/content/icon-mix-fail@2X.png"/>`

      jamTrackTypeHeader = `<span>Full JamTrack {downloader}</span>`

    header = `
      <div className="header">
        <h3>{mediaType}: {mediaName}</h3>
        <h4>{jamTrackTypeHeader}</h4>
        {customMixName}
      </div>`

    myMixes = null
    if @state.showMyMixes

      if jamTrack?
        myMixdowns = []

        boundPlayClick = this.jamTrackPlay.bind(this, jamTrack);
        boundDownloadClick = this.jamTrackDownload.bind(this, jamTrack);

        active = jamTrack.last_mixdown_id == null && jamTrack.last_stem_id == null

        myMixdowns.push `
          <div key="full-track"
               className={classNames({'full-track': true, 'mixdown-display': true, 'active' : active})}>
            <div className="mixdown-name">
              Full JamTrack
            </div>
            <div className="mixdown-actions">
              <img src="/assets/content/icon_open@2X.png" className="mixdown-play" onClick={boundPlayClick}/>
              <a href={this.createJamTrackUrl(jamTrack)} target="_blank" onClick={boundDownloadClick}><img
                src="/assets/content/icon_download@2X.png" className="mixdown-download"/></a>
              <img src="/assets/content/icon-delete@2X.png" style={{visibility:'hidden'}} className="mixdown-edit"
                   onClick={false}/>
              <img src="/assets/content/icon-delete@2X.png" style={{visibility:'hidden'}} className="mixdown-delete"
                   onClick={false}/>
            </div>
          </div>`

        for mixdown in jamTrack.mixdowns
          boundPlayClick = this.mixdownPlay.bind(this, mixdown);
          boundEditClick = this.mixdownEdit.bind(this, mixdown);
          boundSaveClick = this.mixdownSave.bind(this, mixdown);
          boundDeleteClick = this.mixdownDelete.bind(this, mixdown);
          boundErrorClick = this.mixdownError.bind(this, mixdown);
          boundEditKeydown = this.onEditKeydown.bind(this, mixdown);

          boundDownloadNotReadyClick = this.downloadNotReady.bind(this, mixdown)
          boundDownloadReadyClick = this.downloadMixdownReady.bind(this, mixdown)

          mixdown_package = mixdown.myPackage

          active = mixdown.id == jamTrack?.last_mixdown_id

          editing = mixdown.id == @state.editingMixdownId

          # if there is a package, check it's state; otherwise let the user enqueue it
          if mixdown_package
            switch mixdown_package.signing_state
              when 'QUIET_TIMEOUT'
                action = `<img src="/assets/content/icon-mix-fail@2X.png" className="mixdown-play"
                               onClick={boundErrorClick}/>`
              when 'QUIET'
                action = `<img src="/assets/shared/spinner.gif" className="mixdown-play"/>`
              when 'QUEUED'
                action = `<img src="/assets/shared/spinner.gif" className="mixdown-play"/>`
              when 'QUEUED_TIMEOUT'
                action = `<img src="/assets/content/icon-mix-fail@2X.png" className="mixdown-play"
                               onClick={boundErrorClick}/>`
              when 'SIGNING'
                action = `<img src="/assets/shared/spinner.gif" className="mixdown-play"/>`
              when 'SIGNING_TIMEOUT'
                action = `<img src="/assets/content/icon-mix-fail@2X.png" className="mixdown-play"
                               onClick={boundErrorClick}/>`
              when 'SIGNED'
                action = `<img src="/assets/content/icon_open@2X.png" className="mixdown-play"
                               onClick={boundPlayClick}/>`
              when 'ERROR'
                action = `<img src="/assets/content/icon-mix-fail@2X.png" className="mixdown-play"
                               onClick={boundErrorClick}/>`
          else
            action = `<img src="/assets/content/icon-mix-fail@2X.png" className="mixdown-play"
                           onClick={boundErrorClick}/>`

          if editing
            mixdownName = `<input className="edit-name" type="text" defaultValue={mixdown.name}
                                  onKeyDown={boundEditKeydown}/>`
            editIcon = `<img src="/assets/content/icon-save@2X.png" className="mixdown-edit" onClick={boundSaveClick}/>`
          else
            mixdownName = mixdown.name
            editIcon = `<img src="/assets/content/icon-edit@2X.png" className="mixdown-edit" onClick={boundEditClick}/>`

          # create hidden objects to deal with alginment issues using a table
          if !editIcon
            editIcon = `<img src="/assets/content/icon-delete@2X.png" style={{visibility:'hidden'}}
                             className="mixdown-edit" onClick={false}/>`

          download = `<a onClick={boundDownloadReadyClick} href={this.downloadMixdownUrl(mixdown)} target="_blank"><img
            src="/assets/content/icon_download@2X.png" className="mixdown-download"/></a>`

          myMixdowns.push `
            <div key={mixdown.id} className={classNames({'mixdown-display': true, 'active' : active})}>
              <div className="mixdown-name">
                {mixdownName}
              </div>
              <div className="mixdown-actions">
                {action}
                {download}
                {editIcon}

                <img src="/assets/content/icon-delete@2X.png" className="mixdown-delete" onClick={boundDeleteClick}/>
              </div>
            </div>`

        active = jamTrack.last_stem_id?
        trackOptions = []

        jamTrack.tracks.sort((a, b) =>
          aWeight = @computeWeight(a)
          bWeight = @computeWeight(b)
          return aWeight - bWeight
        )


        for track in jamTrack.tracks
          if track.track_type == 'Track' || track.track_type == 'Click'

            if track.instrument
              instrumentId = track.instrument.id
              instrumentDescription = track.instrument.description
              if track.part? && track.part != instrumentDescription
                part = "(#{track.part})"
              else
                part = ''
            trackOptions.push(`<option key={track.id} value={track.id}>{instrumentDescription} {part}</option>`)

        boundStemActivateClick = this.activateStem.bind(this)
        boundStemPlayClick = this.downloadStem.bind(this)
        boundStemChange = this.stemChanged.bind(this)

        myMixdowns.push `
          <div key={track.id} className={classNames({'stem-track' : true, 'mixdown-display': true, 'active' : active})}>
            <div className="mixdown-name">
              <select className="active-stem-select" name="active-stem-select" onChange={boundStemChange}
                      defaultValue={jamTrack.last_stem_id}>
                <option key="null" value="">or select a track</option>
                {trackOptions}
              </select>
            </div>
            <div className="mixdown-actions">
              <img src="/assets/content/icon_open@2X.png" className="mixdown-play" onClick={boundStemActivateClick}/>
              <a href={this.createStemUrl(jamTrack.id, jamTrack.last_stem_id)} target="_blank"
                 onClick={boundStemPlayClick}><img src="/assets/content/icon_download@2X.png"
                                                   className="mixdown-download"/></a>
              <img src="/assets/content/icon-delete@2X.png" style={{visibility:'hidden'}} className="mixdown-edit"
                   onClick={false}/>
              <img src="/assets/content/icon-delete@2X.png" style={{visibility:'hidden'}} className="mixdown-delete"
                   onClick={false}/>
            </div>
          </div>`

        myMixes = `<div key="my-mixes" className="my-mixes">{myMixdowns}</div>`
      else
        # nothing

    mixControls = null

    if @state.showCustomMixes

      tracks = []
      if jamTrack?
        for track in jamTrack.tracks
          if track.track_type == 'Track' || track.track_type == 'Click'
            if track.track_type == 'Click'
              instrumentId = track.instrument.id
              instrumentDescription = 'Clicktrack'
              part = ''
            else if track.instrument
              instrumentId = track.instrument.id
              instrumentDescription = track.instrument.description
              if track.part? && track.part != instrumentDescription
                part = "(#{track.part})"
              else
                part = ''


            tracks.push(`
              <tr className="stem">
                <td><img src={context.JK.getInstrumentIcon24(instrumentId)}
                         className="instrument-icon"/> {instrumentDescription} {part}</td>
                <td className="mute"><input type="checkbox" className="stem-mute" data-stem-id={track.id}
                                            defaultChecked={track.track_type == 'Click'}/></td>
              </tr>`)

        if jamTrack?.jmep?.Events? && jamTrack.jmep.Events[0].metronome?
          # tap-in detected; show user tap-in option
          tracks.push(`
            <tr className="stem">
              <td><img src={context.JK.getInstrumentIcon24('computer')} className="instrument-icon"/> Count-in</td>
              <td className="mute"><input type="checkbox" className="stem-mute" data-stem-id="count-in"/></td>
            </tr>`)

      stems = `<div key="stems" className="stems">
        <table>
          <thead>
          <col align="left"/>
          <col align="right"/>
          <tr>
            <th>TRACKS</th>
            <th className="mute">mute</th>
          </tr>
          </thead>
          <tbody>
          {tracks}
          </tbody>
        </table>
      </div>`


      nameClassData = {field: true}
      if @state.createMixdownErrors?

        errorHtml = context.JK.reactErrors(@state.createMixdownErrors,
          {name: 'Mix Name', settings: 'Settings', jam_track: 'JamTrack'})

      createMixClasses = classNames({'button-orange': true, 'create-mix-btn': true, 'disabled': @state.creatingMixdown})

      mixControls = `
        <div key="create-mix" className="create-mix">
          <p>Mute or unmute any tracks you like. You can also use the controls below to adjust the tempo or pitch of the
            JamTrack. Then give your custom mix a name, and click the Create Mix button.</p>
          {stems}
          <div className="field">
            <label>TEMPO</label>
            <select name="mix-speed">
              <option value="">No change</option>
              <option value="separator-1">------------</option>
              <option value="-5">Slower by 5%</option>
              <option value="-10">Slower by 10%</option>
              <option value="-15">Slower by 15%</option>
              <option value="-20">Slower by 20%</option>
              <option value="-25">Slower by 25%</option>
              <option value="-30">Slower by 30%</option>
              <option value="-35">Slower by 35%</option>
              <option value="-40">Slower by 40%</option>
              <option value="-45">Slower by 45%</option>
              <option value="-50">Slower by 50%</option>
              <option value="-60">Slower by 60%</option>
              <option value="-70">Slower by 70%</option>
              <option value="-80">Slower by 80%</option>
              <option value="separator-2">------------</option>
              <option value="5">Faster by 5%</option>
              <option value="10">Faster by 10%</option>
              <option value="15">Faster by 15%</option>
              <option value="20">Faster by 20%</option>
              <option value="30">Faster by 30%</option>
              <option value="40">Faster by 40%</option>
              <option value="50">Faster by 50%</option>
            </select>
          </div>
          <div className="field">
            <label>PITCH</label>
            <select name="mix-pitch">
              <option value="">No change</option>
              <option value="separator-1">---------------</option>
              <option value="-1">Down 1 Semitone</option>
              <option value="-2">Down 2 Semitones</option>
              <option value="-3">Down 3 Semitones</option>
              <option value="-4">Down 4 Semitones</option>
              <option value="-5">Down 5 Semitones</option>
              <option value="-6">Down 6 Semitones</option>
              <option value="-7">Down 7 Semitones</option>
              <option value="-8">Down 8 Semitones</option>
              <option value="-9">Down 9 Semitones</option>
              <option value="-10">Down 10 Semitones</option>
              <option value="-11">Down 11 Semitones</option>
              <option value="-12">Down 12 Semitones</option>
              <option value="separator-2">---------------</option>
              <option value="1">Up 1 Semitone</option>
              <option value="2">Up 2 Semitones</option>
              <option value="3">Up 3 Semitones</option>
              <option value="4">Up 4 Semitones</option>
              <option value="5">Up 5 Semitones</option>
              <option value="6">Up 6 Semitones</option>
              <option value="7">Up 7 Semitones</option>
              <option value="8">Up 8 Semitones</option>
              <option value="9">Up 9 Semitones</option>
              <option value="10">Up 10 Semitones</option>
              <option value="11">Up 11 Semitones</option>
              <option value="12">Up 12 Semitones</option>
            </select>
          </div>
          <div className={classNames(nameClassData)}>
            <label>MIX NAME</label>
            <input type="text" name="mix-name"/>
          </div>
          <div className="field">
            <a className={createMixClasses} onClick={this.createMix}>CREATE MIX</a>
            {errorHtml}
          </div>
          <div className="clearall"/>

        </div>`


    if @state.showMyMixes
      showMyMixesText = `<a className="show-hide-my-mixes" onClick={this.toggleMyMixes}>hide my mixes
        <div className="details-arrow arrow-up"/>
      </a>`
    else
      showMyMixesText = `<a className="show-hide-my-mixes" onClick={this.toggleMyMixes}>show my mixes
        <div className="details-arrow arrow-down"/>
      </a>`

    if @state.showCustomMixes
      showMixControlsText = `<a className="show-hide-mix-controls" onClick={this.toggleCustomMixes}>hide mix controls
        <div className="details-arrow arrow-up"/>
      </a>`
    else
      showMixControlsText = `<a className="show-hide-mix-controls" onClick={this.toggleCustomMixes}>show mix controls
        <div className="details-arrow arrow-down"/>
      </a>`

    extraControls = `
      <div className="extra-controls">
        <h4>My Mixes {showMyMixesText}</h4>
        <ReactCSSTransitionGroup transitionName="session-track-list" transitionAppear={true}>
          {myMixes}
        </ReactCSSTransitionGroup>
        <h4 className="custom-mix-header">Create Custom Mix {showMixControlsText}</h4>
        <ReactCSSTransitionGroup transitionName="session-track-list" transitionAppear={false}>
          {mixControls}
        </ReactCSSTransitionGroup>
      </div>`


    if helpLink?
      helpButton = `<a className="help-link button-grey" href={helpLink} target="_blank">HELP</a>`

    `<div className="jamtrack-player-main">
      <div className="jamtrack-player-controls">
      <div className="media-header">
        jamtracks web player
      </div>
      <div className="media-controls-popup">
        {header}
        <BrowserMediaControls disabled={this.disableLoading}/>
        {extraControls}
        <div className="actions">
          {helpButton}
        </div>
      </div>
        </div>
      <div className="helpful-resources">
        <div className="helpful-header">
          helpful resources
        </div>
        <div className="helpful-section">
          <a href="https://jamkazam.freshdesk.com/support/solutions/articles/66000125795-using-jamtracks-in-a-browser" target="_blank">read a web player help article</a><br/>
          that explains how to use all the features of this web player
        </div>
        <div className="helpful-section">
          <a href="/client#/jamtrack" target="_blank">go to JamTracks homepage</a><br/>
          where you can access all of your JamTracks, search for more JamTracks, and more
        </div>
        <div className="helpful-section">
          <a href="https://itunes.apple.com/us/app/jamtracks/id1060927816?mt=8" target="_blank">download our free iOS app</a><br/>
          that you can use to play with your JamTracks on your iPhone, iPad, or iPod Touch
        </div>
        <div className="helpful-section">
          <a href="/downloads" target="_blank">download our free Mac or Windows app</a><br/>
          that gives you more powerful features to do more amazing things with your JamTracks
        </div>
        <div className="helpful-section">
          <a href="https://jamkazam.desk.com/customer/en/portal/articles/2126113-playing-your-jamtracks-in-our-free-windows-or-mac-app" target="_blank">review a list of help articles on the Mac/Win app</a><br/>
          to understand all the things you can do with our free desktop app
        </div>
        <div className="helpful-section">
          <a onClick={this.seeAllByArtist} target="_blank">see more JamTracks by this artist</a><br/>
          to check out other songs you might like
        </div>
        <div className="helpful-section">
          <a href="https://s3.amazonaws.com/jamkazam-public/public/lists/all-jamkazam-jamtracks.pdf" target="_blank">download our complete JamTracks catalog</a><br/>
          to browse or search through all the music we have in a convenient PDF file
        </div>
      </div>
    </div>`

  seeAllByArtist: (e) ->
    e.preventDefault()
    jamTrack = @state.jamTrackState?.jamTrack

    console.log("seeAllByArtist context", jamTrack)
    window.open('/client?artist=' + encodeURIComponent(jamTrack.original_artist) + '#/jamtrack/search')

  windowUnloaded: () ->
    JamTrackPlayerActions.windowUnloaded() unless window.DontAutoCloseMedia

  toggleMyMixes: (e) ->
    e.preventDefault()
    @setState({showMyMixes: !@state.showMyMixes})

  toggleCustomMixes: (e) ->
    e.preventDefault()


    @setState({showCustomMixes: !@state.showCustomMixes})

  downloadNotReady: (mixdown, e) ->
    alert("This mix is not yet ready to download.")
    e.preventDefault()

  verificationCheck: () ->
    if @state.user?.email_needs_verification
      alert("Check your email and click the verification link.  Refresh this page when done, and try again.")

    return @state.user?.email_needs_verification

  downloadMixdownReady: (mixdown, e) ->
    if @verificationCheck()
      e.preventDefault()
      return

    if mixdown.myPackage?.signing_state == 'SIGNED'
      if /iPhone|iPad|iPod/i.test(navigator.userAgent)
        # fall through
      else
        e.preventDefault()
        new window.Fingerprint2().get((result, components) => (
          iframe = document.createElement("iframe")
          iframe.src = @downloadMixdownUrl(mixdown, result)
          iframe.style.display = "none"
          document.body.appendChild(iframe);
        ))
    else
      alert("The mix is not yet ready to download")

  downloadMixdownUrl: (mixdown, result) ->
    window.location.protocol + '//' + window.location.host + "/api/mixdowns/#{mixdown.id}/download.mp3?file_type=mp3&sample_rate=48&download=1&mark=#{result}"

  activateStem: (e) ->
    e.preventDefault()

    return if @verificationCheck()

    $select = $(this.getDOMNode()).find('.active-stem-select')

    selectedTrackId = $select.val()

    if !selectedTrackId? || selectedTrackId == ''
      alert("You must pick a track from the dropdown in order to play it.")
    else
      @setState({editingMixdownId: null})

      e.preventDefault()

      if @disableLoading
        alert('Certain actions are disabled while a track is being loaded.')
        return

      # make this package the active one
      JamTrackPlayerActions.openStem(selectedTrackId)

  addUpgradeToCart: (jamtrack) ->
    console.log("adding upgrade to cart")

    params = {id: jamtrack.id, variant: 'download'}

    rest.addJamtrackToShoppingCart(params).done((response) =>
      console.log("added item to shopping cart.  fast_redeem? " + response.fast_redeem)
      if response.fast_reedem
        if context.JK.currentUserId?
          window.open('/client#/redeemComplete')
        else
          window.open('/client#/redeemSignup')
      else
        window.open('/client#/shoppingCart')

    ).fail(((jqxhr) =>

        handled = false
        if jqxhr.status == 422
          body = JSON.parse(jqxhr.responseText)
          if body.errors?.cart_id?[0] == 'has already been taken'
            console.log("already taken, just show shopping cart")
            window.open('/client#/shoppingCart')
            return
          else if body.errors && body.errors.base
            handled = true
            alert("You can not have a mix of free and non-free items in your shopping cart.\n\nIf you want to add this new item to your shopping cart, then clear out all current items by clicking on the shopping cart icon and clicking 'delete' next to each item.")
        if !handled
          alert("Error adding to shoppig cart. " + jqxhr.responseText)
      ))

  downloadStem: (e) ->
    if @verificationCheck()
      e.preventDefault()
      return

    $select = $(this.getDOMNode()).find('.active-stem-select')

    selectedTrackId = $select.val()

    if !@state.jamTrackState.jamTrack.can_download
      e.preventDefault()
      if confirm("You have not purchased the rights to download a JamTrack. Add them to your shopping cart?")
          @addUpgradeToCart(@state.jamTrackState.jamTrack)
      return

    if !selectedTrackId? || selectedTrackId == ''
      e.preventDefault()
      alert("You must select a track in order to download and also click the folder icon.")
    else
      if /iPhone|iPad|iPod/i.test(navigator.userAgent)
        if @state.jamTrackState.jamTrack?.last_stem_id
          # fall through
        else
          e.preventDefault()
          alert("You must select a track in order to download and also click the folder icon.")
      else
        e.preventDefault()

        try
          new window.Fingerprint2().get((result, components) => (
            iframe = document.createElement("iframe")
            iframe.src = @createStemUrl(@state.jamTrackState.jamTrack.id, selectedTrackId, result)
            iframe.style.display = "none"
            document.body.appendChild(iframe);
          ))
        catch error
          logger.error("not working: ", error)
          alert("Unable to download. Please try a different browser.")


  createStemUrl: (jamTrackId, stemId, result) ->
    window.location.protocol + '//' + window.location.host + "/api/jamtracks/#{jamTrackId}/stems/#{stemId}/download.mp3?file_type=mp3&download=1&mark=#{result}"

  stemChanged: () ->

  mixdownPlay: (mixdown, e) ->
    @setState({editingMixdownId: null})

    e.preventDefault()

    if @disableLoading
      alert('Certain actions are disabled while a track is being loaded.')
      return

    # make this package the active one
    JamTrackPlayerActions.openMixdown(mixdown)

  jamTrackPlay: (jamtrack, e) ->
    e.preventDefault()
    # user wants to select the full track

    if @disableLoading
      alert('Certain actions are disabled while a track is being loaded.')
      return

    JamTrackPlayerActions.activateNoMixdown(jamtrack)

  jamTrackDownload: (jamTrack, e) ->
    if @verificationCheck()
      e.preventDefault()
      return

    if !@state.jamTrackState.jamTrack.can_download
      e.preventDefault()
      if confirm("You have not purchased the rights to download a JamTrack. Add them to your shopping cart?")
        @addUpgradeToCart(@state.jamTrackState.jamTrack)

      return

    if /iPhone|iPad|iPod/i.test(navigator.userAgent)
      # fall through

    else
      e.preventDefault()

      new window.Fingerprint2().get((result, components) => (
        iframe = document.createElement("iframe")
        iframe.src = @createJamTrackUrl(jamTrack, result)
        iframe.style.display = "none"
        document.body.appendChild(iframe);
      ))

  createJamTrackUrl: (jamTrack, result) ->
    window.location.protocol + '//' + window.location.host + "/api/jamtracks/#{jamTrack.id}/stems/master/download.mp3?file_type=mp3&download=1&mark=#{result}"

  onEditKeydown: (mixdown, e) ->
    logger.debug("on edit keydown", e)
    if e.keyCode == 13 # enter
      @mixdownSave(mixdown, e)
    else if e.keyCode == 27 # esc
      @setState({editingMixdownId: null})

  mixdownEdit: (mixdown) ->
    @setState({editingMixdownId: mixdown.id})

  mixdownSave: (mixdown, e) ->
    e.preventDefault()
    $input = $(this.getDOMNode()).find('input.edit-name')
    newValue = $input.val()
    logger.debug("editing mixdown name to be: " + newValue)
    JamTrackPlayerActions.editMixdown({id: mixdown.id, name: newValue})
    @setState({editingMixdownId: null})

  mixdownDelete: (mixdown) ->
    if @state.editingMixdownId?
      @setState({editingMixdownId: null})
      return

    if confirm("Delete this custom mix?")
      JamTrackPlayerActions.deleteMixdown(mixdown)

  mixdownError: (mixdown) ->
    myPackage = mixdown.myPackage

    if myPackage?
      switch myPackage.signing_state
        when 'QUIET_TIMEOUT'
          action = 'Custom mix never got created.  Retry?'
        when 'QUEUED_TIMEOUT'
          action = 'Custom mix was never built. Retry?'
        when 'SIGNING_TIMEOUT'
          action = 'Custom mix took took long to build.  Retry?'
        when 'ERROR'
          action = 'Custom mix failed to build. Retry?'
    else
      action = 'Custom mix never got created. Retry?'

    return unless action?

    if confirm(action)
      JamTrackPlayerActions.enqueueMixdown(mixdown, @enqueueDone)

  enqueueDone: (enqueued) ->
    @promptEstimate(enqueued)

  promptEstimate: (enqueued) ->
    time = enqueued.queue_time

    if time == 0
      alert("Your custom mix will take about 1 minute to be created.")
    else
      guess = Math.ceil(time / 60.0)
      if guess == 1
        msg = '1 minute'
      else
        msg = "#{guess} minutes"
      alert("Your custom mix will take about #{msg} to be created.")


  createMix: (e) ->
    e.preventDefault()

    return if @state.creatingMix

    $root = $(@getDOMNode())

    name = $root.find('input[name="mix-name"]').val()
    speed = $root.find('select[name="mix-speed"]').val()
    pitch = $root.find('select[name="mix-pitch"]').val()

    if name == null || name == ''
      @setState({createMixdownErrors: {errors: {'Mix Name': ["can't be blank"]}}})
      return

    # sanitize junk out of speed/pitch
    if speed == '' || speed.indexOf('separator') > -1
      speed = undefined
    else
      speed = parseInt(speed)
    if pitch == '' || pitch.indexOf('separator') > -1
      pitch = undefined
    else
      pitch = parseInt(pitch)

    count_in = false

    # get mute state of all tracks
    $mutes = $(@getDOMNode()).find('.stems .stem .stem-mute')

    tracks = []
    $mutes.each((i, mute) =>
      $mute = $(mute)
      stemId = $mute.attr('data-stem-id')
      muted = $mute.is(':checked')

      if stemId == 'count-in'
        count_in = !muted
      else
        tracks.push({id: stemId, mute: muted})
    )

    mixdown = {
      jamTrackID: @state.jamTrackState.jamTrack.id,
      name: name,
      settings: {speed: speed, pitch: pitch, "count-in": count_in, tracks: tracks}
    }

    JamTrackPlayerActions.createMixdown(mixdown, @createMixdownDone, @createMixdownFail)

    @setState({creatingMixdown: true, createMixdownErrors: null})

  createMixdownDone: (created) ->
    logger.debug("created (within PopupMediaControls)", created)
    @setState({creatingMixdown: false, showCustomMixes: true, showMyMixes: true})

    @promptEstimate(created)

  createMixdownFail: (jqXHR) ->
    logger.debug("create mixdown fail (within PopupMediaControls)", jqXHR.status)
    @setState({creatingMixdown: false})
    if jqXHR.status == 422
      response = JSON.parse(jqXHR.responseText)
      logger.warn("failed to create mixdown", response, jqXHR.responseText)

    @setState({createMixdownErrors: response})

  fetchJamTrackInfo: () ->
    rest.getJamTrack({plan_code: gon.jamtrack_id})
    .done((response) =>
      JamTrackPlayerActions.open(response, false);
      @fetchUserInfo()
    )
    .fail((jqXHR) =>
      alert("Unable to fetch JamTrack information. Try logging in.")
    )

  fetchUserInfo: () ->
    rest.getUserDetail()
    .done((response) =>
      rest.postUserEvent({name: 'jamtrack_web_player_open'})
      context.stats.write('web.jamtrack_web_player.open', {
        value: 1,
        user_id: context.JK.currentUserId,
        user_name: context.JK.currentUserName
      })

      if !response.first_opened_jamtrack_web_player
        setTimeout((() =>
          logger.debug("first time user")
          rest.userOpenedJamTrackWebPlayer()
          $root = $(@getDOMNode())
          #context.JK.prodBubble($root.find('.create-mix-btn'), 'first-time-jamtrack-web-player', {}, {positions:['left'], offsetParent: $root})
        ), 1500)
    )



  componentDidMount: () ->
    $(window).unload(@windowUnloaded)

    @root = jQuery(this.getDOMNode())

    $loop = @root.find('input[name="loop"]')
    context.JK.checkbox($loop)

    $loop.on('ifChecked', () =>
      # it doesn't matter if you do personal or master, because backend just syncs both
      MixerActions.loopChanged(@state.media.backingTracks[0].mixers.personal.mixer, true)
    )
    $loop.on('ifUnchecked', () =>
      # it doesn't matter if you do personal or master, because backend just syncs both
      MixerActions.loopChanged(@state.media.backingTracks[0].mixers.personal.mixer, false)
    )

    @resizeWindow()

    # this is necessary due to whatever the client's rendering behavior is.
    setTimeout(@resizeWindow, 300)

    @fetchJamTrackInfo()

  componentDidUpdate: () ->
    @resizeWindow()
    setTimeout(@resizeWindow, 1000)

  resizeWindow: () =>
    return
    $container = $('#minimal-container')
    width = $container.width()
    height = $container.height()

    # there is 20px or so of unused space at the top of the page.   can't figure out why it's there. (above #minimal-container)
    #mysteryTopMargin = 20
    mysteryTopMargin = 0
    # deal with chrome in real browsers
    offset = (window.outerHeight - window.innerHeight) + mysteryTopMargin

    # handle native client chrome that the above outer-inner doesn't catch
    #if navigator.userAgent.indexOf('JamKazam') > -1

    #offset += 25

    window.resizeTo(450, height + offset)

  computeDisableLoading: (state) ->
    @disableLoading = false

    return unless nextState?

    selectedMixdown = state?.jamTrackState?.jamTrack?.activeMixdown

    mixdownDownloading = false
    if selectedMixdown?
      switch selectedMixdown.client_state
        when 'downloading'
          mixdownDownloading = true

    selectedStem = state?.jamTrackState?.jamTrack?.activeStem

    stemDownloading = false
    if selectedStem?
      switch selectedStem.client_state
        when 'downloading'
          stemDownloading = true

    @disableLoading = state?.jamTrackState?.jamTrack?.client_state == 'downloading' || mixdownDownloading || stemDownloading

  componentWillMount: () ->
    @computeDisableLoading(@state)

  componentWillUpdate: (nextProps, nextState) ->
    @computeDisableLoading(nextState)


})