#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
#include <wchar.h>
#include <ncursesw/ncurses.h>
#include <regex.h>

#include	"env.h"
#include	"utils/nt_std_t.h"
#include	"utils/text.h"
#include	"_2ch/_2ch.h"
#include	"_2ch/model_2ch.h"
#include	"ui/disp.h"
#include	"ui/disp_string.h"

typedef struct tag_ctx_reslist_t *ctx_reslist_tp;
typedef struct tag_ctx_reslist_t
{
	int res_num;
	int cur_res;
	int cur_res_offset;
	int max_cur_res;
	int max_cur_offset;
	nt_stack_tp	selected_num_stackp;

	regex_t regex;
	BOOL regex_init;
	int sel_res_no;
	int sel_res_line;

} ctx_reslist_t;


static ctx_reslist_tp init_context(nt_2ch_model_tp modelp);
static void int_ptr_free(void *ptr);
static BOOL parse_cmd1(const char *param, int *statep);
static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp, 
			int *sel_res_no, int *sel_res_line, int column);
static BOOL search_line_desc(regex_t *regexp, ctx_reslist_tp ctxp,
			nt_link_tp reslistp, 
			int *sel_res_no, int *sel_res_line, int column);

int disp_reslist(nt_window_tp wp, nt_2ch_model_tp modelp)
{
	ctx_reslist_tp ctxp;
	nt_res_tp resp;
	nt_thread_tp threadp;
	nt_link_tp clistp;
	int i, rows;
	int wlines;
	int len, ch;
	int num;
	int res_offset;
	int *nptr;
	void *ptr;
	wchar_t buf[1024*3+1];
	wchar_t *cptr;
	nt_link_tp link_curp;
	int state;
	BOOL search_asc;
	BOOL adjust;
	BOOL set_value;
	int line_num;

	ctxp = (ctx_reslist_tp)wp->data;
	if(!ctxp){
		ctxp = init_context(modelp);
		if(!ctxp)
			return DISP_STATE_ERROR;
		wp->data = ctxp;
	}
	ch = wp->key;

	threadp = modelp->selected_threadp;

	if(ctxp->max_cur_res < 0 || ctxp->max_cur_offset < 0){
		wlines = wp->lines;
		int cur_res = ctxp->res_num - 1;
		/* get the bottom scroll position*/
		clistp = threadp->reslistp->prev;
		while(clistp != threadp->reslistp){
			resp = (nt_res_tp)clistp->data;
			if(!resp->msg_line_linkp){
				parse_res_msg(resp, wp->cols-5);
			}

			if(resp->msg_header_line_num <= 0){
				if(-1 == swprintf(buf, sizeof(buf)-1, 
						L"%5d. %ls %ls %ls", 
						resp->seq_no, resp->name,
						resp->mail, resp->misc)){
					resp->msg_header_line_num = 1;
				}else{
					len = wcslen(buf);
					cptr = buf;
					while(len > 0){
						num = nt_get_wc_count_within_colmns(
									cptr, wp->cols);
						if(num <= 0)
							break;
						resp->msg_header_line_num++;
						len -= num;
						cptr += num;
					}
				}
			}
			wlines--;
			if(wlines == 0){
				ctxp->max_cur_offset = resp->msg_header_line_num;
				ctxp->max_cur_offset += resp->msg_line_num;
				ctxp->max_cur_res = cur_res;
				break;
			}
			if(wlines <= resp->msg_line_num){
				ctxp->max_cur_offset = resp->msg_header_line_num;
				ctxp->max_cur_offset += resp->msg_line_num - wlines;
				ctxp->max_cur_res = cur_res;
				break;
			}
			wlines -= resp->msg_line_num;
			if(wlines <= resp->msg_header_line_num){
				ctxp->max_cur_offset = 
						resp->msg_header_line_num - wlines;
				ctxp->max_cur_res = cur_res;
				break;
			}
			wlines -= resp->msg_header_line_num;
			cur_res--;
			if(cur_res < 0){
				ctxp->max_cur_offset = 0;
				ctxp->max_cur_res = 0;
				break;
			}
			clistp = clistp->prev;
		}
	}

	switch(ch){
	case NT_KEY_REFRESH:
		return DISP_STATE_REFRESH; 
	case NT_KEY_CLOSE:
		return DISP_STATE_THREADTITLE; 
	case NT_KEY_BOTTOM:
		if(ctxp->cur_res == ctxp->res_num - 1)
			break;
		if(!threadp->reslistp)
			break;
		clistp = threadp->reslistp->prev;
		ctxp->cur_res = ctxp->max_cur_res;
		ctxp->cur_res_offset = ctxp->max_cur_offset;
		break;
	case NT_KEY_LEFT:
		if(!ctxp->selected_num_stackp)
			break;
		nptr = malloc(sizeof(int));
		*nptr = ctxp->cur_res;
		ptr = nt_stack_add_last(ctxp->selected_num_stackp, nptr);
		if(!ptr){
			free(nptr);
		}
		nptr = nt_stack_pop(ctxp->selected_num_stackp);
		if(!nptr)
			break;
		num = *nptr;
		if(ctxp->cur_res == num)
			break;
		if(num >= ctxp->res_num)
			break;
		ctxp->cur_res = num;
		ctxp->cur_res_offset = 0;
		if(!threadp->reslistp)
			break;
		clistp = threadp->reslistp;
		for(i = 0; i < num; i++)
			clistp = clistp->next;
		break;
	case NT_KEY_RIGHT:
		if(!ctxp->selected_num_stackp)
			break;
		nptr = nt_stack_cursor_next(ctxp->selected_num_stackp);
		if(!nptr)
			break;
		num = *nptr;
		if(ctxp->cur_res == num)
			break;
		if(num >= ctxp->res_num)
			break;
		ctxp->cur_res = num;
		ctxp->cur_res_offset = 0;
		if(!threadp->reslistp)
			break;
		clistp = threadp->reslistp;
		for(i = 0; i < num; i++)
			clistp = clistp->next;
		break;
	case NT_KEY_COMMAND2:
	case NT_KEY_COMMAND3:
		search_asc = (ch == NT_KEY_COMMAND2);
		if(wp->cmd_param && wp->cmd_param[0] != '\0'){
			if(0 != regcomp(&(ctxp->regex), 
					wp->cmd_param, REG_EXTENDED)){
				if(ctxp->regex_init){
					regfree(&(ctxp->regex));
					ctxp->regex_init = FALSE;
					break;
				}
			}
			if(!ctxp->regex_init)
				ctxp->regex_init = TRUE;
		}
		if(!ctxp->regex_init)
			break;
		adjust = FALSE;
		if(search_asc){
			if(search_line_asc(&(ctxp->regex),threadp->reslistp,
					&ctxp->sel_res_no, &ctxp->sel_res_line, 
					wp->cols - 5)){
				adjust = TRUE;
			}
		}else{
			if(search_line_desc(&(ctxp->regex),ctxp,
					threadp->reslistp,
					&ctxp->sel_res_no, &ctxp->sel_res_line, 
					wp->cols - 5)){
				adjust = TRUE;
			}
		}
		if(adjust){
			set_value = FALSE;
			rows = ctxp->res_num - 1;
			wlines = wp->lines / 2;
			wlines -= ctxp->sel_res_line;
			clistp = threadp->reslistp->prev;
			do{
				if(rows <= ctxp->sel_res_no){
					resp = (nt_res_tp)clistp->data;
					if(!resp->msg_line_linkp){
						parse_res_msg(resp, wp->cols-5);
					}
					if(resp->msg_header_line_num <= 0){
						if(-1 == swprintf(buf, sizeof(buf)-1, 
								L"%5d. %ls %ls %ls", 
								resp->seq_no, resp->name,
								resp->mail, resp->misc)){
							resp->msg_header_line_num = 1;
						}else{
							len = wcslen(buf);
							cptr = buf;
							while(len > 0){
								num = nt_get_wc_count_within_colmns(
											cptr, wp->cols);
								if(num <= 0)
									break;
								resp->msg_header_line_num++;
								len -= num;
								cptr += num;
							}
						}
					}
					if(rows == ctxp->sel_res_no){
						if(wlines <= ctxp->sel_res_line){
							ctxp->cur_res = rows;
							ctxp->cur_res_offset = 
									resp->msg_header_line_num + 
									(ctxp->sel_res_line - wlines);
							set_value = TRUE;
							break;
						}
						wlines -= ctxp->sel_res_line;
					}else if(wlines <= (resp->msg_line_num+1)){
						ctxp->cur_res = rows;
						ctxp->cur_res_offset = 
								resp->msg_header_line_num + wlines;
						set_value = TRUE;
						break;
					}else{
						wlines -= resp->msg_line_num + 1;
					}
					if(wlines <= resp->msg_header_line_num){
						ctxp->cur_res = rows;
						ctxp->cur_res_offset = 
								resp->msg_header_line_num - wlines;
						set_value = TRUE;
						break;
					}
					wlines -= resp->msg_header_line_num;
				}
				rows--;
				clistp = clistp->prev;
			}while(clistp != threadp->reslistp->prev);
			if(!set_value){
				ctxp->cur_res = 0;
				ctxp->cur_res_offset = 0;
			}
		}
		break;
	case NT_KEY_COMMAND1:
		assert(wp->cmd_param);
		if(parse_cmd1(wp->cmd_param, &state)){
			return state;
		}
		num = atoi(wp->cmd_param);
		if(0 == num)
			break;
		num--;
		if(ctxp->cur_res == num)
			break;
		if(num >= ctxp->res_num)
			break;
		nptr = malloc(sizeof(int));
		*nptr = ctxp->cur_res;
		ctxp->cur_res = num;
		ctxp->cur_res_offset = 0;
		if(!threadp->reslistp){
			free(nptr);
			break;
		}
		clistp = threadp->reslistp;
		for(i = 0; i < num; i++)
			clistp = clistp->next;
		nt_stack_push(ctxp->selected_num_stackp, nptr);
		break;
	case NT_KEY_UP:
		ctxp->cur_res_offset--;
		if(0 <= ctxp->cur_res_offset){
			break;
		}
		if(0 >= ctxp->cur_res){
			ctxp->cur_res_offset = 0;
			ctxp->cur_res = 0;
			break;
		}
		ctxp->cur_res--;
		clistp = threadp->reslistp;
		for(i = 0; i < ctxp->res_num; i++){
			if(i == ctxp->cur_res)
				break;
			clistp = clistp->next;
		}
		if(i == ctxp->res_num)
			break;
		resp = (nt_res_tp)clistp->data;
		if(!resp->msg_line_linkp){
			parse_res_msg(resp, wp->cols-5);
		}
		if(resp->msg_header_line_num <= 0){
			if(-1 == swprintf(buf, sizeof(buf)-1, 
					L"%5d. %ls %ls %ls", 
					resp->seq_no, resp->name,
					resp->mail, resp->misc)){
				resp->msg_header_line_num = 1;
			}else{
				len = wcslen(buf);
				cptr = buf;
				while(len > 0){
					num = nt_get_wc_count_within_colmns(
								cptr, wp->cols);
					if(num <= 0)
						break;
					resp->msg_header_line_num++;
					len -= num;
					cptr += num;
				}
			}
		}
		num = resp->msg_header_line_num;
		num += resp->msg_line_num;
		ctxp->cur_res_offset = num;
		break;
	case NT_KEY_DOWN:
		ctxp->cur_res_offset++;
		clistp = threadp->reslistp;
		for(i = 0; i < ctxp->res_num; i++){
			if(i == ctxp->cur_res)
				break;
			clistp = clistp->next;
		}
		if(i == ctxp->res_num)
			break;
		resp = (nt_res_tp)clistp->data;
		if(!resp->msg_line_linkp){
			parse_res_msg(resp, wp->cols-5);
		}
		if(resp->msg_header_line_num <= 0){
			if(-1 == swprintf(buf, sizeof(buf)-1, 
					L"%5d. %ls %ls %ls", 
					resp->seq_no, resp->name,
					resp->mail, resp->misc)){
				resp->msg_header_line_num = 1;
			}else{
				len = wcslen(buf);
				cptr = buf;
				while(len > 0){
					num = nt_get_wc_count_within_colmns(
								cptr, wp->cols);
					if(num <= 0)
						break;
					resp->msg_header_line_num++;
					len -= num;
					cptr += num;
				}
			}
		}
		num = resp->msg_header_line_num;
		num += resp->msg_line_num + 1;
		if(ctxp->cur_res_offset >= num){
			ctxp->cur_res++;
			ctxp->cur_res_offset = 0;
		}
		break;
	case NT_KEY_PAGEUP:
		ctxp->cur_res_offset -= wp->lines;
		if(ctxp->cur_res_offset >= 0){
			break;
		}
		ctxp->cur_res--;
		clistp = threadp->reslistp;
		for(i = 0; i < ctxp->res_num; i++){
			if(i == ctxp->cur_res)
				break;
			clistp = clistp->next;
		}
		if(i == ctxp->res_num){
			ctxp->cur_res_offset = 0;
			break;
		}
		for( ; i > 0; i--){
			resp = (nt_res_tp)clistp->data;
			if(!resp->msg_line_linkp){
				parse_res_msg(resp, wp->cols-5);
			}
			if(resp->msg_header_line_num <= 0){
				if(-1 == swprintf(buf, sizeof(buf)-1, 
						L"%5d. %ls %ls %ls", 
						resp->seq_no, resp->name,
						resp->mail, resp->misc)){
					resp->msg_header_line_num = 1;
				}else{
					len = wcslen(buf);
					cptr = buf;
					while(len > 0){
						num = nt_get_wc_count_within_colmns(
									cptr, wp->cols);
						if(num <= 0)
							break;
						resp->msg_header_line_num++;
						len -= num;
						cptr += num;
					}
				}
			}
			num = resp->msg_header_line_num;
			num += resp->msg_line_num;
			if(ctxp->cur_res_offset + num < 0){
				ctxp->cur_res_offset += num;
				ctxp->cur_res--;
				clistp = clistp->prev;
				continue;
			}
			ctxp->cur_res_offset += num;
			break;
		}
		if(i == 0){
			ctxp->cur_res = 0;
			ctxp->cur_res_offset = 0;
		}
		break;
	case NT_KEY_PAGEDOWN:
		clistp = threadp->reslistp;
		if(0 > ctxp->cur_res)
			ctxp->cur_res = 0;
		for(i = 0; i < ctxp->res_num; i++){
			if(i == ctxp->cur_res)
				break;
			clistp = clistp->next;
		}
		if(i == ctxp->res_num)
			break;
				
		ctxp->cur_res_offset += wp->lines;
		for( ; i < ctxp->res_num; i++){
			resp = (nt_res_tp)clistp->data;
			if(!resp->msg_line_linkp){
				parse_res_msg(resp, wp->cols-5);
			}
			if(resp->msg_header_line_num <= 0){
				if(-1 == swprintf(buf, sizeof(buf)-1, 
						L"%5d. %ls %ls %ls", 
						resp->seq_no, resp->name,
						resp->mail, resp->misc)){
					resp->msg_header_line_num = 1;
				}else{
					len = wcslen(buf);
					cptr = buf;
					while(len > 0){
						num = nt_get_wc_count_within_colmns(
									cptr, wp->cols);
						if(num <= 0)
							break;
						resp->msg_header_line_num++;
						len -= num;
						cptr += num;
					}
				}
			}
			num = resp->msg_header_line_num;
			num += resp->msg_line_num + 1;
			if(num > ctxp->cur_res_offset){
				break;
			}
			ctxp->cur_res++;
			ctxp->cur_res_offset -= num;

			clistp = clistp->next;
		}
		break;
	}/* end switch */

	if(ctxp->cur_res > ctxp->max_cur_res ||
		(ctxp->cur_res == ctxp->max_cur_res && 
		ctxp->cur_res_offset > ctxp->max_cur_offset)){
		ctxp->cur_res = ctxp->max_cur_res;
		ctxp->cur_res_offset = ctxp->max_cur_offset;
	}

	clistp = threadp->reslistp;
	res_offset = 0;
	rows = 0;
	for(i = 0; i < ctxp->res_num; i++){
		if(i < ctxp->cur_res){
			clistp = clistp->next;
			continue;
		}

		if(rows == wp->lines)
			break;

		resp = (nt_res_tp)clistp->data;
		
		if(-1 == swprintf(buf, sizeof(buf)-1, 
				L"%5d. %ls %ls %ls", 
				resp->seq_no, resp->name,
				resp->mail, resp->misc)){
			continue;
		}
		len = wcslen(buf);
		num = nt_get_wc_count_within_colmns(buf, wp->cols);

		if(num < len){
			if(!nt_w_str_move(buf, sizeof(buf), num, 1))
				break;
			if(res_offset >= ctxp->cur_res_offset){
				wmove(wp->wp, rows, 0);
				nt_add_wstr(wp->wp, buf, 0);
				rows++;
			}else{
				res_offset++;
			}
			if(rows == wp->lines)
				break;
			if(res_offset >= ctxp->cur_res_offset){
				wmove(wp->wp, rows, 0);
				nt_add_wnch(wp->wp, L' ', WA_UNDERLINE, 5);
				nt_add_wnstr(wp->wp, buf + num + 1, WA_UNDERLINE,
				wp->cols - 5);
				rows++;
			}else{
				res_offset++;
			}
		}else{
			if(res_offset >= ctxp->cur_res_offset){
				wmove(wp->wp, rows, 0);
				nt_add_wstr(wp->wp, buf, WA_UNDERLINE);
				rows++;
			}else{
				res_offset++;
			}
		}
		if(rows == wp->lines)
			break;
		if(!resp->msg_line_linkp){
			parse_res_msg(resp, wp->cols-5);
		}
		if(0 == resp->msg_line_num)
			continue;

		link_curp = resp->msg_line_linkp;
		line_num = 0;
		do{
			cptr = (wchar_t*)link_curp->data;
			if(res_offset >= ctxp->cur_res_offset){
				wmove(wp->wp, rows, 5);
				if(i == ctxp->sel_res_no &&
					line_num == ctxp->sel_res_line){
					/*fprintf(stderr, "hilighted no: %d, line: %d\n",
						i, line_num);*/
					nt_add_wstr(wp->wp, cptr, WA_REVERSE);
				}else{
					nt_add_wstr(wp->wp, cptr, 0);
				}
				rows++;
				if(rows == wp->lines)
					goto END_FOR;
			}else{
				res_offset++;
			}
			line_num++;
			link_curp = link_curp->next;
		}while(resp->msg_line_linkp != link_curp);

		if(rows == wp->lines)
			goto END_FOR;
		if(res_offset >= ctxp->cur_res_offset){
			wmove(wp->wp, rows, 0);
			nt_add_wnch(wp->wp, L' ', 0, wp->cols);
			rows++;
		}else{
			res_offset++;
		}
		clistp = clistp->next;
	}/* end for */
END_FOR:
	
	return DISP_STATE_RESLIST; 
}

