/*
 * $Id: m_msg_control.c,v 1.1 2003/06/06 00:15:12 tong Exp $
 *
 *	メッセージ表示のライブラリーのインクルードソースファイル
 *
 * $Log: m_msg_control.c,v $
 * Revision 1.1  2003/06/06 00:15:12  tong
 * source files for localization from Nintendo.
 *
 * Revision 1.36  2001-01-27 20:02:24+09  sakakibara
 * アイテム受け渡し 開始、終了 命令追加。
 *
 * Revision 1.35  2001-01-18 13:54:54+09  sakakibara
 * disappear_wait_type2
 *
 * Revision 1.34  2001-01-05 13:09:56+09  sakakibara
 * pf5 も色指定。
 *
 * Revision 1.33  2000-12-13 21:38:02+09  sakakibara
 * *** empty log message ***
 *
 * Revision 1.32  2000-12-13 13:50:25+09  sakakibara
 * *** empty log message ***
 *
 * Revision 1.31  2000-12-12 23:58:21+09  sakakibara
 * 自由文字列色指定
 *
 * Revision 1.30  2000-12-12 13:31:52+09  sakakibara
 * *** empty log message ***
 *
 * Revision 1.29  2000-12-11 22:41:45+09  sakakibara
 * *** empty log message ***
 *
 * Revision 1.28  2000-09-23 15:34:35+09  sakakibara
 * メッセージ番号取得関数作成。
 *
 */
/*************ウインドウの制御の処理******************/

/*
 ***************************************************************
 *	ベースとなるウインドウデータへのポインタをゲット
 ***************************************************************
 */
extern M_MSG_WIN *mMsg_Get_base_window_p(void)
{
    return(&(mMsg_window[0]));
}

/*
 ****************************************************************
 *	メッセージのメイン処理変更の優先順位が有効かを調べる
 ****************************************************************
 */
extern int mMsg_Check_request_priority(M_MSG_WIN *win_p, int request_priority)
{
    int priority = win_p->request_priority;
    return(request_priority > priority);
}

/*
 ****************************************************************
 *	メッセージのメイン処理変更を要求
 ****************************************************************
 */
static int mMsg_Change_request_main_index(M_MSG_WIN *win_p,
					  int request_main_index,
					  int request_priority)
{
    /* メッセージのメイン処理変更の優先順位が有効かを調べる */
    if(mMsg_Check_request_priority(win_p, request_priority)) {
	/* リクエストされたメイン処理のインデックス */
	win_p->request_main_index = request_main_index;
	/* リクエスト優先順位 */
	win_p->request_priority = request_priority;
	return(TRUE);
    }
    return(FALSE);
}

/*
 ****************************************************************
 *	メッセージのメイン処理が"main_index"と一致するか調べる
 ****************************************************************
 */
extern int mMsg_Check_main_index(M_MSG_WIN *win_p, int main_index)
{
    return(win_p->main_index == main_index);
}

/*
 ****************************************************************
 *	メッセージのメイン処理が"待機"状態かを調べる
 ****************************************************************
 */
extern int mMsg_Check_main_wait(M_MSG_WIN *win_p)
{
    return(mMsg_Check_main_index(win_p, M_MSG_MAIN_WAIT));
}

/*
 ****************************************************************
 *	メッセージのメイン処理が"待機シリーズ"状態かを調べる
 ****************************************************************
 */
extern int mMsg_Check_not_series_main_wait(M_MSG_WIN *win_p)
{
    return(
	!(mMsg_Check_main_index(win_p, M_MSG_MAIN_WAIT) ||
	  mMsg_Check_main_index(win_p, M_MSG_MAIN_APPEAR_WAIT) ||
	  mMsg_Check_main_index(win_p, M_MSG_MAIN_DISAPPEAR_WAIT))
	);
}

/*
 ****************************************************************
 *	メッセージのメイン処理が"隠れ"状態かを調べる
 ****************************************************************
 */
extern int mMsg_Check_main_hide(M_MSG_WIN *win_p)
{
    return(mMsg_Check_main_index(win_p, M_MSG_MAIN_HIDE));
}

