local	CELL_PLAYLIST_GET_STATIONS = 0 
 
local CELL_PLAYLIST_GET_SONGS 	= 1 
 
 
 
local STATION_ID_KRUU = 1 
 
local STATION_ID_MAX	 = 2 
 
local STATION_ID_DEAD = 3 
 
 
 
local Station_data = {}  
local Playlist_data = {}  
 
 
List_left = -1 
 
List_right = -1 
 
List_active = -1 
 
 
 
local List_data_stations = {  
	[1] = {  
		id = STATION_ID_KRUU, 
 
		type = TYPE_BUTTON, 
 
		label = "KRUU 107.1", 
 
	}, 
 
	[2] = {  
		id = STATION_ID_MAX, 
 
		type = TYPE_BUTTON, 
 
		label = "MAX 97.5", 
 
	}, 
 
	[3] = {  
		id = STATION_ID_DEAD, 
 
		type = TYPE_BUTTON, 
 
		label = "DEADBOMB 89.1", 
 
	}, 
 
} 
 
local List_data_tracklist = {}   
 
 
local List_data_left = {}   
local List_data_right = {}  
local List_data_current_station = -1 
 
 
 
local List_data_left_is_empty 
 
local List_data_right_is_empty 
 
 
 
local LIST_FOCUS_LEFT 	= 1 
 
local LIST_FOCUS_RIGHT 	= 2 
 
 
 
local LIST_RIGHT_STATE_NAV		= 1 
 
local LIST_RIGHT_STATE_MOVING = 2 
 
 
 
local LIST_LEFT_STATE_STATION = 1 
 
local LIST_LEFT_STATE_TRACKLIST = 2 
 
 
 
local List_right_state  
 
local List_left_state  
 
 
 
local	Artist_name_text_h = -1 
 
local Track_name_text_h = -1 
 
 
 
 
 
List_data_right[1] = {  
	id = 20041, 
 
	type = TYPE_BUTTON, 
 
	label = "NO_", 
 
	track_id = 20041, 
 
} 
 
 
 
--Empty playlist default.. 
 
local List_data_no_playlist = {  
	[1] = {  
		id = -1, 
 
		type = TYPE_BUTTON, 
 
		label = "PLAYLIST_NO_ITEMS", 
 
		track_id = -1, 
 
	} 
 
}		 
 
 
 
--Empty playlist default.. 
 
local List_data_no_stationlist = {  
	[1] = {  
		id = -1, 
 
		type = TYPE_BUTTON, 
 
		label = "PLAYLIST_NO_STATION_ITEMS", 
 
		track_id = -1, 
 
	} 
 
}		 
 
 
 
local Input_tracker_left 
 
local Input_tracker_right  
 
local Hint_bar 
 
 
 
local Hint_bar_mouse_input_tracker 
 
local Mouse_input_tracker 
 
 
 
local LIST_SIZE = 400 
 
local LIST_ITEMS = 9 
 
local LIST_SCALE = .8 
 
local Cell_playlist_doc_h 
 
 
 
------------------------------------------------------------------------------- 
 
-- Menu hints... 
 
-- 
 
local Station_menu_hints = {  
	{CTRL_MENU_BUTTON_B, "MENU_BACK"},  
	{CTRL_MENU_BUTTON_A, "PLAYLIST_SELECT_STATION"},  
} 
 
local Song_menu_hints = {  
	{CTRL_MENU_BUTTON_B, "MENU_BACK"},  
	{CTRL_MENU_BUTTON_A, "PLAYLIST_ADD_TRACK"},  
} 
 
local Song_menu_empty_hints = {  
	{CTRL_MENU_BUTTON_B, "MENU_BACK"},  
} 
 
local Playlist_menu_hints = {  
	{CTRL_MENU_BUTTON_B, "MENU_BACK"},  
	{CTRL_MENU_BUTTON_A, "PLAYLIST_MOVE_TRACK"},  
	{CTRL_BUTTON_X, "PLAYLIST_REMOVE_TRACK", game_get_key_name(211)}, --"del"  
} 
 
local Playlist_menu_no_moving_hints = {  
	{CTRL_MENU_BUTTON_B, "MENU_BACK"},  
	{CTRL_BUTTON_X, "PLAYLIST_REMOVE_TRACK", game_get_key_name(211)}, --"del"  
} 
 
 
 
local Playlist_menu_move_hints = {  
	{CTRL_MENU_BUTTON_B, "MENU_BACK"},  
	{CTRL_MENU_BUTTON_A, "MENU_TITLE_CONFIRM"}  
} 
 
 
 
 
 
