TotemPlParserResult
totem_pl_parser_add_ram (TotemPlParser *parser, GFile *file, TotemPlParseData *parse_data, gpointer data)
{
	gboolean retval = TOTEM_PL_PARSER_RESULT_UNHANDLED;
	char *contents, **lines;
	gsize size;
	guint i;

	if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE)
		return TOTEM_PL_PARSER_RESULT_ERROR;

	lines = g_strsplit_set (contents, "\r\n", 0);
	g_free (contents);

	for (i = 0; lines[i] != NULL; i++) {
		/* Empty line */
		if (totem_pl_parser_line_is_empty (lines[i]) != FALSE)
			continue;

		retval = TOTEM_PL_PARSER_RESULT_SUCCESS;

		/* Either it's a URI, or it has a proper path ... */
		if (strstr(lines[i], "://") != NULL
				|| lines[i][0] == G_DIR_SEPARATOR) {
			GFile *line_file;

			line_file = g_file_new_for_uri (lines[i]);
			/* .ram files can contain .smil entries */
			if (totem_pl_parser_parse_internal (parser, line_file, NULL, parse_data) != TOTEM_PL_PARSER_RESULT_SUCCESS)
				totem_pl_parser_parse_ram_uri (parser, lines[i]);
			g_object_unref (line_file);
		} else if (strcmp (lines[i], "--stop--") == 0) {
			/* For Real Media playlists, handle the stop command */
			break;
		} else {
			//FIXME
#if 0
			char *base;

			/* Try with a base */
			base = totem_pl_parser_base_uri (uri);

			if (totem_pl_parser_parse_internal (parser, lines[i], base) != TOTEM_PL_PARSER_RESULT_SUCCESS)
			{
				char *fullpath;
				fullpath = g_strdup_printf ("%s/%s", base, lines[i]);
				totem_pl_parser_parse_ram_uri (parser, fullpath);
				g_free (fullpath);
			}
			g_free (base);
#endif
		}
	}

	g_strfreev (lines);

	return retval;
}
TotemPlParserResult
totem_pl_parser_add_desktop (TotemPlParser *parser,
			     GFile *file,
			     GFile *base_file,
			     TotemPlParseData *parse_data,
			     gpointer data)
{
	char *contents, **lines;
	const char *path, *display_name, *type;
	GFile *target;
	gsize size;
	TotemPlParserResult res = TOTEM_PL_PARSER_RESULT_ERROR;

	if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE)
		return res;

	lines = g_strsplit (contents, "\n", 0);
	g_free (contents);

	type = totem_pl_parser_read_ini_line_string (lines, "Type");
	if (type == NULL)
		goto bail;
	
	if (g_ascii_strcasecmp (type, "Link") != 0
	    && g_ascii_strcasecmp (type, "FSDevice") != 0) {
		goto bail;
	}

	path = totem_pl_parser_read_ini_line_string (lines, "URL");
	if (path == NULL)
		goto bail;
	target = g_file_new_for_uri (path);

	display_name = totem_pl_parser_read_ini_line_string (lines, "Name");

	if (totem_pl_parser_ignore (parser, path) == FALSE
	    && g_ascii_strcasecmp (type, "FSDevice") != 0) {
		totem_pl_parser_add_one_file (parser, target, display_name);
	} else {
		if (totem_pl_parser_parse_internal (parser, target, NULL, parse_data) != TOTEM_PL_PARSER_RESULT_SUCCESS)
			totem_pl_parser_add_one_file (parser, target, display_name);
	}

	res = TOTEM_PL_PARSER_RESULT_SUCCESS;

