/*
 * GQmpeg
 * (C)1998, 1999 John Ellis
 *
 * Author: John Ellis
 *
 * This software is released under the GNU General Public License.
 * Please read the included file COPYING for more information.
 * This software comes with no warranty of any kind, use at you own risk!
 */

#include "gqmpeg.h"

gchar *quoted_value(gchar *text)
{
	gchar *ptr;
	gint c = 0;
	gint l = strlen(text);

	if (l == 0) return NULL;

	while (c < l && text[c] !='"') c++;
	if (text[c] == '"')
		{
		c++;
		ptr = text + c;
		while (c < l && text[c] !='"') c++;
		if (text[c] == '"')
			{
			text[c] = '\0';
			if (strlen(ptr) > 0)
				{
				return g_strdup(ptr);
				}
			}
		}
	else
		/* for compatibility with older formats (<0.3.7)
		 * read a line without quotes too */
		{
		c = 0;
		while (c < l && text[c] !=' ' && text[c] !=8 && text[c] != '\n') c++;
		if (c != 0)
			{
			text[c] = '\0';
			return g_strdup(text);
			}
		}

	return NULL;
}

void write_char_option(FILE *f, gchar *label, gchar *text)
{
	if (text)
		fprintf(f,"%s: \"%s\"\n", label, text);
	else
		fprintf(f,"%s: \n", label);
}

gchar *read_char_option(FILE *f, gchar *option, gchar *label, gchar *value, gchar *text)
{
	if (!strcasecmp(option, label))
		{
		g_free(text);
		text = quoted_value(value);
		}
	return text;
}

void write_int_option(FILE *f, gchar *label, gint n)
{
	fprintf(f,"%s: %d\n\n", label, n);
}

gint read_int_option(FILE *f, gchar *option, gchar *label, gchar *value, gint n)
{
	if (!strcasecmp(option, label))
		{
		n = strtol(value,NULL,10);
		}
	return n;
}

void write_bool_option(FILE *f, gchar *label, gint n)
{
	fprintf(f,"%s: ", label);
	if (n) fprintf(f,"true\n"); else fprintf(f,"false\n");
	fprintf(f,"\n");
}

gint read_bool_option(FILE *f, gchar *option, gchar *label, gchar *value, gint n)
{
	if (!strcasecmp(option, label))
		{
		if (!strcasecmp(value, "true"))
			n = TRUE;
		else
			n = FALSE;
		}
	return n;
}