/*
 ****************************************************************
 *	メッセージのクライアント(話し手)を登録
 ****************************************************************
 */
static void mMsg_Set_client_actor_p(M_MSG_WIN *win_p,
				    ACTOR *client_actor_p,
				    int display_name)
{
    if(client_actor_p) {
	win_p->client_actor_p = client_actor_p;
	win_p->display_name = display_name;

	{
	    float width;
	    float max_width = ((float)PERSON_NAME_NUM) * M_FONT_1TEXSIZE_DOT_S_F;
	    float offsetX;
	    unchar name[PERSON_NAME_NUM];
	    int index;

	    /** 2000. 2. 8. gen */
	    mNpc_GetNpcWorldName(name, client_actor_p);
	    index = mMsg_Get_Length_String(name, PERSON_NAME_NUM);
	    width = (float)mFont_GetStringWidth(name, index, FALSE);
	    offsetX = (max_width - width) / 2.0F;
	    win_p->client_name_rectX = M_MSG_CLIENT_NAME_BASEX_F + offsetX;
	    win_p->client_name_rectY = M_MSG_CLIENT_NAME_BASEY_F;
	    win_p->client_name_total = index;
	}
    }
    else {
	win_p->client_actor_p = NULL;
	win_p->display_name = FALSE;
    }
}

/*
 ****************************************************************
 *	メッセージのメイン処理を隠れに強制変更要求
 ****************************************************************
 */
extern int mMsg_request_main_forceoff(void)
{
    return(mMsg_Change_request_main_index(mMsg_Get_base_window_p(),
					  M_MSG_MAIN_HIDE,
					  M_MSG_REQUEST_PRIORITY_MAXIMAM));
}

/*
 ****************************************************************
 *	メッセージのメイン処理を出現に変更要求
 ****************************************************************
 */
extern int mMsg_request_main_appear(M_MSG_WIN *win_p,
				    ACTOR *client_actor_p,
				    int display_name,
				    rgba_t *window_color_p,
				    int msg_num,
				    int request_priority)
{
    if(mMsg_Change_request_main_index(win_p,
				      M_MSG_MAIN_APPEAR,
				      request_priority)) {
	M_MSG_REQUEST_MAIN_APPEAR_DATA	*request_main_data_appear_p = &(win_p->request_main_data.appear);

	request_main_data_appear_p->client_actor_p = client_actor_p;
	request_main_data_appear_p->display_name = display_name;
	request_main_data_appear_p->window_color = *window_color_p;
	request_main_data_appear_p->msg_num = msg_num;
	
	return(TRUE);
    }
    return(FALSE);
}

/*
 ****************************************************************
 *	メッセージのメイン処理を"消滅(待機へ)"に変更要求
 ****************************************************************
 */
static int mMsg_request_main_disappear_wait(M_MSG_WIN *win_p,
					    int back_main_index,
					    int request_priority)
{
    if(mMsg_Change_request_main_index(win_p,
				      M_MSG_MAIN_DISAPPEAR_WAIT,
				      request_priority)) {
	M_MSG_REQUEST_MAIN_DISAPPEAR_WAIT_DATA	*request_main_disappear_wait_data_p = &(win_p->request_main_data.disappear_wait);
	
	/* メイン処理インデックスのバックアップ */
	request_main_disappear_wait_data_p->back_main_index = back_main_index;
	return(TRUE);
    }
    return(FALSE);
}

/*
 *	メッセージのメイン処理を"消滅(待機へ)"に変更要求サブ
 */
static int mMsg_request_main_disappear_wait_sub(M_MSG_WIN *win_p, int back_main_index)
{
    if (mChoice_check_main_index(mChoice_Get_base_window_p()) == M_CHOICE_MAIN_HIDE) {
	return mMsg_request_main_disappear_wait(win_p,
						back_main_index,
						M_MSG_REQUEST_PRIORITY_NORMAL);
    } else {
#if DEBUG
	PRINTF(ESC_WARNING
	       "mMsg_request_main_disappear_wait_sub:選択肢を選び終わってから！！！！\n"
	       ESC_NORMAL);
#endif
	return FALSE;
    }
}