static BOOL parse_cmd1(const char *param, int *statep)
{
	assert(param);

	if(0 == strcmp(NT_COMMAND1_WRITE_MSG_1, param) ||
		0 == strcmp(NT_COMMAND1_WRITE_MSG_2, param)){
		*statep = DISP_STATE_EDITOR;
		return TRUE;

	}
	return FALSE;
}



static ctx_reslist_tp init_context(nt_2ch_model_tp modelp)
{
	ctx_reslist_tp ctxp;
	nt_thread_tp threadp;
	ctxp = (ctx_reslist_tp)calloc(1,sizeof(ctx_reslist_t));

	if(!ctxp)
		return NULL;

	threadp = modelp->selected_threadp;
	if(threadp->reslistp)
		ctxp->res_num = nt_link_num(threadp->reslistp);
	ctxp->cur_res = 0;
	ctxp->cur_res_offset = 0;
	ctxp->max_cur_res = -1;
	ctxp->max_cur_offset = -1;
	ctxp->selected_num_stackp = nt_stack_alloc();
	ctxp->regex_init = FALSE;
	ctxp->sel_res_no = -1;
	ctxp->sel_res_line = -1;

	return ctxp;
}

void free_reslist_ctx(void *ptr)
{
	ctx_reslist_tp ctxp;
	if(!ptr)
		return;
	 ctxp = (ctx_reslist_tp)ptr;
	 nt_stack_free(ctxp->selected_num_stackp, &int_ptr_free);
	 if(ctxp->regex_init)
	 	regfree(&(ctxp->regex));
	 free(ptr);
}