void save_options()
{
	FILE *f;
	gchar *rc_path;
	gchar *rcdir;
	gint i;

	rcdir = g_strconcat(homedir(), "/.gqmpeg", NULL);
	if (!isdir(rcdir))
		{
		printf("Creating gqmpeg dir:%s\n", rcdir);
		if ( (mkdir (rcdir, 0755) < 0) )
			{
			printf("Could not create dir:%s\n", rcdir);
			printf("Config not saved!\n");
			g_free(rcdir);
			return;
			}
		}

	rc_path = g_strconcat(rcdir, "/gqmpegrc", NULL);
	g_free(rcdir);

	f = fopen(rc_path,"w");
	if (!f)
		{
		printf("error saving config file: %s\n", rc_path);
		g_free(rc_path);
		return;
		}

	fprintf(f,"######################################################################\n");
	fprintf(f,"#                         GQmpeg config file           version %d.%d.%d #\n",
		GQMPEG_VERSION_MAJOR, GQMPEG_VERSION_MINOR, GQMPEG_VERSION_REV);
	fprintf(f,"#                                                                    #\n");
	fprintf(f,"#  Everything in this file can be changed in the option dialogs.     #\n");
	fprintf(f,"#      (so there should be no need to edit this file by hand)        #\n");
	fprintf(f,"#                                                                    #\n");
	fprintf(f,"######################################################################\n");

	fprintf(f,"\n##### General Options #####\n\n");

	write_bool_option(f, "playlist_accounting", playlist_accounting);
	write_bool_option(f, "read_header_tags", read_header_tags);

	write_bool_option(f, "smart_window_placement", smart_window_placement);
	write_bool_option(f, "remember_window_position", remember_window_position);
	write_bool_option(f, "wm_decorations", wm_decorations);
	write_bool_option(f, "double_size", double_size_mode);

	write_char_option(f, "mixer_command", mixer_command);
	write_int_option(f, "mixer_device", mixer_device_id);

	write_char_option(f, "default_skin", default_skin);
	write_bool_option(f, "show_extra_winamp_info", show_extra_winamp_info);

	write_bool_option(f, "prev_includes_current_song", prev_includes_current);
	write_bool_option(f, "allow_ipc", allow_ipc);

	fprintf(f,"\n##### Startup Options #####\n\n");

	fprintf(f,"initial_playlist_mode: ");
	if (initial_playlist_mode == PLAYLIST_MODE_EMPTY) fprintf(f,"empty\n");
	if (initial_playlist_mode == PLAYLIST_MODE_SESSION) fprintf(f,"save_session\n");
	if (initial_playlist_mode == PLAYLIST_MODE_FILE) fprintf(f,"open_file\n");

	write_char_option(f, "initial_playlist", initial_playlist_pathname);

	write_bool_option(f, "play_on_startup" , start_playing_on_startup);
	write_bool_option(f, "show_playlist", show_playlist_on_startup);
	write_bool_option(f, "enable_startup_directory", initial_directory_enable);
	write_char_option(f, "startup_directory", initial_directory_path);

	/* save player module data */
	player_modules_config_save(f);

	fprintf(f,"\n##### Playlist options #####\n\n");

	write_bool_option(f, "obey_mode_in_playlist", obey_mode_in_playlist);
	write_bool_option(f, "save_mode_in_playlist", save_mode_in_playlist);
	write_bool_option(f, "show_hidden_files", show_dot_files);
	write_bool_option(f, "show_all_files", disable_filtering);
	write_bool_option(f, "add_single_drops_to_playlist", drop_single_to_playlist);

	fprintf(f,"\n##### Presets #####\n\n");

	write_bool_option(f, "play_presets", play_presets);

	for (i=0; i<10 ; i++)
		{
		fprintf(f,"preset_%d_name: ", i + 1);
		if (preset_name[i]) fprintf(f,"\"%s\"", preset_name[i]);
		fprintf(f, "\n");
		fprintf(f,"preset_%d_file: ", i + 1);
		if (preset_file[i]) fprintf(f,"\"%s\"", preset_file[i]);
		fprintf(f,"\n\n");
		}

	fprintf(f,"\n##### Current state #####\n\n");

	write_int_option(f, "window_position_x", window_pos_x);
	write_int_option(f, "window_position_y", window_pos_y);

	write_int_option(f, "window_list_x", window_list_x);
	write_int_option(f, "window_list_y", window_list_y);
	write_int_option(f, "window_list_width", window_list_w);
	write_int_option(f, "window_list_height", window_list_h);

	write_bool_option(f, "repeat", repeat_mode);
	write_bool_option(f, "shuffle", shuffle_mode);

	write_bool_option(f, "alternate_skin", alternate_skin);
	write_bool_option(f, "show_time_remaining", show_remaining_time);
	write_int_option(f, "initial_playlist_position", initial_playlist_position);

	fprintf(f,"######################################################################\n");
	fprintf(f,"#                      end of GQmpeg config file                     #\n");
	fprintf(f,"######################################################################\n");

	fclose(f);

	g_free(rc_path);
}

