Property definitions

mpd $ MPDConnection :: defaultinit
# Connection to a MPD server
class MPDConnection

	# Socket connection to server.
	var socket: nullable TCPStream = null

	# Server hostname.
	var host: String

	# Server port.
	var port: Int

	# Server password.
	var password: nullable String

	# Last occured error.
	var error: nullable String = null

	# Connect to the MPD server
	fun connect
	do
		var p: nullable TCPStream = null

		p = new TCPStream.connect(host, port)
		assert p.connected

		sys.nanosleep(0,5000)

		var rep = p.read(1024)
		assert not rep.is_empty
		if not rep.has_prefix("OK") then
			print "MPD responded {rep}"
			abort
		end

		socket = p

		var password = password
		if password != null then
			write_and_check("password {password}\n")
		end
	end

	# Write a command to the MPD server
	protected fun write_and_check(msg: String)
	do
		if socket == null then connect

		socket.write(msg)
		sys.nanosleep(0,5000)
		var rep = socket.read(1024)
		if not rep.has_prefix("OK") then
			print "Error: MPD responded {rep}"
			socket.close
			socket = null
		end
	end

	# Get MPD server status
	fun status: nullable ServerStatus
	do
		if socket == null then connect

		var volume: nullable Int = null
		var state: nullable String = null
		var elapsed: nullable Int = null
		var time_at: nullable Int = null
		var time_total: nullable Int = null

		# get current status
		socket.write("status\n")
		var rep = socket.read(1024)
		for l in rep.split_with("\n") do
			var words = l.split_with(" ")
			if words.length > 1 then
				var key = words[0].to_lower
				var first_space = l.chars.index_of(' ')
				var rest = l.substring_from(first_space+1)
				if  key == "volume:" then
					volume = rest.to_i
					if volume == -1 then volume = null
				else if  key == "state:" then
					state = rest
				else if  key == "elapsed:" then
					elapsed = rest.to_i
				else if  key == "time:" then
					var times = rest.split(":")
					time_at = times[0].to_i
					time_total = times[1].to_i
				end
			end
		end

		if state != null then
			var status = new ServerStatus(volume, state, elapsed, time_at, time_total)
			return status
		else
			return null
		end
	end

	# Set the volume relatively
	fun relative_volume=(diff: Int)
	do
		if socket == null then connect

		var status = status
		if status != null then
			var vol = status.volume
			if vol != null then
				var new_vol = vol + diff
				new_vol = new_vol.clamp(0, 100)
				volume = new_vol
				return
			end
		end

		error = "Cannot get volume"
	end

	# Set MPD server volume.
	fun volume=(vol: Int) do write_and_check("setvol {vol}\n")

	# Pause music playing on the MPD server
	fun pause do write_and_check("pause\n")

	# Stop music playing on the MPD server
	fun stop do write_and_check("stop\n")

	# Play music playing on the MPD server
	fun play do write_and_check("play\n")

	# Get information on the currently playing song on the MPD server
	fun current_song: nullable SongInfo
	do
		if socket == null then connect

		var album: nullable String = null
		var artist: nullable String = null
		var title: nullable String = null
		var time: nullable Int = null

		socket.write("currentsong\n")
		var rep = socket.read(1024)
		for l in rep.split_with("\n") do
			var words = l.split_with(" ")
			if words.length > 1 then
				var key = words[0].to_lower
				var first_space = l.chars.index_of(' ')
				var rest = l.substring_from(first_space+1)
				if key == "album:" then
					album = rest
				else if key == "artist:" then
					artist = rest
				else if key == "title:" then
					title = rest
				else if key == "time:" then
					time = rest.to_i
				end
			end
		end

		if album != null and artist != null and
			title != null and time != null then
			return new SongInfo(album, artist, title, time)
		else
			return null
		end
	end

	# Load playlist named `name`.
	fun load_playlist(name: String)
	do
		write_and_check "load \"{name}\""
	end
end
lib/mpd/mpd.nit:22,1--197,3