static void int_ptr_free(void *ptr)
{
	free(ptr);
}


static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp, 
			int *sel_res_no, int *sel_res_line, int column)
{
	nt_link_tp clistp, listp;
	nt_res_tp resp;
	int cur, line, res_no, res_line;
	wchar_t *cptr;
	char buf[256];
	size_t nmatch = 5;
	regmatch_t pmatch[5];

	if(!reslistp)
		return FALSE;
	
	if(*sel_res_no < 0)
		res_no = 0;
	else
		res_no = *sel_res_no;
	if(*sel_res_line < 0)
		res_line = 0;
	else
		res_line = *sel_res_line + 1;
		
	cur = 0;
	clistp = reslistp;
	do{
		if(cur >= res_no){
			resp = (nt_res_tp)clistp->data;
			if(!resp->msg_line_linkp)
				parse_res_msg(resp, column);
			listp = resp->msg_line_linkp;
			line = 0;
			do{
				if(line >= res_line){
					cptr = (wchar_t*)listp->data;
					if(0 < wcstombs(buf, cptr, sizeof(buf))){
						if(0 == regexec(regexp, buf, 
								nmatch, pmatch, 0)){
							*sel_res_line = line;
							*sel_res_no = cur;
							return TRUE;
						}
					}
				}
				line++;
				listp = listp->next;
			}while(listp != resp->msg_line_linkp);
			res_line = 0;
		}
		cur++;
		clistp = clistp->next;
	}while(clistp != reslistp);

	cur = 0;
	clistp = reslistp;
	do{
		if(cur >= res_no)
			break;

		resp = (nt_res_tp)clistp->data;
		if(!resp->msg_line_linkp)
			parse_res_msg(resp, column);
		listp = resp->msg_line_linkp;
		line = 0;
		do{
			if(line >= res_line){
				cptr = (wchar_t*)listp->data;
				if(0 < wcstombs(buf, cptr, sizeof(buf))){
					if(0 == regexec(regexp, buf, 
							nmatch, pmatch, 0)){
						*sel_res_line = line;
						*sel_res_no = cur;
						return TRUE;
					}
				}
			}
			line++;
			listp = listp->next;
		}while(listp != resp->msg_line_linkp);
		res_line = 0;
		cur++;
		clistp = clistp->next;
	}while(clistp != reslistp);
	return FALSE;
}