function cell_playlist_init() 
 
	local Cell_playlist_doc_h = vint_document_find("cell_playlist")  
	List_left = Vdo_mega_list:new("plist_left", 0, Cell_playlist_doc_h, "cell_playlist.lua", "List_left")  
	List_right = Vdo_mega_list:new("plist_right", 0, Cell_playlist_doc_h, "cell_playlist.lua", "List_right")  
	 
 
	--set colors for mixtape list... 
 
	List_left:set_highlight_color(COLOR_CHEATS_PRIMARY, COLOR_CHEATS_SECONDARY)	 
 
	List_right:set_highlight_color(COLOR_CHEATS_PRIMARY, COLOR_CHEATS_SECONDARY)	 
 
	 
 
	--Set up title 
 
	local cell_title_h = Vdo_cell_title:new("cell_title", 0, Cell_playlist_doc_h)  
	cell_title_h:set_text("PLAYLIST_TITLE_PLAYLIST")  
	cell_title_h:set_icon("ui_cell_icon_mix")  
	cell_title_h:play_dots_anim() 
 
	 
 
	--Datasubscribe and popluate lists... 
 
	List_data_stations = { }  
	List_data_tracklist = { }  
	vint_dataresponder_request("cell_playlist_populate", "station_populate", 0, CELL_PLAYLIST_GET_STATIONS)  
	vint_dataresponder_request("cell_playlist_populate", "plist_populate", 0, CELL_PLAYLIST_GET_SONGS)  
	 
 
	--Empty playlist on right... 
 
	List_data_right = plist_generate_right() 
 
 
 
	--Copy stations into left side of list... 
 
	List_data_left = table_clone(List_data_stations) 
 
	List_left_state = LIST_LEFT_STATE_STATION 
 
	 
 
	List_left:draw_items(List_data_left, 1, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
	List_right:draw_items(List_data_right, 1, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
	-- subscribe to common inputs 
 
	Input_tracker_left = Vdo_input_tracker:new() 
 
	Input_tracker_left:add_input("pause", "plist_nav_do_nothing", 50)  
	Input_tracker_left:add_input("map", "plist_nav_exit", 50)  
	Input_tracker_left:add_input("select", "plist_left_nav", 50)  
	Input_tracker_left:add_input("alt_select", "plist_left_nav", 50)  
	Input_tracker_left:add_input("back", "plist_left_nav", 50)	  
	Input_tracker_left:add_input("nav_up", "plist_left_nav", 50)  
	Input_tracker_left:add_input("nav_down", "plist_left_nav", 50)  
	Input_tracker_left:add_input("nav_left", "plist_left_nav", 50)  
	Input_tracker_left:add_input("nav_right", "plist_left_nav", 50)  
	Input_tracker_left:subscribe(false) 
 
	 
 
	Input_tracker_right = Vdo_input_tracker:new() 
 
	Input_tracker_right:add_input("pause", "plist_nav_do_nothing", 50)  
	Input_tracker_right:add_input("map", "plist_nav_exit", 50)  
	Input_tracker_right:add_input("select", "plist_right_nav", 50)  
	if game_get_platform() == "PC" then 
 
		Input_tracker_right:add_input("scancode", "plist_right_nav", 50, false, 211) --'del' key  
		Input_tracker_right:add_input("gamepad_x", "plist_right_nav", 50)  
	else 
 
		Input_tracker_right:add_input("alt_select", "plist_right_nav", 50)   
	end 
 
	Input_tracker_right:add_input("back", "plist_right_nav", 50)	  
	Input_tracker_right:add_input("nav_up", "plist_right_nav", 50)  
	Input_tracker_right:add_input("nav_down", "plist_right_nav", 50)  
	Input_tracker_right:add_input("nav_left", "plist_right_nav", 50)  
	Input_tracker_right:add_input("nav_right", "plist_right_nav", 50)  
	Input_tracker_right:subscribe(false) 
 
	 
 
	List_active = LIST_FOCUS_LEFT 
 
	List_left:toggle_highlight(true) 
 
	List_right:toggle_highlight(false) 
 
	List_right_state = LIST_RIGHT_STATE_NAV 
 
	 
 
	--Setup Button Hints 
 
	Hint_bar = Vdo_hint_bar:new("playlist_hints", 0, Cell_playlist_doc_h)  
	Hint_bar:set_hints(Station_menu_hints)  
 
	Hint_bar:set_visible(true)	 
 
 
 
	Artist_name_text_h = vint_object_find("label_1_txt")  
	Track_name_text_h = vint_object_find("label_2_txt")  
	 
 
	plist_set_track_artist(nil) 
 
	 
 
	--Transition the screen in... 
 
	cell_transition_screen(CELL_STATE_LANDSCAPE, CELL_SCREEN_PLAYLIST, CELL_SCREEN_MUSIC_SUB, cell_playlist_gained_focus) 
 
	 
 
	if game_get_platform() == "PC" then 
 
		Hint_bar:set_highlight(0) 
 
		 
 
		Hint_bar_mouse_input_tracker = Vdo_input_tracker:new() 
 
		Hint_bar:add_mouse_inputs("cell_playlist", Hint_bar_mouse_input_tracker)  
		Hint_bar_mouse_input_tracker:subscribe(true) 
 
		 
 
		Mouse_input_tracker = Vdo_input_tracker:new() 
 
		List_left:add_mouse_inputs("cell_playlist", Mouse_input_tracker)  
		Mouse_input_tracker:subscribe(true) 
 
	end 
 
	 
 
	--glitch 
 
	glitch_cell() 
 
end 
 
 
 
function station_populate(station_name, station_id) 
 
	local index = #List_data_stations + 1 
 
	List_data_stations[index] = { label = station_name, id = station_id, type = TYPE_BUTTON	}  
end 
 
 
 
function get_station_index_from_id(station_id)  
 
	for i = 1, #List_data_stations do 
 
		if List_data_stations[i].id == station_id then 
 
			return i 
 
		end 
 
	end 
 
end 
 
 
 
function plist_populate(artist, track, track_id, station_id, playlist_index) 
 
	local index = #Playlist_data + 1 
 
	Playlist_data[index] = {  
		artist = artist, 
 
		track = track, 
 
		track_id = track_id, 
 
		station_id = station_id, 
 
		station_index = get_station_index_from_id(station_id), 
 
		playlist_index = playlist_index, 
 
		internal_id = index, 
 
	} 
 
end 
 
 
 
function plist_generate_right() 
 
	local num_items = #Playlist_data 
 
	local item  
 
	local playlist_items = {}  
	local num_playlist_items = 0 
 
	--loop through items and see which ones are in the playlist... 
 
	for i = 1, num_items do 
 
		item = Playlist_data[i] 
 
		if item.playlist_index ~= -1 then 
 
			--its in the playlist... save it off... 
 
			num_playlist_items = #playlist_items + 1 
 
			playlist_items[num_playlist_items] = item 
 
		end 
 
	end 
 
 
 
	--now we have a list of playlist items... 
 
	if num_playlist_items > 0 then 
 
		--we need to bubble sort them for the playlist order... 
 
		local temp_item_storage 
 
		local flag = false 
 
		while flag == false do 
 
			flag = true 
 
			for i = 1, num_playlist_items - 1 do 
 
				if playlist_items[i].playlist_index > playlist_items[i + 1].playlist_index then 
 
					--swap indexes if the priority is greater 
 
					temp_item_storage = table_clone(playlist_items[i]) 
 
					playlist_items[i] = table_clone(playlist_items[i + 1]) 
 
					playlist_items[i + 1] = temp_item_storage   
 
					flag = false 
 
					break 
 
				end 
 
			end 
 
		end 
 
		 
 
		--sort the data into  
 
		local data = {}  
		 
 
		for i = 1, num_playlist_items do 
 
			data[i] = {  
				type = TYPE_BUTTON, 
 
				label = playlist_items[i].artist .. " - " .. playlist_items[i].track, 
 
				internal_id = playlist_items[i].internal_id 
 
			} 
 
		end 
 
		 
 
		List_data_right_is_empty = false 
 
		return data 
 
	else 
 
		--no items pass back empty list... 
 
		List_data_right_is_empty = true 
 
		return List_data_no_playlist 
 
	end 
 
	 
 
	--[[ DEBUG 
 
	for i = 1, num_playlist_items do 
 
		local artist = playlist_items[i].artist 
 
		local playlist_index = playlist_items[i].playlist_index 
 
		debug_print("vint", "playlist_index: " .. var_to_string(playlist_index) .. "artist: " .. var_to_string(artist) .. " : " .. i .. "\n")  
	end 
 
	]] 
 
end 
 
 
 
function plist_generate_station_tracks(station_id) 
 
	local num_items = #Playlist_data 
 
	local item  
 
	local station_items = {}  
	local num_station_items 
 
	--loop through items and see which ones are in the station... 
 
	for i = 1, num_items do 
 
		item = Playlist_data[i] 
 
		if item.station_id == station_id and item.playlist_index == -1 then 
 
			--its in the station... save it off... 
 
			num_station_items = #station_items + 1 
 
			station_items[num_station_items] = item 
 
		end 
 
	end 
 
 
 
	if #station_items == 0 then 
 
		--no items... 
 
		return station_items 
 
	end 
 
	 
 
	--we need to bubble sort them for the playlist order... 
 
	local temp_item_storage 
 
	local flag = false 
 
	while flag == false do 
 
		flag = true 
 
		for i = 1, num_station_items - 1 do 
 
			if station_items[i].playlist_index > station_items[i + 1].playlist_index then 
 
				--swap indexes if the priority is greater 
 
				temp_item_storage = table_clone(station_items[i]) 
 
				station_items[i] = table_clone(station_items[i + 1]) 
 
				station_items[i + 1] = temp_item_storage   
 
				flag = false 
 
				break 
 
			end 
 
		end 
 
	end 
 
	 
 
	 
 
	--format into list data... 
 
	local list_data = {}  
	for i = 1, num_station_items do 
 
		list_data[i] = {  
			type = TYPE_BUTTON, 
 
			label = station_items[i].artist .. " - " .. station_items[i].track, 
 
			internal_id = station_items[i].internal_id 
 
		} 
 
	end 
 
	 
 
	return list_data 
 
end 
 
 
 
--Adds an item to the end of a list... 
 
function plist_song_list_add(internal_id) 
 
 
 
	--make sure this list isn't empty... 
 
	if List_data_right_is_empty then 
 
		--if its empty lets actually make it empty.. 
 
		List_data_right = {}  
		List_data_right_is_empty = false 
 
	end 
 
	 
 
	--get next playlist index... 
 
	local playlist_index = #List_data_right + 1 
 
	 
 
	local item = Playlist_data[internal_id] 
 
	--Give the internal copy a new playlist index... 
 
	item.playlist_index = playlist_index 
 
	 
 
	List_data_right[playlist_index] = 	{  
		type = TYPE_BUTTON, 
 
		label = item.artist .. " - " .. item.track, 
 
		internal_id = internal_id, 
 
	} 
 
	ui_audio_post_event("ui_radio_toggle_on")  
end 
 
 
 
----------------------------------------- 
 
-- Removes a specific item in the list... 
 
----------------------------------------- 
 
function plist_song_list_remove_item(list, index) 
 
 
 
	--get the number of items in list... 
 
	local num_items = #list 
 
	 
 
	-- remove item in list... 
 
	local list_item = table_clone(list[index]) 
 
	list[index] = nil 
 
	 
 
	--Remove this item from playlist internal data it should end up back on the left list... 
 
	local internal_id = list_item.internal_id 
 
	local item = Playlist_data[internal_id] 
 
		 
 
	if item ~= nil then 
 
		--Give the internal copy a new playlist index... 
 
		item.playlist_index = -1 
 
		 
 
		--slide everthing beyond that item in the list back one... 
 
		for loop_index = index, num_items do 
 
			--table clone next item 
 
			list[loop_index] = table_clone(list[loop_index+1]) 
 
		end 
 
	end 
 
	 
 
	--delete last item in list... 
 
	list[num_items] = nil 
 
 
 
	return list_item 
 
end 
 
 
 
---------------------------------------------------------------------------------- 
 
-- Inserts an item in the list at specific index. 
 
-- 
 
-- @param	list 			table to modify... 
 
-- @param	list_item 	item to insert 
 
-- @param	index 		index at when to insert... 
 
---------------------------------------------------------------------------------- 
 
function plist_song_list_insert_item(list, list_item, index) 
 
	local num_items = (#list) 
 
 
 
	--slide everthing forward that item in the list back one... 
 
	for loop_index = num_items, index, -1 do 
 
		--table each item into slot above... 
 
		local next_item = loop_index + 1 
 
		list[next_item] = table_clone(list[loop_index]) 
 
		 
 
		--Remove this item from playlist internal data it should end up back on the left list... 
 
		local internal_id = list[next_item].internal_id 
 
		local item = Playlist_data[internal_id] 
 
	 
 
		--Give the internal copy a new playlist index... 
 
		item.playlist_index = next_item 
 
	end 
 
	 
 
	local item = Playlist_data[list_item.internal_id] 
 
 
 
	--Give the internal copy a new playlist index... 
 
	item.playlist_index = index 
 
	 
 
	-- items all shifted... now insert our items want.. 
 
	list[index] = list_item 
 
	 
 
	if List_right_state == LIST_RIGHT_STATE_NAV then  
 
		game_UI_audio_play("UI_Reward_Store_Menu_Navigation")  
	end 
 
end 
 
 
 
------------------------------------------------------------------------------- 
 
-- Play list left nav... 
 
------------------------------------------------------------------------------- 
 
function plist_left_nav(event) 
 
	if event == "select" then 
 
		if List_left:list_is_playing() == false then 
 
			if List_left_state == LIST_LEFT_STATE_STATION then 
 
				--Navigate to song menu... need to build it... 
 
				--Get current station id... and generate the station tracks... 
 
				local station_id = List_left:get_id() 
 
				List_data_current_station = station_id 
 
				List_data_left = plist_generate_station_tracks(station_id) 
 
				 
 
				if #List_data_left == 0 then 
 
					List_data_left = List_data_no_stationlist 
 
					List_data_left_is_empty = true 
 
				else  
 
					List_data_left_is_empty = false 
 
				end 
 
				 
 
				--Populate items in left list... 
 
				List_left:draw_items(List_data_left, 1, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
				 
 
				List_left_state = LIST_LEFT_STATE_TRACKLIST 
 
				 
 
				cell_playlist_update_mouse_inputs(true, false)		 
 
			else 
 
				if List_data_left_is_empty == true then 
 
					-- cannot add from an empty list... 
 
					return 
 
				end 
 
				--Move from track list to playlist... 
 
				--get track info... 
 
				local list_item = List_left:return_selected_data() 
 
				local left_index = List_left:get_selection() 
 
				local internal_id = list_item.internal_id 
 
 
 
				--TODO: Make sure we havn't removed all the items so we can select the right index... 
 
				plist_song_list_remove_item(List_data_left, left_index) 
 
				 
 
				--Add item to list on right... 
 
				plist_song_list_add(internal_id) 
 
				 
 
				List_right:draw_items(List_data_right, #List_data_right, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
				List_right:toggle_highlight(false) 
 
				 
 
				if #List_data_left == 0 then 
 
					List_data_left = List_data_no_stationlist 
 
					List_data_left_is_empty = true 
 
				end 
 
				 
 
				List_left:draw_items(List_data_left, left_index, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
			 
 
				cell_playlist_update_mouse_inputs(true, false) 
 
			end	 
 
		end 
 
	elseif event == "back" then 
 
		if List_left_state == LIST_LEFT_STATE_TRACKLIST then 
 
			if List_left:list_is_playing() == false then 
 
				List_data_left = table_clone(List_data_stations) 
 
				 
 
				local selected_index = get_station_index_from_id(List_data_current_station) 
 
				 
 
				--Populate items in left list... 
 
				List_left:draw_items(List_data_left, selected_index, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
				List_left_state = LIST_LEFT_STATE_STATION 
 
				 
 
				List_data_current_station = -1 
 
				--Update hints 
 
				Hint_bar:set_hints(Station_menu_hints) 
 
				cell_playlist_update_mouse_inputs(false, true) 
 
			end 
 
		else 
 
			--nav out of menu 
 
			cell_playlist_exit() 
 
		end 
 
	elseif event == "alt_select" then 
 
		--do nothing... 
 
		return 
 
	elseif event == "nav_up" then 
 
		if #List_data_left == 1 then 
 
			-- don't nav if we only have one item in list... 
 
			return 
 
		end 
 
		List_left:move_cursor(-1) 
 
	elseif event == "nav_down" then 
 
		if #List_data_left == 1 then 
 
			-- don't nav if we only have one item in list... 
 
			return 
 
		end 
 
		List_left:move_cursor(1) 
 
	elseif event == "nav_left" or event == "nav_right" then 
 
		if List_data_right_is_empty ~= true then 
 
			if List_left:list_is_playing() == false then 
 
				--only nav right if our playlist is full... 
 
				plist_nav_swap() 
 
			 
 
				--Reset hints because we exit early... 
 
				plist_set_hint_and_button_states() 
 
			end 
 
		end 
 
		return 
 
	end 
 
	 
 
	if List_left_state == LIST_LEFT_STATE_TRACKLIST then 
 
		plist_set_track_artist(List_left:return_selected_data()) 
 
	else 
 
		plist_set_track_artist(nil) 
 
	end 
 
	 
 
	--Set button states after any events... 
 
	plist_set_hint_and_button_states() 
 
end 
 
 
 
local swap_index = 1 
 
------------------------------------------------------------------------------- 
 
-- Play list right nav... 
 
------------------------------------------------------------------------------- 
 
function plist_right_nav(event) 
 
	if event == "select" then 
 
		if List_right:list_is_playing() == false then 
 
			--Moving track functionality only works if we have 2 or more items. 
 
			if #List_data_right > 1 then 
 
				 
 
				-- Turn into movable item... 
 
				if List_right_state == LIST_RIGHT_STATE_NAV then 
 
					--change to moving state... 
 
					List_right_state = LIST_RIGHT_STATE_MOVING 
 
					 
 
					-- Remove and reinsert the item as new/flashing 
 
					local current_selection = List_right:get_selection() 
 
					swap_index = current_selection 
 
					local list_item = plist_song_list_remove_item(List_data_right, current_selection) 
 
					list_item.is_new = true 
 
					plist_song_list_insert_item(List_data_right, list_item, current_selection) 
 
					List_right:draw_items(List_data_right, current_selection, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
				 
 
				elseif List_right_state == LIST_RIGHT_STATE_MOVING then 
 
					--change to naving state... 
 
					List_right_state = LIST_RIGHT_STATE_NAV 
 
					 
 
					-- Remove and reinsert the swap index into the current selection's spot 
 
					local current_selection = List_right:get_selection() 
 
					local list_item = plist_song_list_remove_item(List_data_right, swap_index) 
 
					list_item.is_new = false 
 
					plist_song_list_insert_item(List_data_right, list_item, current_selection) 
 
					List_right:draw_items(List_data_right, current_selection, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
				end 
 
			end 
 
		end 
 
	elseif event == "alt_select" or event == "gamepad_x" or event == "scancode" then 
 
		if List_right_state == LIST_RIGHT_STATE_MOVING then 
 
			--do nothing... 
 
			return 
 
		end 
 
		 
 
		if List_right:list_is_playing() == false then 
 
			-- Remove Track 
 
			--swap items... 
 
			local current_selection = List_right:get_selection() 
 
			local list_item = plist_song_list_remove_item(List_data_right, current_selection) 
 
			 
 
			if List_data_current_station ~= -1 then 
 
				List_data_left = plist_generate_station_tracks(List_data_current_station) 
 
				 
 
				if #List_data_left == 0 then 
 
					List_data_left = List_data_no_stationlist 
 
					List_data_left_is_empty = true 
 
				else  
 
					List_data_left_is_empty = false 
 
				end 
 
			end 
 
			local left_selection = List_left:get_selection() 
 
			--Populate items in left list... 
 
			List_left:draw_items(List_data_left, left_selection, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
			List_left:toggle_highlight(false)	--hide highlight after redraw. 
 
			 
 
			-- check if new playlist isn't empty. 
 
			if #List_data_right == 0 then 
 
				List_data_right = table_clone(List_data_no_playlist) 
 
				List_data_right_is_empty = true 
 
			end 
 
			 
 
			List_right:draw_items(List_data_right, current_selection, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
			ui_audio_post_event("ui_radio_toggle_off")  
			if List_data_right_is_empty then 
 
				--nav back left... 
 
				plist_nav_swap() 
 
				plist_set_hint_and_button_states() 
 
				 
 
				cell_playlist_update_mouse_inputs(true, false) 
 
				return 
 
			end 
 
			 
 
		end		 
 
	elseif event == "back" then 
 
		if List_right:list_is_playing() == false and List_left:list_is_playing() == false then 
 
			-- Go back to station select (or exit) 
 
			plist_left_nav("back")  
			plist_set_hint_and_button_states() 
 
			 
 
			-- Turn off the left highlight (it gets reactivated by redrawing the left list) 
 
			List_left:toggle_highlight(false) 
 
			return 
 
		end 
 
	elseif event == "nav_up" then 
 
		 
 
		if #List_data_right == 1 then 
 
			-- don't nav if we only have one item in list... 
 
			return 
 
		end 
 
		 
 
		if List_right_state == LIST_RIGHT_STATE_NAV then 
 
			List_right:move_cursor(-1) 
 
		elseif List_right_state == LIST_RIGHT_STATE_MOVING then 
 
			--swap items... 
 
			local current_selection = swap_index --List_right:get_selection() 
 
			 
 
			--insert into previous slot... 
 
			local next_slot = current_selection - 1 
 
			if next_slot < 1 then 
 
				next_slot = #List_data_right 
 
			end 
 
						 
 
			--get track info and remove item from list... 
 
			local list_item = plist_song_list_remove_item(List_data_right, current_selection) 
 
			 
 
			plist_song_list_insert_item(List_data_right, list_item, next_slot) 
 
			 
 
			List_right:draw_items(List_data_right, current_selection, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
			List_right:move_cursor(-1) 
 
			swap_index = next_slot 
 
		end 
 
 
 
	elseif event == "nav_down" then 
 
		 
 
		if #List_data_right == 1 then 
 
			-- don't nav if we only have one item in list... 
 
			return 
 
		end 
 
		 
 
		if List_right_state == LIST_RIGHT_STATE_NAV then 
 
			List_right:move_cursor(1) 
 
		elseif List_right_state == LIST_RIGHT_STATE_MOVING then 
 
			--swap items... 
 
			local current_selection = swap_index --List_right:get_selection() 
 
 
 
			--insert into next slot... 
 
			local next_slot = current_selection + 1 
 
			if next_slot > #List_data_right then 
 
				next_slot = 1 
 
			end 
 
		 
 
			--get track info... 
 
			local list_item = plist_song_list_remove_item(List_data_right, current_selection) 
 
			 
 
			plist_song_list_insert_item(List_data_right, list_item, next_slot) 
 
			 
 
			List_right:draw_items(List_data_right, current_selection, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
			List_right:move_cursor(1) 
 
			swap_index = next_slot 
 
		end 
 
		 
 
	elseif event == "nav_left" or event == "nav_right" then 
 
		if List_right:list_is_playing() == false and List_left:list_is_playing() == false then 
 
			--Swap nav... 
 
			plist_nav_swap() 
 
			 
 
			--Reset hints because we exit early... 
 
			plist_set_hint_and_button_states() 
 
			cell_playlist_update_mouse_inputs(false, true) 
 
			return 
 
		end 
 
	end 
 
	 
 
	if List_right_state == LIST_RIGHT_STATE_NAV then 
 
		plist_set_track_artist(List_right:return_selected_data()) 
 
	end 
 
	 
 
		--Set button states after any events... 
 
	plist_set_hint_and_button_states() 
 
	cell_playlist_update_mouse_inputs(true, true) 
 
end 
 
 
 
------------------------------------------------------------------------------- 
 
-- Updates button states depending on what state we are in. 
 
-- This has to be done because the highlight must be reset when we redraw the lists. 
 
-- We redraw so often its easiest to do this all in one function. 
 
-- 
 
function plist_set_hint_and_button_states() 
 
 
 
	--set titles of menus 
 
	local header_left_h = vint_object_find("playlist_header_left")  
	if List_left_state == LIST_LEFT_STATE_TRACKLIST then 
 
		--set title to tracklist 
 
		vint_set_property(header_left_h, "text_tag","PLAYLIST_HEADER_TRACKS") 
 
	else 
 
		--set title to station  
 
		vint_set_property(header_left_h, "text_tag","PLAYLIST_HEADER_STATIONS") 
 
	end 
 
 
 
	local hint_data = {}  
	if List_active == LIST_FOCUS_LEFT then 
 
		if List_data_left_is_empty and List_left_state == LIST_LEFT_STATE_TRACKLIST then 
 
			--Hide button 
 
			List_left:highlight_set_button("")  
			hint_data = Song_menu_empty_hints 
 
		else 
 
			if List_left_state == LIST_LEFT_STATE_STATION then 
 
				--Left Station State 
 
				List_left:highlight_set_button(CTRL_MENU_BUTTON_A) 
 
				hint_data = Station_menu_hints 
 
			elseif List_left_state == LIST_LEFT_STATE_TRACKLIST then 
 
				--Left Tracklist State 
 
				List_left:highlight_set_button(CTRL_MENU_BUTTON_A) 
 
				hint_data = Song_menu_hints 
 
			end 
 
		end 
 
	elseif List_active == LIST_FOCUS_RIGHT then 
 
		if List_data_right_is_empty then 
 
			--Hide button 
 
			List_right:highlight_set_button("")  
			hint_data = Song_menu_empty_hints 
 
		else 
 
			if List_right_state == LIST_RIGHT_STATE_MOVING then 
 
				--Right Moving state 
 
				List_right:highlight_set_button("ui_cell_playlist_up_down", true)  
				hint_data = Playlist_menu_move_hints 
 
			elseif List_right_state == LIST_RIGHT_STATE_NAV then 
 
				local list_right_num_items = #List_data_right 
 
				if list_right_num_items > 1 then 
 
					--Right Nav state and option to move 
 
					List_right:highlight_set_button(CTRL_MENU_BUTTON_A) 
 
					hint_data = Playlist_menu_hints 
 
				else 
 
					-- Only one item no moving here... 
 
					List_right:highlight_set_button("")  
					hint_data = Playlist_menu_no_moving_hints 
 
				end 
 
			end	 
 
		end  
 
	end 
 
	 
 
	-- Override the back button label if stations are not visible 
 
	if List_left_state ~= LIST_LEFT_STATE_STATION then 
 
		hint_data[1] = {CTRL_MENU_BUTTON_B, "PLAYLIST_HEADER_STATIONS"}  
	else 
 
		hint_data[1] = {CTRL_MENU_BUTTON_B, "MENU_BACK"}  
	end 
 
	Hint_bar:set_hints(hint_data) 
 
	cell_playlist_update_mouse_inputs(true, true) 
 
end 
 
 
 
 
 
--Exit all the way out of the menu 
 
function plist_nav_exit() 
 
	cell_playlist_exit(true) 
 
end 
 
 
 
function plist_nav_swap() 
 
	-- Make sure the right list doesn't have a highlighted item 
 
	if swap_index <= #List_data_right and List_data_right_is_empty == false then 
 
		local list_item = plist_song_list_remove_item(List_data_right, swap_index) 
 
		if list_item ~= nil then 
 
			list_item.is_new = false 
 
			plist_song_list_insert_item(List_data_right, list_item, swap_index) 
 
			List_right:draw_items(List_data_right, swap_index, LIST_SIZE, LIST_ITEMS,	LIST_SCALE, true, false) 
 
		end 
 
	end 
 
 
 
	--Move navigator between list 
 
	if List_active == LIST_FOCUS_LEFT then 
 
		--Switch to right side... 
 
		Input_tracker_left:subscribe(false) 
 
		Input_tracker_right:subscribe(true) 
 
		List_left:toggle_highlight(false) 
 
		List_right:toggle_highlight(true) 
 
		List_active = LIST_FOCUS_RIGHT 
 
	else 
 
		--Switch to left side 
 
		Input_tracker_left:subscribe(true) 
 
		Input_tracker_right:subscribe(false) 
 
		List_left:toggle_highlight(true) 
 
		List_right:toggle_highlight(false) 
 
		List_active = LIST_FOCUS_LEFT 
 
	end 
 
	 
 
	--always reset the state of right side when swapping... 
 
	List_right_state = LIST_RIGHT_STATE_NAV 
 
	 
 
	if List_active == LIST_FOCUS_LEFT then 
 
		if List_left_state ~= LIST_LEFT_STATE_TRACKLIST then 
 
			plist_set_track_artist(nil) 
 
		else 
 
			local list_item = List_left:return_selected_data() 
 
			plist_set_track_artist(list_item) 
 
		end 
 
	else 
 
		local list_item = List_right:return_selected_data() 
 
		plist_set_track_artist(list_item) 
 
	end 
 
end 
 
 
 
 
 
Plist_play_thread = -1 
 
function plist_set_track_artist(track_info) 
 
	 
 
	if Plist_play_thread ~= -1 then 
 
		thread_kill(Plist_play_thread) 
 
		Plist_play_thread = -1 
 
	end 
 
	if track_info == nil or track_info.internal_id == nil then 
 
		vint_set_property(Artist_name_text_h, "visible", false) 
 
		vint_set_property(Track_name_text_h, "visible", false) 
 
		playlist_stop_track() 
 
	else 
 
		vint_set_property(Artist_name_text_h, "visible", true) 
 
		vint_set_property(Track_name_text_h, "visible", true) 
 
		 
 
		local item = Playlist_data[track_info.internal_id] 
 
		vint_set_property(Artist_name_text_h, "text_tag", item.artist) 
 
		vint_set_property(Track_name_text_h, "text_tag", item.track) 
 
		 
 
		Plist_play_thread = thread_new("plist_play_delayed_track", item.track_id)  
	end 
 
end 
 
 
 
function plist_play_delayed_track(track_id) 
 
	delay(0.5) 
 
	playlist_play_track(track_id) 
 
	Plist_play_thread = -1 
 
end 
 
 
 
function plist_song_list_clear() 
 
	List_data_left = {}  
end 
 
 
 
function plist_nav_do_nothing() 
 
	--do nothing... 
 
end 
 
 
 
 
 
function cell_playlist_cleanup() 
 
	--Guarantee cleanup of controls. 
 
	Input_tracker_left:subscribe(false) 
 
	Input_tracker_right:subscribe(false) 
 
end 
 
 
 
 
 
------------------------------------------------------------------------------- 
 
-- Changes highlight button on right list to use arrow or standard (a) button 
 
------------------------------------------------------------------------------- 
 
function cell_playlist_list_right_use_arrow(use_arrow) 
 
	if use_arrow then 
 
		--Change button on list... 
 
 
 
	else 
 
		 
 
	end 
 
end 
 
 
 
------------------------------------------------------------------------------- 
 
-- Exits the playlist menu... 
 
-- 
 
function cell_playlist_exit(exit_to_game) 
 
 
 
	vint_dataresponder_post("cell_menu_state_dr", "Set", ID_MAIN)  
	--save playlist 
 
	cell_playlist_save() 
 
	 
 
	--Lock controls 
 
	cell_playlist_lost_focus() 
 
	 
 
	--do the right exit... 
 
	if exit_to_game == true then 
 
		cell_transition_screen(CELL_STATE_OUT, CELL_SCREEN_NONE, CELL_SCREEN_PLAYLIST, cell_playlist_exit_to_game) 
 
	else 
 
		cell_transition_screen(CELL_STATE_PORTRAIT, CELL_SCREEN_MUSIC_SUB, CELL_SCREEN_PLAYLIST, cell_playlist_exit_to_sub) 
 
	end 
 
end 
 
 
 
 
 
------------------------------------------------------------------------------- 
 
-- Final exit to cell music sub 
 
-- 
 
function cell_playlist_exit_to_sub() 
 
	ui_audio_post_event("UI_Hub_Menu_Back")  
	pop_screen() --Playlist Editor 
 
end 
 
 
 
------------------------------------------------------------------------------- 
 
-- Final exit to game 
 
-- 
 
function cell_playlist_exit_to_game() 
 
	ui_audio_post_event("UI_Hub_Menu_Back")  
	pop_screen()	--Playlist Editor 
 
	pop_screen()	--music Sub screen 
 
	pop_screen()	--main 
 
	pop_screen()	--cell frame 
 
end 
 
 
 
function cell_playlist_save() 
 
	local Save_list = { }  
	if List_data_right_is_empty == false then 
 
		--if our list isn't empty we can make the savelist... 
 
		for i = 1, #List_data_right do 
 
			Save_list[i] = Playlist_data[List_data_right[i].internal_id].track_id 
 
		end		 
 
	end 
 
	cell_playlist_save_list(Save_list) 
 
end 
 
 
 
function debug_right_list() 
 
	local num_items = #List_data_right 
 
	local item  
 
	local playlist_items = {}  
	local num_playlist_items 
 
	--loop through items and see which ones are in the playlist... 
 
	for i = 1, num_items do 
 
		local internal_id = List_data_right[i].internal_id 
 
		local artist = Playlist_data[internal_id].artist 
 
		local playlist_index = Playlist_data[internal_id].playlist_index 
 
		debug_print("vint", "artist: " .. var_to_string(artist) .. " | playlist_index: " .. var_to_string(playlist_index) .. "\n")  
	end 
 
end 
 
 
 
function cell_playlist_gained_focus() 
 
	Input_tracker_left:subscribe(true) 
 
	cell_playlist_update_mouse_inputs(true, true) 
 
end 
 
 
 
function cell_playlist_lost_focus() 
 
	Input_tracker_left:subscribe(false) 
 
	Input_tracker_right:subscribe(false) 
 
	if Mouse_input_tracker ~= nil then 
 
		Mouse_input_tracker:subscribe(false) 
 
		Hint_bar_mouse_input_tracker:subscribe(false) 
 
	end 
 
end 
 
 
 
-- Mouse input functions 
 
-- 
 
 
 
function cell_playlist_mouse_right_click(event, target_handle, mouse_x, mouse_y)	 
 
	local new_index2 = List_right:get_button_index(target_handle) 
 
	if new_index2 ~= 0 then 
 
		plist_right_nav("alt_select")  
	end 
 
end 
 
 
 
function cell_playlist_mouse_click(event, target_handle, mouse_x, mouse_y) 
 
	local hint_index = Hint_bar:get_hint_index(target_handle) 
 
	 
 
	-- Hint bar functionality 
 
	if hint_index == 1 then 
 
		if List_active == LIST_FOCUS_RIGHT then 
 
			plist_left_nav("back")  
		else 
 
			plist_right_nav("back")  
		end 
 
	elseif hint_index == 2 then 
 
		if List_active == LIST_FOCUS_RIGHT then 
 
			if #List_data_right == 1 then 
 
				plist_right_nav("alt_select")  
			else 
 
				plist_right_nav("select")  
			end 
 
		else 
 
			plist_left_nav("select")  
		end 
 
	elseif hint_index == 3 then 
 
		if List_active == LIST_FOCUS_RIGHT then 
 
			plist_right_nav("alt_select")  
		else 
 
		end 
 
	end 
 
 
 
	local new_index = List_left:get_button_index(target_handle) 
 
	if new_index ~= 0 then 
 
		-- Swap navigation if not already focused on this list 
 
		if List_active == LIST_FOCUS_RIGHT then 
 
			plist_nav_swap() 
 
			plist_set_hint_and_button_states() 
 
		end 
 
		List_left:set_selection(new_index) 
 
		List_left:move_cursor(0, true) 
 
		plist_set_track_artist(List_left:return_selected_data()) 
 
		plist_left_nav("select")  
	end 
 
	 
 
	local new_index2 = List_right:get_button_index(target_handle) 
 
	if new_index2 ~= 0 then 
 
		-- Swap navigation if not already focused on this list 
 
		if List_active == LIST_FOCUS_LEFT then 
 
			plist_nav_swap() 
 
			plist_set_hint_and_button_states() 
 
		end 
 
		List_right:set_selection(new_index2) 
 
		List_right:move_cursor(0, true) 
 
		plist_set_track_artist(List_right:return_selected_data()) 
 
		plist_right_nav("select")  
	end 
 
end 
 
 
 
function cell_playlist_mouse_move(event, target_handle) 
 
	Hint_bar:set_highlight(0) 
 
	 
 
	local hint_index = Hint_bar:get_hint_index(target_handle) 
 
	if hint_index ~= 0 then 
 
		Hint_bar:set_highlight(hint_index) 
 
	end 
 
	 
 
	local new_index = List_left:get_button_index(target_handle) 
 
	if new_index ~= 0 then 
 
		-- Swap navigation if not already focused on this list 
 
		if List_active == LIST_FOCUS_RIGHT then 
 
			plist_nav_swap() 
 
			plist_set_hint_and_button_states() 
 
		end 
 
		List_left:set_selection(new_index) 
 
		List_left:move_cursor(0, true) 
 
		plist_set_track_artist(List_left:return_selected_data()) 
 
	end 
 
	 
 
	local new_index2 = List_right:get_button_index(target_handle) 
 
	if new_index2 ~= 0 then 
 
		-- Swap navigation if not already focused on this list 
 
		if List_active == LIST_FOCUS_LEFT then 
 
			plist_nav_swap() 
 
			plist_set_hint_and_button_states() 
 
		end 
 
		List_right:set_selection(new_index2) 
 
		List_right:move_cursor(0, true) 
 
		plist_set_track_artist(List_right:return_selected_data()) 
 
		if List_right_state == LIST_RIGHT_STATE_MOVING then 
 
			List_right:highlight_set_button("ui_cell_playlist_up_down", true)  
		end 
 
	end 
 
end 
 
 
 
function cell_playlist_mouse_scroll(event, target_handle, mouse_x, mouse_y, scroll_lines) 
 
	if scroll_lines ~= 0 then 
 
		if List_left:get_scroll_region_handle() == target_handle then 
 
			List_left:scroll_list(scroll_lines * -1) 
 
			cell_playlist_update_mouse_inputs(true, false) 
 
		elseif List_right:get_scroll_region_handle() == target_handle then 
 
			List_right:scroll_list(scroll_lines * -1) 
 
			cell_playlist_update_mouse_inputs(true, false) 
 
		end 
 
	end 
 
end 
 
 
 
function cell_playlist_mouse_drag(event, target_handle, mouse_x, mouse_y) 
 
	if List_left.scrollbar.tab_grp.handle == target_handle then 
 
		local new_start_index = List_left.scrollbar:drag_scrolltab(mouse_y, List_left.num_buttons - (List_left.max_buttons - 1)) 
 
		List_left:scroll_list(0, new_start_index) 
 
	elseif List_right.scrollbar.tab_grp.handle == target_handle then 
 
		local new_start_index = List_right.scrollbar:drag_scrolltab(mouse_y, List_right.num_buttons - (List_right.max_buttons - 1)) 
 
		List_right:scroll_list(0, new_start_index) 
 
	end 
 
end 
 
 
 
-- Updates the mouse inputs for the list and snaps the scrolltab to the closest notch based on the visible index 
 
-- 
 
function cell_playlist_mouse_drag_release(event, target_handle, mouse_x, mouse_y) 
 
	if List_left.scrollbar.tab_grp.handle == target_handle then 
 
		local start_index = List_left:get_visible_indices() 
 
		List_left.scrollbar:release_scrolltab(start_index, List_left.num_buttons - (List_left.max_buttons - 1)) 
 
		cell_playlist_update_mouse_inputs(true, false) 
 
	elseif List_right.scrollbar.tab_grp.handle == target_handle then 
 
		local start_index = List_right:get_visible_indices() 
 
		List_right.scrollbar:release_scrolltab(start_index, List_right.num_buttons - (List_right.max_buttons - 1)) 
 
		cell_playlist_update_mouse_inputs(true, false) 
 
	end 
 
end 
 
 
 
function cell_playlist_update_mouse_inputs(update_list, update_hint_bar) 
 
	if Mouse_input_tracker ~= nil then 
 
		if update_list == true then 
 
			-- Remove and add the inputs to both lists (if possible) 
 
			Mouse_input_tracker:remove_all() 
 
			if List_data_left_is_empty == false or List_left_state == LIST_LEFT_STATE_STATION then 
 
				List_left:add_mouse_inputs("cell_playlist", Mouse_input_tracker)  
			end 
 
			if List_data_right_is_empty == false then 
 
				List_right:add_mouse_inputs("cell_playlist", Mouse_input_tracker, 0, nil, nil, 0, true)  
			end 
 
			Mouse_input_tracker:subscribe(true) 
 
		end 
 
		if update_hint_bar == true then 
 
			-- Remove and add the inputs to the hintbar 
 
			Hint_bar_mouse_input_tracker:remove_all() 
 
			Hint_bar:add_mouse_inputs("cell_playlist", Hint_bar_mouse_input_tracker)  
			Hint_bar_mouse_input_tracker:subscribe(true) 
 
		end 
 
	end 
 
end