void load_options()
{
	FILE *f;
	gchar rc_path[1024];
	gchar s_buf[1024];
	gchar *s_buf_ptr;
	gchar option[1024];
	gchar value[1024];
	gchar value_all[1024];
	gint c,l,i;
	sprintf(rc_path,"%s/.gqmpeg/gqmpegrc",homedir());

	f = fopen(rc_path,"r");
	if (!f)
		{
		/* no file has been created yet */
		sprintf(rc_path,"%s/.gqmpegrc",homedir());
		
		f = fopen(rc_path,"r");
		if (!f)
			{
			return;
			}
		printf ("reading old rc file:%s\n", rc_path);
		printf ("new file will be saved in:%s/.gqmpeg/gqmpegrc on exit\n", homedir());
		}

	while (fgets(s_buf,1024,f))
		{
		if (s_buf[0]=='#') continue;
		if (s_buf[0]=='\n') continue;
		c = 0;
		l = strlen(s_buf);
		while (s_buf[c] != ':' && c < l) c++;
		if (c >= l) continue;
		s_buf[c] = '\0';
		c++;
		while (s_buf[c] == ' ' && c < l) c++;
		while (s_buf[c] == 8 && c < l) c++;
		while (s_buf[c] == ' ' && c < l) c++;
		s_buf_ptr = s_buf + c;
		strcpy(value_all,s_buf_ptr);
		while (s_buf[c] != 8 && s_buf[c] != ' ' && s_buf[c] != '\n' && c < l) c++;
		s_buf[c] = '\0';
		strcpy(option,s_buf);
		strcpy(value,s_buf_ptr);

	/* general options */

		playlist_accounting = read_bool_option(f, option,
			"playlist_accounting", value, playlist_accounting);
		read_header_tags = read_bool_option(f, option,
			"read_header_tags", value, read_header_tags);
	/* this is for backwards compatibility, to be removed for 0.7.0 */
		read_header_tags = read_bool_option(f, option,
			"read_id3_tags", value, read_header_tags);

		smart_window_placement = read_bool_option(f, option,
			"smart_window_placement", value, smart_window_placement);
		remember_window_position = read_bool_option(f, option,
			"remember_window_position", value, remember_window_position);
		wm_decorations = read_bool_option(f, option,
			"wm_decorations", value, wm_decorations);
		double_size_mode = read_bool_option(f, option,
			"double_size", value, double_size_mode);

		mixer_command = read_char_option(f, option,
			"mixer_command", value_all, mixer_command);
		mixer_device_id = read_int_option(f, option,
			"mixer_device", value, mixer_device_id);

		default_skin = read_char_option(f, option,
			"default_skin", value_all, default_skin);
		show_extra_winamp_info = read_bool_option(f, option,
			"show_extra_winamp_info", value, show_extra_winamp_info);

		prev_includes_current = read_bool_option(f, option,
			"prev_includes_current_song", value, prev_includes_current);
		allow_ipc = read_bool_option(f, option,
			"allow_ipc", value, allow_ipc);

	/* startup options */

		if (!strcasecmp(option,"initial_playlist_mode"))
			{
			if (!strcasecmp(value,"empty")) initial_playlist_mode = PLAYLIST_MODE_EMPTY;
			if (!strcasecmp(value,"save_session")) initial_playlist_mode = PLAYLIST_MODE_SESSION;
			if (!strcasecmp(value,"open_file")) initial_playlist_mode = PLAYLIST_MODE_FILE;
			}

		initial_playlist_pathname = read_char_option(f, option,
			"initial_playlist", value_all, initial_playlist_pathname);

		start_playing_on_startup = read_bool_option(f, option,
			"play_on_startup", value, start_playing_on_startup);
		show_playlist_on_startup = read_bool_option(f, option,
			"show_playlist", value, show_playlist_on_startup);
		initial_directory_enable = read_bool_option(f, option,
			"enable_startup_directory", value, initial_directory_enable);
		initial_directory_path = read_char_option(f, option,
			"startup_directory", value_all, initial_directory_path);

	/* load player module data */
	player_modules_config_load(f, option, value, value_all);

	/* playlist */

		obey_mode_in_playlist = read_bool_option(f, option,
			"obey_mode_in_playlist", value, obey_mode_in_playlist);
		save_mode_in_playlist = read_bool_option(f, option,
			"save_mode_in_playlist", value, save_mode_in_playlist);
		show_dot_files = read_bool_option(f, option,
			"show_hidden_files", value, show_dot_files);
		disable_filtering = read_bool_option(f, option,
			"show_all_files", value, disable_filtering);
		drop_single_to_playlist = read_bool_option(f, option,
			"add_single_drops_to_playlist", value, drop_single_to_playlist);

	/* presets */

		play_presets = read_bool_option(f, option,
			"play_presets", value, play_presets);
		if (!strncasecmp(option, "preset_", 7))
			{
			for (i=0; i<10; i++)
				{
				gchar s[32];
				sprintf(s, "preset_%d_name", i+1);
				if (!strcasecmp(option, s))
					{
					g_free (preset_name[i]);
					preset_name[i] = quoted_value(value_all);
					}
				sprintf(s, "preset_%d_file", i+1);
				if (!strcasecmp(option, s))
					{
					g_free (preset_file[i]);
					preset_file[i] = quoted_value(value_all);
					}
				}
			}

	/* current state */

		window_pos_x = read_int_option(f, option,
			"window_position_x", value, window_pos_x);
		window_pos_y = read_int_option(f, option,
			"window_position_y", value, window_pos_y);

		window_list_x = read_int_option(f, option,
			"window_list_x", value, window_list_x);
		window_list_y = read_int_option(f, option,
			"window_list_y", value, window_list_y);
		window_list_w = read_int_option(f, option,
			"window_list_width", value, window_list_w);
		window_list_h = read_int_option(f, option,
			"window_list_height", value, window_list_h);

		repeat_mode = read_bool_option(f, option,
			"repeat", value, repeat_mode);
		shuffle_mode = read_bool_option(f, option,
			"shuffle", value, shuffle_mode);

		alternate_skin = read_bool_option(f, option,
			"alternate_skin", value, alternate_skin);
		show_remaining_time = read_bool_option(f, option,
			"show_time_remaining", value, show_remaining_time);
		initial_playlist_position = read_int_option(f, option,
			"initial_playlist_position", value, initial_playlist_position);
		}

	fclose(f);
}