/*
 ****************************************************************
 *	外部からメッセージのメイン処理を"消滅(待機へ)"に変更要求
 ****************************************************************
 */
extern int mMsg_request_main_disappear_wait_type1(M_MSG_WIN *win_p)
{
    return mMsg_request_main_disappear_wait_sub(win_p, win_p->main_index);
}

/*
 *	外部からメッセージのメイン処理を「消滅(待機へ)」に変更要求
 *	(出現(待機から)の後、強制的にノーマルにするの)
 */
extern int mMsg_request_main_disappear_wait_type2(M_MSG_WIN *win_p)
{
    return mMsg_request_main_disappear_wait_sub(win_p, M_MSG_MAIN_NORMAL);
}

/*
 ****************************************************************
 *	メッセージのメイン処理を"待機"に変更要求
 ****************************************************************
 */
static int mMsg_request_main_wait(M_MSG_WIN *win_p,
				  int back_main_index,
				  int request_priority)
{
    if(mMsg_Change_request_main_index(win_p,
				      M_MSG_MAIN_WAIT,
				      request_priority)) {
	M_MSG_REQUEST_MAIN_WAIT_DATA	*request_main_wait_data_p = &(win_p->request_main_data.wait);
	
	/* メイン処理インデックスのバックアップ */
	request_main_wait_data_p->back_main_index = back_main_index;
	return(TRUE);
    }
    return(FALSE);
}

/*
 ****************************************************************
 *	メッセージのメイン処理を"出現(待機から)"に変更要求
 ****************************************************************
 */
static int mMsg_request_main_appear_wait(M_MSG_WIN *win_p,
					 int back_main_index,
					 u32 flag,
					 int request_priority)
{
    if(mMsg_Change_request_main_index(win_p,
				      M_MSG_MAIN_APPEAR_WAIT,
				      request_priority)) {
	M_MSG_REQUEST_MAIN_APPEAR_WAIT_DATA	*request_main_appear_wait_data_p = &(win_p->request_main_data.appear_wait);
	
	/* メイン処理インデックスのバックアップ */
	request_main_appear_wait_data_p->back_main_index = back_main_index;
	request_main_appear_wait_data_p->flag = flag;
	return(TRUE);
    }
    return(FALSE);
}

/*
 ****************************************************************
 *	外部からメッセージのメイン処理を"出現(待機から)"に変更要求
 ****************************************************************
 */
/* 画面クリヤー制御有り */
extern int mMsg_request_main_appear_wait_type2(M_MSG_WIN *win_p, int clear)
{
    int main_index = win_p->main_index;
    
    if(main_index == M_MSG_MAIN_WAIT) {
	M_MSG_MAIN_WAIT_DATA *main_wait_data_p = &(win_p->main_data.wait);
	int back_main_index = main_wait_data_p->back_main_index;
	u32 flag = clear ? (u32)M_MSG_INIT_APPEAR_WAIT_CLEAR_CURSOL : (u32)M_MSG_INIT_ELEMENT_NONE_INSETUP;
	
	return(mMsg_request_main_appear_wait(win_p,
					     back_main_index,
					     flag,
					     M_MSG_REQUEST_PRIORITY_NORMAL));
    }
    else {
#if DEBUG
	PRINTF(ESC_WARNING
	       "mMsg_request_main_appear_wait_type1:待機状態出はない！！！！！！！！！！！！！\n"
	       ESC_NORMAL);
#endif
	return(FALSE);
    }
}

/* 強制的に画面クリヤー */
extern int mMsg_request_main_appear_wait_type1(M_MSG_WIN *win_p)
{
    return(mMsg_request_main_appear_wait_type2(win_p, TRUE));
}

/*
 ****************************************************************
 *	メッセージのメイン処理を"通常"に変更要求
 ****************************************************************
 */
static int mMsg_request_main_normal(M_MSG_WIN *win_p,
				    s32 flag,
				    int request_priority)
{
    if(mMsg_Change_request_main_index(win_p,
				      M_MSG_MAIN_NORMAL,
				      request_priority)) {
	M_MSG_REQUEST_MAIN_NORMAL_DATA	*request_main_normal_data_p = &(win_p->request_main_data.normal);
	
	/* メイン処理インデックスのバックアップ */
	request_main_normal_data_p->flag = flag;
	return(TRUE);
    }
    return(FALSE);
}

