# lastfmradio: ZOMG last.fm radio functions
#   Copyright (C) 2005, 2006, 2007, 2008  Clint Adams

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

lastfm_get_np() {
  local lastfm_session="$1" debug="$2"
  local -a np
  local station artist album track trackduration trackprogress

  np=(
  ${(f)"$(wget -q --output-document=- http://${baseurl}${basepath}/np.php\?session=${lastfm_session}\&debug=0)"}
  )

  if [[ $debug -eq 1 ]]; then
    print ">NP<"
    print "$np"
    print ">NP<"
  fi

  station=${${(M)np:#station=*}#station=}
  artist=${${(M)np:#artist=*}#artist=}
  album=${${(M)np:#album=*}#album=}
  track=${${(M)np:#track=*}#track=}
  trackduration=${${(M)np:#trackduration=*}#trackduration=}
  trackprogress=${${(M)np:#trackprogress=*}#trackprogress=}

  (( timeleft = trackduration - trackprogress ))

  print ""
  print "Station: ${station}"
  print "Artist: ${artist}"
  print "Album: ${album}"
  print "Track: ${track}"
  print "Length: ${trackduration} seconds"
  print ""

  if (( timeleft == 0 )); then (( timeleft = 10 )); fi
}

lastfm_quit() {
  if [[ -z "$BUFFER" ]]; then
    BUFFER="q"
    zle .accept-line
  fi
}

lastfm_tune() {
  local lastfm_session="$1" station="$2"
  local tunestatus

  print -n "Tuning to $station... "

  tunestatus=$(wget -q --output-document=- "http://${baseurl}${basepath}/adjust.php?session=${lastfm_session}&url=${station}&debug=0")

  print "$tunestatus"
}

lastfm_radio_getplaylist() {
  local session="$1"
  local i

  wget -q -O ~/.zomg/radio_playlist.xspf "http://ws.audioscrobbler.com/radio/xspf.php?sk=${session}&discovery=0&desktop=1.3.0.58" || return 99
  zomghelper-xspf ~/.zomg/radio_playlist.xspf > ~/.zomg/radio_playlist || return 98

  unset zomg_xspf_location zomg_xspf_title zomg_xspf_id zomg_xspf_album
  unset zomg_xspf_creator zomg_xspf_duration zomg_xspf_image

  for i in ${(f)"$(<~/.zomg/radio_playlist)"}
  do
    case "$i" in
      ((#b)([^=]##)\[([0-9]##)\]=(*))
      eval zomg_xspf_$match[1]\[$match[2]\]="${(q)match[3]}"
      ;;
      ((#b)([^=]##)=(*))
      eval zomg_xspf_$match[1]="${(q)match[2]}"
      ;;
      (*)
      ;;
    esac
  done

  if [[ -z $zomg_xspf_location ]]; then
    print Empty playlist, quitting.
    return 99
  fi

  print Parsed radio playlist $zomg_xspf_playlist_title by $zomg_xspf_playlist_creator.
  for i in {1..${#zomg_xspf_location}}
  do
    print $i. $zomg_xspf_creator[$i] / $zomg_xspf_title[$i]
  done
}

lastfm_playfive() {
  local lastfm_session="$1"

  lastfm_radio_getplaylist "$lastfm_session" || exit 99

  for currenttrack in {1..${#zomg_xspf_location}}
  do

  audioscrobbler_construct_np_query "$LASTFM_USER" "$sessionid" \
   "$zomg_xspf_creator[$currenttrack]" "$zomg_xspf_title[$currenttrack]" \
   "$zomg_xspf_album[$currenttrack]" "" \
   ${${zomg_xspf_duration[$currenttrack]}/000(#e)/} "$EPOCHSECONDS" && \
    audioscrobbler_np_submit ${(j::)reply} "$LASTFM_USER"

  print "Now playing $zomg_xspf_creator[$currenttrack] / $zomg_xspf_title[$currenttrack] / $zomg_xspf_album[$currenttrack]"

  starttime=$EPOCHSECONDS
#  "$mp3streamer[@]" $zomg_xspf_location[$currenttrack] >/dev/null 2>&1 &
  "$mp3streamer[@]" $zomg_xspf_location[$currenttrack]
  endtime=$EPOCHSECONDS

  skip=0
      (( endtime - starttime <= (${${zomg_xspf_duration[$currenttrack]}/000(#e)/} / 2.0 ) )) &&
      (( endtime - starttime < 240 )) && skip=1

      (( ${${zomg_xspf_duration[$currenttrack]}/000(#e)/} < 30 )) && skip=1

      if [[ $skip -eq 1 ]];
      then
	print "SKIPPING"
	skip=0
      else
  audioscrobbler_constructquery "$sessionid" \
   "$zomg_xspf_creator[$currenttrack]" "$zomg_xspf_title[$currenttrack]" \
   "$zomg_xspf_album[$currenttrack]" "" \
   "${${zomg_xspf_duration[$currenttrack]}/000(#e)/}" "$starttime" \
   L"$zomg_xspf_lastfm_trackauth[$currenttrack]" &&
	audioscrobbler_submit ${(j::)reply} "$LASTFM_USER" || { submit=0; audioscrobbler_cache "$reply[2]" }
      fi

      done

}

lastfm_radio() {
  local station="$1"
  local passwordmd5=${${="$(print -n $LASTFM_PASSWORD | md5sum)"}[1]}
  local -a handshake
  local lastfm_session streamurl radiocmd streamstate
  local baseurl basepath

  handshake=( ${(f)"$(wget -q --output-document=- http://ws.audioscrobbler.com/radio/handshake.php\?version=1.3.0.58\&platform=linux\&username=${LASTFM_USER}\&passwordmd5=${passwordmd5}\&language=en)"} )

  lastfm_session=${${(M)handshake:#session=*}#session=}
  streamurl=${${(M)handshake:#stream_url=*}#stream_url=}
  baseurl=${${${(M)handshake:#base_url=*}#base_url=}:-ws.audioscrobbler.com}
  basepath=${${${(M)handshake:#base_path=*}#base_path=}:-/radio}

  if [[ -n "$lastfm_session" && "$lastfm_session" != FAILED ]]; then
    print "Connecting to Last.fm session ${lastfm_session}"
    print "at $streamurl"
  else
    print "Handshake failed"
    exit 47

  fi

  if [[ -n "$station" && "$station" == lastfm://* ]]; then

    lastfm_tune $lastfm_session $station

  fi

  unset HISTFILE
  HISTSIZE=512
  SAVEHIST=512
  setopt histignorealldups
  history -ap ~/.zomg/lastfm_history

  if [[ -x =mpg123 ]]; then
    mp3streamer=(mpg123 -b 2048 -q)
  else
    mp3streamer=(mplayer -quiet -noconsolecontrols -cache 2048 -cache-min 1)
  fi

  lastfm_playfive "$lastfm_session"
  print "Either tune to a new station or type 'p' to play a few more songs."

  zle -N lastfm_quit
  bindkey '^D' lastfm_quit
  autoload -U compinit
  compinit
  bindkey '^I' _history-complete-older

  while true
  do
    [[ $#jobstates -eq 1 ]] && streamstate="" || streamstate="[broken] "

    radiocmd=""
    vared -hp "${streamstate}last.fm $LASTFM_USER $timeleft> " radiocmd
    print -s $radiocmd

    case "$radiocmd" in
      (h)
      print "h: help"
#      print "n: show what's playing now"
      print "q: quit"
#      print "s: skip"
      print "p: play another five songs from the same station"
      print "t lastfm://<station> : tune to another radio station"
      print "tu <lastfm user> : shortcut to tune to lastfm://user/<user>/personal"
      print "tl <lastfm user> : shortcut to tune to lastfm://user/<user>/loved"
      print "tn <lastfm user> : shortcut to tune to lastfm://user/<user>/neighbours"
#      print "love: mark this track as loved"
#      print "ban: ban this track"
#      print "discovery <on/off>: turn discovery mode on or off"
#      print "rtp: turn scrobbling on"
#      print "nortp: turn scrobbling off"
      ;;
#      (n)
#      lastfm_get_np "${lastfm_session}" 0
#      ;;
#      (ndebug)
#      lastfm_get_np "${lastfm_session}" 1
#      ;;
      (q|exit)
      kill %2
      exit 0
      ;;
#      (s)
#      print "Skipping... " $(wget -q --output-document=- "http://${baseurl}${basepath}/control.php?session=${lastfm_session}&command=skip&debug=0")
#      lastfm_get_np "${lastfm_session}" 0
#      ;;
      (p)
      lastfm_playfive "${lastfm_session}"
      ;;
      (t (#b)(lastfm://[^ ]##))
      lastfm_tune ${lastfm_session} $match[1]
      lastfm_playfive "${lastfm_session}"
#      lastfm_get_np "${lastfm_session}" 0
      ;;
      (tu (#b)([^ ]##))
      lastfm_tune ${lastfm_session} lastfm://user/$match[1]/personal
      lastfm_playfive "${lastfm_session}"
#      lastfm_get_np "${lastfm_session}" 0
      ;;
      (tl (#b)([^ ]##))
      lastfm_tune ${lastfm_session} lastfm://user/$match[1]/loved
      lastfm_playfive "${lastfm_session}"
#      lastfm_get_np "${lastfm_session}" 0
      ;;
      (tn (#b)([^ ]##))
      lastfm_tune ${lastfm_session} lastfm://user/$match[1]/neighbours
      lastfm_playfive "${lastfm_session}"
#      lastfm_get_np "${lastfm_session}" 0
      ;;
#      (love)
#      print "Loving... " $(wget -q --output-document=- "http://${baseurl}${basepath}/control.php?session=${lastfm_session}&command=love&debug=0")
#      ;;
#      (ban)
#      print "Banning... " $(wget -q --output-document=- "http://${baseurl}${basepath}/control.php?session=${lastfm_session}&command=ban&debug=0")
#      ;;
#      (discovery (#b)(on|off))
#      print "Turning discovery ${match[1]}..." $(wget -q --output-document=- "http://${baseurl}${basepath}/adjust.php?session=${lastfm_session}&url=lastfm://settings/discovery/${match[1]}&debug=0")
#      ;;
#      ((#b)(rtp|nortp))
#      print "Setting ${match[1]}..." $(wget -q --output-document=- "http://${baseurl}${basepath}/control.php?session=${lastfm_session}&command=${match[1]}")
#      ;;
      (*)
      print "WTF?! Try 'h' for help"
      ;;

    esac
  done

}
