# Bryan Schumaker (11/07/2010)

import libsaria
import libsaria.path.files

library = None
source  = None
rand    = None

song_list = []
song_set  = set(song_list)

filtered   = False
visible    = None
recent     = None
recent_msg = "Skipping %s by %s because it has played recently"
skip_msg   = "Skipping %s by %s because I don't think you like it"
cur_index  = None

def add_id(id):
	global song_list
	global song_set
	if id not in song_set:
		song_list.append(id)
		song_set.add(id)

def add_ids(ids):
	for id in ids:
		add_id(id)
	save()

def rm_id(id):
	song_list.remove(id)
	song_set.remove(id)

def rm_ids(ids):
	for id in ids:
		rm_id(id)
	save()

def init():
	global library
	global rand
	global source

	import library
	import random as rand
	source = libsaria.sources.Source()
	source.get_attrs  = library.get_attrs
	source.set_attr   = library.set_attr
	source.get_cur_id = get_cur_id
	source.save       = save

def reset():
	global song_list
	global song_set
	global recent
	global cur_index
	recent    = []
	song_list = []
	song_set  = set()
	cur_index = -1

def default_objects():
	return ([], [], -1)

def load():
	global song_list
	global song_set
	global recent
	global visible
	global cur_index
	objects = libsaria.storage.load_obj("playlist", default_objects)
	if objects == None or len(objects) != 3:
		reset()
	else:
		song_list = objects[0]
		recent    = objects[1]
		cur_index = objects[2]
		song_set  = set(song_list)
		if cur_index >= 0:
			libsaria.sources.cur_lib_id = song_list[cur_index]

def init_bg():
	init()
	load()

def startup():
	if cur_index >= 0:
		load_id(song_list[cur_index])

def save():
	libsaria.storage.save_obj("playlist", (song_list, recent, cur_index))

def walk():
	global song_list
	for id in song_list:
		yield id

def walk_playlist(*attrs):
	res = []
	for id in walk():
		res.append(library.get_attrs(id, *attrs))
	return res

def filter(text):
	global visible
	global song_set
	global filtered
	if len(text) > 0:
		visible  = song_set.intersection(library.test_filter(text))
		filtered = True
	else:
		visible  = song_set
		filtered = False

def is_visible(id):
	global visible
	global filtered
	if filtered == True:
		return id in visible
	return True

def num_visible():
	if filtered == True:
		return len(visible)
	return len(song_list)

def get_cur_id():
	return song_list[cur_index]

def seq_next():
	global cur_index
	global song_list
	cur_index += 1
	max_index  = len(song_list)
	if cur_index == max_index:
		cur_index = 0
	while is_visible(song_list[cur_index]) == False:
		cur_index += 1
		if cur_index == max_index:
			cur_index = 0
	return song_list[cur_index]

def rand_candidate(list, max):
	index = rand.randint(0, max-1)
	return list[index]

def rand_next():
	global cur_index
	n = num_visible()
	if n == 0:
		return
	get_attrs = library.get_attrs

	if filtered == False:
		selection = song_list
	else:
		selection = list(visible)

	for i in xrange(15):
		id = rand_candidate(selection, n)
		(artist, title, like) = get_attrs(id, "artist", "title", "like")
		if (artist, title) in recent:
			print recent_msg % (artist, title)
			continue
		if like == False:
			print skip_msg % (artist, title)
			continue
		if i > 0:
			print "Picking a song took %s iterations" % i
		cur_index = song_list.index(id)
		return id
	return id

def load_id(id):
	global cur_index
	cur_index = song_list.index(id)
	save()
	path = library.get_attrs(id, "filepath")
	return source.load_file(path)

def play_id(id):
	if load_id(id) == True:
		print "playing..."
		libsaria.controls.play()
		return True
	return False

def next():
	id = None
	if len(song_list) == 0:
		return
	if libsaria.prefs.get("libsaria.random") == True:
		id = rand_next()
	else:
		id = seq_next()
	if id != None:
		artist, title, file = library.get_attrs(id, "artist", "title", "filepath")
		recent.append((artist, title))
		if len(recent) > 50:
			recent.pop(0)
		source.set_current()
		save()
		return library.get_attrs(id, "filepath")