/*
 ****************************************************************
 *	メッセージのメイン処理を"カーソル表示"に変更要求
 ****************************************************************
 */
static int mMsg_request_main_cursol(M_MSG_WIN *win_p,
				    s32 flag,
				    int request_priority)
{
    if(mMsg_Change_request_main_index(win_p,
				      M_MSG_MAIN_CURSOL,
				      request_priority)) {
	M_MSG_REQUEST_MAIN_CURSOL_DATA	*request_main_cursol_data_p = &(win_p->request_main_data.cursol);
	
	/* メイン処理インデックスのバックアップ */
	request_main_cursol_data_p->flag = flag;
	return(TRUE);
    }
    return(FALSE);
}

/*
 ****************************************************************
 *	会話用文字列変換テーブルにセット
 ****************************************************************
 */
/*
 *	Original
 */
extern void mMsg_Set_free_str(M_MSG_WIN *win_p,
			      int string_num,	/* 文字列の番号("0"から
						   "M_MSG_TOTAL_PUT_FREE_STRINGS-1"まで) */
			      unchar *str_p,	/* コピーする文字列 */
			      int total_code)	/* 文字数 */
{
    if((0 <= string_num) && (string_num < M_MSG_TOTAL_PUT_FREE_STRINGS) && (str_p != NULL)) {
	int i;
	unchar *free_str_p = win_p->free_str[string_num];
	
	if(total_code > M_MSG_PUT_FREE_STRINGS_LENGTH) {
#if DEBUG
	    PRINTF(ESC_WARNING
		   "mMsg_Set_free_str:文字列でかすぎ!!!!\n"
		   ESC_NORMAL);
#endif
	    total_code = M_MSG_PUT_FREE_STRINGS_LENGTH;
	}
	
	for(i = 0; i < M_MSG_PUT_FREE_STRINGS_LENGTH; i++) {
	    if(i < total_code) {
		free_str_p[i] = str_p[i];
	    }
	    else {
		/* 余った所は空白 */
		free_str_p[i] = MOJI_SPACE1;
	    }
	}
    }
#if DEBUG
    else {
	PRINTF(ESC_WARNING
	       "mMsg_Set_free_str:文字列の指定番号か文字列ポインタがおかしい!!!!\n"
	       ESC_NORMAL);
    }
#endif
    
    /* カラーＩＤテーブルクリア */
    if (string_num == 1) {
	win_p->free_str_cl_id[mMSG_PF_CL_TBL_1] = mMSG_Pf_CL_ID_NONE;
    } else if (string_num == 2) {
	win_p->free_str_cl_id[mMSG_PF_CL_TBL_2] = mMSG_Pf_CL_ID_NONE;
    } else if (string_num == 5) {
	win_p->free_str_cl_id[mMSG_PF_CL_TBL_5] = mMSG_Pf_CL_ID_NONE;
    }
}

/*
 *	色付
 */
extern void mMsg_Set_free_str_cl(M_MSG_WIN *win_p,
				 int string_num,	/* 文字列の番号 */
				 unchar *str_p,		/* コピー元 文字列 */
				 int total_code,	/* 文字数 */
				 mMSG_Pf_Cl_Id color_id)
{
    /* 自由文字列設定 (Original Function Call) */
    mMsg_Set_free_str(win_p, string_num, str_p, total_code);
    
    /*  */
    if (color_id != mMSG_Pf_CL_ID_NONE) {
	/* カラーＩＤセット */
	if (string_num == 1) {
	    win_p->free_str_cl_id[mMSG_PF_CL_TBL_1] = (unchar)color_id;
	} else if (string_num == 2) {
	    win_p->free_str_cl_id[mMSG_PF_CL_TBL_2] = (unchar)color_id;
	} else if (string_num == 5) {
	    win_p->free_str_cl_id[mMSG_PF_CL_TBL_5] = (unchar)color_id;
	}
#if DEBUG
	else {
	    PRINTF(ESC_ERROR
		   "自由文字列色処理はＰＦ１,２,５のみ用意している。(%s %d)\n"
		   ESC_NORMAL, __FILE__, __LINE__);
	}
#endif
    }
}

