#include "io-dump/dump-util.h"
#include "term/term-color-types.h"

TERM_COLOR attr_idx = 0;
SYMBOL_CODE char_idx = 0;

TERM_COLOR attr_idx_feat[F_LIT_MAX];
SYMBOL_CODE char_idx_feat[F_LIT_MAX];

/*
 * @brief シンボル変更処理 / Do visual mode command -- Change symbols
 * @param ch
 * @param visual_list_ptr
 * @param height
 * @param width
 * @param attr_ptr_ptr
 * @param char_left_ptr
 * @param cur_attr_ptr
 * @param cur_char_ptr
 * @param need_redraw
 * @return 何かコマンドを入れたらTRUE
 */
bool visual_mode_command(char ch, bool *visual_list_ptr,
	int height, int width,
	TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
	TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
{
	static TERM_COLOR attr_old = 0;
	static SYMBOL_CODE char_old = 0;

	switch (ch)
	{
	case ESCAPE:
	{
		if (!*visual_list_ptr) return FALSE;

		*cur_attr_ptr = attr_old;
		*cur_char_ptr = char_old;
		*visual_list_ptr = FALSE;
		return TRUE;
	}
	case '\n':
	case '\r':
	{
		if (!*visual_list_ptr) return FALSE;

		*visual_list_ptr = FALSE;
		*need_redraw = TRUE;
		return TRUE;
	}
	case 'V':
	case 'v':
	{
		if (*visual_list_ptr) return FALSE;

		*visual_list_ptr = TRUE;
		*attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
		*char_left_ptr = MAX(0, *cur_char_ptr - 10);
		attr_old = *cur_attr_ptr;
		char_old = *cur_char_ptr;
		return TRUE;
	}
	case 'C':
	case 'c':
	{
		attr_idx = *cur_attr_ptr;
		char_idx = *cur_char_ptr;
		for (int i = 0; i < F_LIT_MAX; i++)
		{
			attr_idx_feat[i] = 0;
			char_idx_feat[i] = 0;
		}

		return TRUE;
	}
	case 'P':
	case 'p':
	{
		if (attr_idx || (!(char_idx & 0x80) && char_idx))
		{
			*cur_attr_ptr = attr_idx;
			*attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
			if (!*visual_list_ptr) *need_redraw = TRUE;
		}

		if (char_idx)
		{
			/* Set the char */
			*cur_char_ptr = char_idx;
			*char_left_ptr = MAX(0, *cur_char_ptr - 10);
			if (!*visual_list_ptr) *need_redraw = TRUE;
		}

		return TRUE;
	}
	default:
	{
		if (!*visual_list_ptr) return FALSE;

		int eff_width;
		int d = get_keymap_dir(ch);
		TERM_COLOR a = (*cur_attr_ptr & 0x7f);
		SYMBOL_CODE c = *cur_char_ptr;

		if (use_bigtile) eff_width = width / 2;
		else eff_width = width;

		if ((a == 0) && (ddy[d] < 0)) d = 0;
		if ((c == 0) && (ddx[d] < 0)) d = 0;
		if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
		if (((byte)c == 0xff) && (ddx[d] > 0)) d = 0;

		a += (TERM_COLOR)ddy[d];
		c += (SYMBOL_CODE)ddx[d];
		if (c & 0x80) a |= 0x80;

		*cur_attr_ptr = a;
		*cur_char_ptr = c;
		if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
		if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
		if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
		if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;

		return TRUE;
	}
	}
}


/*!
 * @brief ダンプ用の一時ファイルを開く
 * @param fff 一時ファイルへの参照ポインタ
 * @param file_name ファイル名
 * @return ファイルを開けたらTRUE、開けなかったらFALSE
 * @details 
 */
bool open_temporary_file(FILE **fff, char *file_name)
{
	*fff = my_fopen_temp(file_name, FILE_NAME_SIZE);
	if (*fff != NULL) return TRUE;

	msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
	msg_print(NULL);
	return FALSE;
}


/*!
 * @brief モンスター情報リスト中のグループを表示する /
 * Display the object groups.
 * @param col 開始行
 * @param row 開始列
 * @param wid 表示文字数幅
 * @param per_page リストの表示行
 * @param grp_idx グループのID配列
 * @param group_text グループ名の文字列配列
 * @param grp_cur 現在の選択ID
 * @param grp_top 現在の選択リスト最上部ID
 * @return なし
 */
void display_group_list(int col, int row, int wid, int per_page, IDX grp_idx[], concptr group_text[], int grp_cur, int grp_top)
{
	for (int i = 0; i < per_page && (grp_idx[i] >= 0); i++)
	{
		int grp = grp_idx[grp_top + i];
		TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
		Term_erase(col, row + i, wid);
		c_put_str(attr, group_text[grp], row + i, col);
	}
}


/*
 * Display visuals.
 */
void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
{
	for (int i = 0; i < height; i++)
	{
		Term_erase(col, row + i, width);
	}

	if (use_bigtile) width /= 2;

	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			TERM_LEN x = col + j;
			TERM_LEN y = row + i;
			if (use_bigtile) x += j;

			int ia = attr_top + i;
			int ic = char_left + j;
			if (ia > 0x7f || ic > 0xff || ic < ' ' ||
				(!use_graphics && ic > 0x7f))
				continue;

			TERM_COLOR a = (TERM_COLOR)ia;
			SYMBOL_CODE c = (SYMBOL_CODE)ic;
			if (c & 0x80) a |= 0x80;

			Term_queue_bigchar(x, y, a, c, 0, 0);
		}
	}
}


/*
 * Place the cursor at the collect position for visual mode
 */
void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
{
	int i = (a & 0x7f) - attr_top;
	int j = c - char_left;

	TERM_LEN x = col + j;
	TERM_LEN y = row + i;
	if (use_bigtile) x += j;

	Term_gotoxy(x, y);
}


/*
 * Move the cursor in a browser window
 */
void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt, IDX *list_cur, int list_cnt)
{
	int d;
	int col = *column;
	IDX grp = *grp_cur;
	IDX list = *list_cur;
	if (ch == ' ')
		d = 3;
	else if (ch == '-')
		d = 9;
	else
		d = get_keymap_dir(ch);

	if (!d) return;

	if ((ddx[d] > 0) && ddy[d])
	{
		int browser_rows;
		int wid, hgt;
		Term_get_size(&wid, &hgt);
		browser_rows = hgt - 8;
		if (!col)
		{
			int old_grp = grp;
			grp += ddy[d] * (browser_rows - 1);
			if (grp >= grp_cnt)	grp = grp_cnt - 1;
			if (grp < 0) grp = 0;
			if (grp != old_grp)	list = 0;
		}
		else
		{
			list += ddy[d] * browser_rows;
			if (list >= list_cnt) list = list_cnt - 1;
			if (list < 0) list = 0;
		}

		(*grp_cur) = grp;
		(*list_cur) = list;
		return;
	}

	if (ddx[d])
	{
		col += ddx[d];
		if (col < 0) col = 0;
		if (col > 1) col = 1;

		(*column) = col;
		return;
	}

	if (!col)
	{
		int old_grp = grp;
		grp += (IDX)ddy[d];
		if (grp >= grp_cnt)	grp = grp_cnt - 1;
		if (grp < 0) grp = 0;
		if (grp != old_grp)	list = 0;
	}
	else
	{
		list += (IDX)ddy[d];
		if (list >= list_cnt) list = list_cnt - 1;
		if (list < 0) list = 0;
	}

	(*grp_cur) = grp;
	(*list_cur) = list;
}
