/*!
 * @brief 自動拾いにアイテムを登録する
 * @date 2020/04/26
 * @author Hourier
 */
 
#include "autopick/autopick-registry.h"
#include "autopick/autopick-entry.h"
#include "autopick/autopick-finder.h"
#include "autopick/autopick-methods-table.h"
#include "autopick/autopick-reader-writer.h"
#include "io/files-util.h"
#include "object-enchant/item-feeling.h"
#include "perception/object-perception.h"
#include "object/object-flavor.h"
#include "object/object-hook.h"
#include "object-enchant/special-object-flags.h"
#include "util/util.h"

static const char autoregister_header[] = "?:$AUTOREGISTER";

/*
 *  Clear auto registered lines in the picktype.prf .
 */
static bool clear_auto_register(player_type *player_ptr)
{
	char pref_file[1024];
	path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_WITH_PNAME));
	FILE *pref_fff;
	pref_fff = my_fopen(pref_file, "r");

	if (!pref_fff)
	{
		path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_DEFAULT));
		pref_fff = my_fopen(pref_file, "r");
	}

	if (!pref_fff)
	{
		return TRUE;
	}

	char tmp_file[1024];
	FILE *tmp_fff;
	tmp_fff = my_fopen_temp(tmp_file, sizeof(tmp_file));
	if (!tmp_fff)
	{
		fclose(pref_fff);
		msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
		msg_print(NULL);
		return FALSE;
	}

	bool autoregister = FALSE;
	int num = 0;
	char buf[1024];
	while (TRUE)
	{
		if (my_fgets(pref_fff, buf, sizeof(buf))) break;

		if (autoregister)
		{
			if (buf[0] != '#' && buf[0] != '?') num++;
			continue;
		}

		if (streq(buf, autoregister_header))
		{
			autoregister = TRUE;
		}
		else
		{
			fprintf(tmp_fff, "%s\n", buf);
		}
	}

	my_fclose(pref_fff);
	my_fclose(tmp_fff);

	bool okay = TRUE;
	if (num)
	{
		msg_format(_("以前のキャラクター用の自動設定(%d行)が残っています。",
			"Auto registered lines (%d lines) for previous character are remaining."), num);
		strcpy(buf, _("古い設定行は削除します。よろしいですか？", "These lines will be deleted.  Are you sure? "));

		if (!get_check(buf))
		{
			okay = FALSE;
			autoregister = FALSE;

			msg_print(_("エディタのカット&ペースト等を使って必要な行を避難してください。",
				"Use cut & paste of auto picker editor (_) to keep old prefs."));
		}
	}

	if (autoregister)
	{
		tmp_fff = my_fopen(tmp_file, "r");
		pref_fff = my_fopen(pref_file, "w");

		while (!my_fgets(tmp_fff, buf, sizeof(buf)))
			fprintf(pref_fff, "%s\n", buf);

		my_fclose(pref_fff);
		my_fclose(tmp_fff);
	}

	fd_kill(tmp_file);
	return okay;
}


/*
 *  Automatically register an auto-destroy preference line
 */
bool autopick_autoregister(player_type *player_ptr, object_type *o_ptr)
{
	autopick_type an_entry, *entry = &an_entry;
	int match_autopick = find_autopick_list(player_ptr, o_ptr);
	if (match_autopick != -1)
	{
		concptr what;
		byte act = autopick_list[match_autopick].action;
		if (act & DO_AUTOPICK) what = _("自動で拾う", "auto-pickup");
		else if (act & DO_AUTODESTROY) what = _("自動破壊する", "auto-destroy");
		else if (act & DONT_AUTOPICK) what = _("放置する", "leave on floor");
		else what = _("確認して拾う", "query auto-pickup");

		msg_format(_("そのアイテムは既に%sように設定されています。", "The object is already registered to %s."), what);
		return FALSE;
	}

	if ((object_is_known(o_ptr) && object_is_artifact(o_ptr)) ||
		((o_ptr->ident & IDENT_SENSE) &&
		(o_ptr->feeling == FEEL_TERRIBLE || o_ptr->feeling == FEEL_SPECIAL)))
	{
		GAME_TEXT o_name[MAX_NLEN];
		object_desc(player_ptr, o_name, o_ptr, 0);
		msg_format(_("%sは破壊不能だ。", "You cannot auto-destroy %s."), o_name);
		return FALSE;
	}

	if (!player_ptr->autopick_autoregister)
	{
		if (!clear_auto_register(player_ptr)) return FALSE;
	}

	char buf[1024];
	char pref_file[1024];
	FILE *pref_fff;
	path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_WITH_PNAME));
	pref_fff = my_fopen(pref_file, "r");

	if (!pref_fff)
	{
		path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_DEFAULT));
		pref_fff = my_fopen(pref_file, "r");
	}

	if (pref_fff)
	{
		while (TRUE)
		{
			if (my_fgets(pref_fff, buf, sizeof(buf)))
			{
				player_ptr->autopick_autoregister = FALSE;
				break;
			}

			if (streq(buf, autoregister_header))
			{
				player_ptr->autopick_autoregister = TRUE;
				break;
			}
		}

		fclose(pref_fff);
	}
	else
	{
		/*
		 * File could not be opened for reading.  Assume header not
		 * present.
		 */
		player_ptr->autopick_autoregister = FALSE;
	}

	pref_fff = my_fopen(pref_file, "a");
	if (!pref_fff)
	{
		msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), pref_file);
		msg_print(NULL);
		return FALSE;
	}

	if (!player_ptr->autopick_autoregister)
	{
		fprintf(pref_fff, "%s\n", autoregister_header);

		fprintf(pref_fff, "%s\n", _("# *警告!!* 以降の行は自動登録されたものです。",
			"# *Warning!* The lines below will be deleted later."));
		fprintf(pref_fff, "%s\n", _("# 後で自動的に削除されますので、必要な行は上の方へ移動しておいてください。",
			"# Keep it by cut & paste if you need these lines for future characters."));
		player_ptr->autopick_autoregister = TRUE;
	}

	autopick_entry_from_object(player_ptr, entry, o_ptr);
	entry->action = DO_AUTODESTROY;
	add_autopick_list(entry);

	concptr tmp = autopick_line_from_entry(entry);
	fprintf(pref_fff, "%s\n", tmp);
	string_free(tmp);
	fclose(pref_fff);
	return TRUE;
}