static BOOL search_line_desc(regex_t *regexp, ctx_reslist_tp ctxp,
			nt_link_tp reslistp, 
			int *sel_res_no, int *sel_res_line, int column)
{
	nt_link_tp clistp, listp;
	nt_res_tp resp;
	int cur, line, res_no, res_line;
	wchar_t *cptr;
	char buf[256];
	size_t nmatch = 5;
	regmatch_t pmatch[5];

	if(!reslistp)
		return FALSE;
	
	if(*sel_res_no < 0){
		res_no = ctxp->res_num - 1;
	}else{
		res_no = *sel_res_no;
	}
	if(*sel_res_line < 0){
		res_line = INT_MAX;
	}else{
		res_line = *sel_res_line - 1;
	}
		
	cur = ctxp->res_num - 1;
	clistp = reslistp->prev;
	do{
		if(cur <= res_no){
			resp = (nt_res_tp)clistp->data;
			if(!resp->msg_line_linkp)
				parse_res_msg(resp, column);
			listp = resp->msg_line_linkp->prev;
			line = resp->msg_line_num - 1;
			do{
				if(line <= res_line){
					cptr = (wchar_t*)listp->data;
					if(0 < wcstombs(buf, cptr, sizeof(buf))){
						if(0 == regexec(regexp, buf, 
								nmatch, pmatch, 0)){
							*sel_res_line = line;
							*sel_res_no = cur;
							return TRUE;
						}
					}
				}
				line--;
				listp = listp->prev;
			}while(listp != resp->msg_line_linkp->prev);
			res_line = resp->msg_line_num - 1;
		}
		cur--;
		clistp = clistp->prev;
	}while(clistp != reslistp->prev);

	cur = ctxp->res_num - 1;
	clistp = reslistp->prev;
	do{
		if(cur <= res_no)
			break;

		resp = (nt_res_tp)clistp->data;
		if(!resp->msg_line_linkp)
			parse_res_msg(resp, column);
		listp = resp->msg_line_linkp->prev;
		line = resp->msg_line_num - 1;
		do{
			if(line >= res_line){
				cptr = (wchar_t*)listp->data;
				if(0 < wcstombs(buf, cptr, sizeof(buf))){
					if(0 == regexec(regexp, buf, 
							nmatch, pmatch, 0)){
						*sel_res_line = line;
						*sel_res_no = cur;
						return TRUE;
					}
				}
			}
			line--;
			listp = listp->prev;
		}while(listp != resp->msg_line_linkp->prev);
		res_line = resp->msg_line_num - 1;
		cur--;
		clistp = clistp->prev;
	}while(clistp != reslistp->prev);
	return FALSE;
}