/*
 ****************************************************************
 *	アイテム用文字列変換テーブルにセット
 ****************************************************************
 */
extern void mMsg_Set_item_str(M_MSG_WIN *win_p,
			      int string_num,	/* 文字列の番号("0"から
						   "M_MSG_TOTAL_PUT_ITEM_STRINGS-1"まで) */
			      unchar *str_p,	/* コピーする文字列 */
			      int total_code)	/* 文字数 */
{
    if((0 <= string_num) && (string_num < M_MSG_TOTAL_PUT_ITEM_STRINGS) && (str_p != NULL)) {
	int i;
	unchar *item_str_p = win_p->item_str[string_num];
	
	if(total_code > mIN_ITEM_NAME_NUM) {
#if DEBUG
	    PRINTF(ESC_WARNING
		   "mMsg_Set_item_str:文字列でかすぎ!!!!\n"
		   ESC_NORMAL);
#endif
	    total_code = mIN_ITEM_NAME_NUM;
	}
	
	for(i = 0; i < mIN_ITEM_NAME_NUM; i++) {
	    if(i < total_code) {
		item_str_p[i] = str_p[i];
	    }
	    else {
		/* 余った所は空白 */
		item_str_p[i] = MOJI_SPACE1;
	    }
	}
    }
#if DEBUG
    else {
	PRINTF(ESC_WARNING
	       "mMsg_Set_item_str:文字列の指定番号か文字列ポインタがおかしい!!!!\n"
	       ESC_NORMAL);
    }
#endif
}

/*
 ****************************************************************
 *	会話用文字列変換テーブルの内容をゲット
 ****************************************************************
 */
extern void mMsg_Get_free_str(M_MSG_WIN *win_p,
			      int string_num,	/* 文字列の番号("0"から
						   "M_MSG_TOTAL_PUT_FREE_STRINGS-1"まで) */
			      unchar *str_p)	/* 代入する文字列
						   (M_MSG_PUT_FREE_STRINGS_LENGTHの大きさが要る) */
{
    if((0 <= string_num) && (string_num < M_MSG_TOTAL_PUT_FREE_STRINGS) && (str_p != NULL)) {
	int i;
	unchar *free_str_p = win_p->free_str[string_num];
	
	for(i = 0; i < M_MSG_PUT_FREE_STRINGS_LENGTH; i++) {
	    str_p[i] = free_str_p[i];
	}
    }
#if DEBUG
    else {
	PRINTF(ESC_WARNING
	       "mMsg_Get_free_str:文字列の指定番号か文字列ポインタがおかしい!!!!\n"
	       ESC_NORMAL);
    }
#endif
}

/*
 ****************************************************************
 *	アイテム用文字列変換テーブルの内容をゲット
 ****************************************************************
 */
extern void mMsg_Get_item_str(M_MSG_WIN *win_p,
			      int string_num,	/* 文字列の番号("0"から
						   "M_MSG_TOTAL_PUT_ITEM_STRINGS-1"まで) */
			      unchar *str_p)	/* 代入する文字列
						   (mIN_ITEM_NAME_NUMの大きさが要る) */
{
    if((0 <= string_num) && (string_num < M_MSG_TOTAL_PUT_ITEM_STRINGS) && (str_p != NULL)) {
	int i;
	unchar *item_str_p = win_p->item_str[string_num];
	
	for(i = 0; i < mIN_ITEM_NAME_NUM; i++) {
	    str_p[i] = item_str_p[i];
	}
    }
#if DEBUG
    else {
	PRINTF(ESC_WARNING
	       "mMsg_Get_item_str:文字列の指定番号か文字列ポインタがおかしい!!!!\n"
	       ESC_NORMAL);
    }
#endif
}

/*
 ****************************************************************
 *	手紙用文字列変換テーブルにセット
 ****************************************************************
 */
