# imms <-> mpd coupler

require 'histqueue'
require 'imms'

class IMMS_MPD
  attr_accessor :imms_sel, :histqueue

  def initialize rel_path, xidle = true
    @mpd_path = rel_path

    @histqueue = HistQueue.new
    @histqueue.register self

    @imms = IMMS.new xidle
    @imms.log "#{ENV['HOME']}/.imms_mpd.log"
    @imms.register self

    send_playlist_length

    end_playlist unless @histqueue.mpd.status["song"]
    @imms.selectNext if @histqueue.last_song?
  end

  def join
    @histqueue.join
  end

  ### imms callbacks

  def send_song x
    x = x.to_i
    @imms.playlistItem x, File.join(@mpd_path, @list[x])
  end
  def send_playlist
    puts "sending playlist: #{File.join @mpd_path, @list.first}"
    @imms.updatePlaylist @list.map{|x| File.join @mpd_path, x}
  end
  def send_playlist_length
    @list = @histqueue.mpd.listall
    puts "sending playlist length: #{@list.length}"
    @imms.playlistChanged @list.length
  end
  def enqueue x
    @imms_sel = @list[x.to_i]
    puts "imms chose: #{@imms_sel}"
    if @resume_now
      puts "imms enqueue: resuming"
      @resume_now = false
      end_playlist
    end
  end
  def try_again
    @imms.selectNext
  end
  def cancel_selection
    puts "cancel #{@imms_sel}" if imms_sel
    @imms_sel = nil
    @imms.selectNext
    puts "canceled"
  end

  ### histqueue callbacks

  def song_change cur, last # current and last statuses
    puts "song_change"
    if last["state"] == "play" # send endSong
      times = last["time"].split(":").map {|t| t.to_i}
      skip = (times[1] - times[0]) > 2
      current = @histqueue.current_song
      jump = (cur["state"] != "stop" and current and current.file != @last)
      puts "endSong #{!skip}, #{jump}"
      @imms.endSong !skip, jump
      end_playlist if cur["state"] == "stop"
    end
    if cur["state"] != "stop" # send startSong
      puts "startSong"
      file = @histqueue.current_song.file
      puts file
      index = @list.rindex file
      @imms.startSong index, File.join(@mpd_path, @list[index])
    end

    @imms.selectNext if @histqueue.last_song?
  end
  def end_playlist
    puts "end_playlist"
    unless @imms_sel
      @imms.selectNext
      @resume_now = true
    else
      @histqueue.enqueue @imms_sel
      @imms_sel = nil
      @histqueue.resume
    end
  end
end

if __FILE__ == $0
  imms_mpd = IMMS_MPD.new "/var/lib/mpd/music"
  qlen = ARGV[0].to_i
  imms_mpd.histqueue.hist_length = qlen
  sleep 5 # give a chance for imms to come up to speed
  imms_mpd.join
end