bail:
	g_strfreev (lines);

	return res;
}
TotemPlParserResult
totem_pl_parser_add_m3u (TotemPlParser *parser,
			 GFile *file,
			 GFile *base_file,
			 TotemPlParseData *parse_data,
			 gpointer data)
{
	TotemPlParserResult retval = TOTEM_PL_PARSER_RESULT_UNHANDLED;
	char *contents, **lines;
	gsize size;
	guint i, num_lines;
	gboolean dos_mode = FALSE;
	const char *extinfo, *extvlcopt_audiotrack;
	char *pl_uri;

	if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE) {
		DEBUG (file, g_print ("Failed to load '%s'\n", uri));
		return TOTEM_PL_PARSER_RESULT_ERROR;
	}

	/* .pls files with a .m3u extension, the nasties */
	if (g_str_has_prefix (contents, "[playlist]") != FALSE
			|| g_str_has_prefix (contents, "[Playlist]") != FALSE
			|| g_str_has_prefix (contents, "[PLAYLIST]") != FALSE) {
		DEBUG (file, g_print ("Parsing '%s' playlist as PLS\n", uri));
		retval = totem_pl_parser_add_pls_with_contents (parser, file, base_file, contents, parse_data);
		g_free (contents);
		return retval;
	}

	if (strstr (contents, EXTINF_HLS) ||
	    strstr (contents, EXTINF_HLS2)) {
		DEBUG (file, g_print ("Unhandled HLS playlist '%s', should be passed to player\n", uri));
		g_free (contents);
		return retval;
	}

	/* Try to use ISO-8859-1 if we don't have valid UTF-8,
	 * try to parse anyway if it's not ISO-8859-1 */
	if (g_utf8_validate (contents, -1, NULL) == FALSE) {
		char *fixed;
		fixed = g_convert (contents, -1, "UTF-8", "ISO8859-1", NULL, NULL, NULL);
		if (fixed != NULL) {
			g_free (contents);
			contents = fixed;
		}
	}

	/* is non-NULL if there's an EXTINF on a preceding line */
	extinfo = NULL;
	extvlcopt_audiotrack = NULL;

	/* figure out whether we're a unix m3u or dos m3u */
	if (strstr(contents, "\x0d")) {
		dos_mode = TRUE;
	}

	lines = g_strsplit_set (contents, "\r\n", 0);
	g_free (contents);
	num_lines = g_strv_length (lines);
	/* We don't count the terminating NULL */
	num_lines--;

	/* Send out the playlist start and get crackin' */
	pl_uri = g_file_get_uri (file);
	totem_pl_parser_add_uri (parser,
				 TOTEM_PL_PARSER_FIELD_IS_PLAYLIST, TRUE,
				 TOTEM_PL_PARSER_FIELD_URI, pl_uri,
				 TOTEM_PL_PARSER_FIELD_CONTENT_TYPE, "audio/x-mpegurl",
				 NULL);

	for (i = 0; lines[i] != NULL; i++) {
		const char *line;
		char *length;
		gint64 length_num = 0;
		char *audio_track;

		line = lines[i];

		if (line[0] == '\0')
			continue;

		retval = TOTEM_PL_PARSER_RESULT_SUCCESS;

		/* Ignore leading spaces */
		for (; g_ascii_isspace (line[0]); line++)
			;

		/* Ignore comments, but mark it if we have extra info */
		if (line[0] == '#') {
			if (extinfo == NULL && g_str_has_prefix (line, EXTINF) != FALSE)
				extinfo = line;
			if (extvlcopt_audiotrack == NULL && g_str_has_prefix (line, EXTVLCOPT_AUDIOTRACK) != FALSE)
				extvlcopt_audiotrack = line;
			continue;
		}

		length = totem_pl_parser_get_extinfo_length (extinfo);
		if (length != NULL)
			length_num = totem_pl_parser_parse_duration (length, totem_pl_parser_is_debugging_enabled (parser));
		g_free (length);

		audio_track = totem_pl_parser_get_extvlcopt_audio_track (extvlcopt_audiotrack);

		/* Either it's a URI, or it has a proper path ... */
		if (strstr(line, "://") != NULL
				|| line[0] == G_DIR_SEPARATOR) {
			GFile *uri;

			uri = g_file_new_for_commandline_arg (line);
			if (length_num < 0 ||
			    totem_pl_parser_parse_internal (parser, uri, NULL, parse_data) != TOTEM_PL_PARSER_RESULT_SUCCESS) {
				totem_pl_parser_add_uri (parser,
							 TOTEM_PL_PARSER_FIELD_URI, line,
							 TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo),
							 TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
							 NULL);
			}
			g_object_unref (uri);
		} else if (g_ascii_isalpha (line[0]) != FALSE
			   && g_str_has_prefix (line + 1, ":\\")) {
			/* Path relative to a drive on Windows, we need to use
			 * the base that was passed to us */
			GFile *uri;

			lines[i] = g_strdelimit (lines[i], "\\", '/');
			/* + 2, skip drive letter */
			uri = g_file_get_child (base_file, line + 2);
			totem_pl_parser_add_uri (parser,
						 TOTEM_PL_PARSER_FIELD_FILE, uri,
						 TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo),
						 TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
						 NULL);
			g_object_unref (uri);
		} else if (line[0] == '\\' && line[1] == '\\') {
			/* ... Or it's in the windows smb form
			 * (\\machine\share\filename), Note drive names
			 * (C:\ D:\ etc) are unhandled (unknown base for
			 * drive letters) */
		        char *tmpuri;

			lines[i] = g_strdelimit (lines[i], "\\", '/');
			tmpuri = g_strjoin (NULL, "smb:", line, NULL);

			totem_pl_parser_add_uri (parser,
						 TOTEM_PL_PARSER_FIELD_URI, tmpuri,
						 TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo),
						 TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
						 NULL);

			g_free (tmpuri);
		} else {
			/* Try with a base */
			GFile *uri, *_base_file;
			char sep;

			_base_file = g_file_get_parent (file);
			sep = (dos_mode ? '\\' : '/');
			if (sep == '\\')
				lines[i] = g_strdelimit (lines[i], "\\", '/');
			uri = g_file_get_child (_base_file, line);
			g_object_unref (_base_file);
			totem_pl_parser_add_uri (parser,
						 TOTEM_PL_PARSER_FIELD_FILE, uri,
						 TOTEM_PL_PARSER_FIELD_TITLE, totem_pl_parser_get_extinfo_title (extinfo),
						 TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
						 NULL);
			g_object_unref (uri);
		}
		extinfo = NULL;
		extvlcopt_audiotrack = NULL;

		g_free (audio_track);
	}

	g_strfreev (lines);

	totem_pl_parser_playlist_end (parser, pl_uri);
	g_free (pl_uri);

	return retval;
}