extern void mMsg_Set_mail_str(M_MSG_WIN *win_p,
			      int string_num,	/* 文字列の番号("0"から
						   "M_MSG_TOTAL_PUT_MAIL_STRINGS-1"まで) */
			      unchar *str_p,	/* コピーする文字列 */
			      int total_code)	/* 文字数 */
{
    if((0 <= string_num) && (string_num < M_MSG_TOTAL_PUT_MAIL_STRINGS) && (str_p != NULL)) {
	
	if(total_code > M_MSG_PUT_MAIL_STRINGS_LENGTH) {
#if DEBUG
	    PRINTF(ESC_WARNING
		   "mMsg_Set_mail_str:文字列でかすぎ!!!!\n"
		   ESC_NORMAL);
#endif
	    total_code = M_MSG_PUT_MAIL_STRINGS_LENGTH;
	}

	/* 改行を付加する */
	{
	    int src_index;
	    int domain_index = 0;
	    unchar *domain_data_p = win_p->mail_str[string_num];
	    unchar *src_data_p = str_p;
	    int total_line = 0;
	    int total_column = 0;
	    
	    for(src_index = 0; src_index < total_code; src_index++) {
		unchar code = *src_data_p++;

		if(code == MOJI_RETURN) {
		    total_line++;
		    *domain_data_p++ = code;
		    domain_index++;
		    total_column = 0;

		    if((domain_index >= M_MSG_PUT_MAIL_STRINGS_LENGTH) || (total_line > 4)) {
			break;
		    }
		}
		else {
		    *domain_data_p++ = code;
		    domain_index++;
		    total_column++;

		    if(domain_index >= M_MSG_PUT_MAIL_STRINGS_LENGTH) {
			break;
		    }
		    else if(total_column >= 16) {	/* 横１６文字を越えた */
			total_line++;
			*domain_data_p++ = MOJI_RETURN;
			domain_index++;
			total_column = 0;

			if((domain_index >= M_MSG_PUT_MAIL_STRINGS_LENGTH) || (total_line > 4)) {
			    break;
			}
		    }
		}
	    }
	    for(; domain_index < M_MSG_PUT_MAIL_STRINGS_LENGTH; domain_index++) {
		/* 余った所は空白 */
		*domain_data_p++ = MOJI_SPACE1;
	    }
	}
    }
#if DEBUG
    else {
	PRINTF(ESC_WARNING
	       "mMsg_Set_mail_str:文字列の指定番号か文字列ポインタがおかしい!!!!\n"
	       ESC_NORMAL);
    }
#endif
}


/*
 ****************************************************************
 *	継続メッセージの番号セット
 ****************************************************************
 */
#if DEBUG
extern void DEBUG_mMsg_Set_continue_msg_num(M_MSG_WIN *win_p, int msg_num,
					    const char *file,
					    int line)
{
    (void)file; (void)line;
    
#if 1
    if (mREG(31) == 2) {
	PRINTF("~~~~~~~~~~継続メッセージの番号セット<%d>(%s %d)[%d](from :: %s %d)\n",
	       msg_num, __FILE__, __LINE__, getP_game()->frame_counter, file, line);
    }
#endif
    win_p->continue_msg_num = msg_num;
}
#else
extern void mMsg_Set_continue_msg_num(M_MSG_WIN *win_p, int msg_num)
{
    win_p->continue_msg_num = msg_num;
}
#endif


/*
 ****************************************************************
 *	現在のメッセージ番号を取得する。
 ****************************************************************
 */
extern int mMsg_Get_msg_num(M_MSG_WIN *win_p)
{
    M_MSG_DATA *msg_p = win_p->msg_p;
    
    if ((win_p->able) && (msg_p->able)) {
	return (msg_p->num);
    } else {
	return -1;
    }
}


/*
 *	アイテム受け渡し中であるかのチェック
 */
static int mMsg_Check_give_item(void)
{
    /*
     *	領域確保されている ?
     *	アイテム受け渡ししている ?
     */
    return ((aHOI_CLIP_P != NULL) &&
	    (aHOI_MASTER_ACTOR_P != NULL));
}
