static char rcsid[] = "@(#)$Id: select.c,v 1.9 2006/04/09 07:37:42 hurtta Exp $";

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.9 $   $State: Exp $
 *
 *  Author: Kari Hurtta <hurtta+elm@posti.FMI.FI>
 *      or  Kari Hurtta <elm@elmme-mailer.org>
 *****************************************************************************/

#include "def_list.h"
#include "s_me.h"

DEBUG_VAR(Debug,__FILE__,"url");

struct menu_anon_param {
     struct list_elem *list;
     int               list_len;
};


enum { selection_mp_list,
       selection_mp_COUNT };


static void first_item P_((void));
static void first_item()
{
    lib_error(CATGETS(elm_msg_cat, MeSet, 
		      MeNoMoreItemsAbove,
		      "No more items above."));    
}

static void last_item P_((void));
static void last_item()
{
    lib_error(CATGETS(elm_msg_cat, MeSet, 
		      MeNoMoreItemsBelow,
		      "No more items below.")); 
}

static struct move_messages M = {
    first_item,
    last_item
};

#if ANSI_C
#define S_(x) static x;
#else
#define S_(x)
#endif

S_(header_line_redraw select_show_header)
static void select_show_header P_((struct menu_context  *ptr,
				   struct menu_param *list,
				   int line_number,
				   int index,
				   int is_current));
static void select_show_header(ptr,list,line_number,index,is_current)
     struct menu_context  *ptr;
     struct menu_param *list;	   
     int line_number;
     int index;
     int is_current;
{
    struct menu_anon_param *A = mp_lookup_anon(list,selection_mp_list);
    int LINES, COLUMNS;

    menu_get_sizes(ptr, &LINES, &COLUMNS);

    menu_ClearLine(ptr,line_number);	    
    menu_MoveCursor(ptr,line_number,0);

    if (is_current) {

	if (has_highlighting && ! arrow_cursor) {

	    menu_StartXX(ptr,pg_INVERSE);

	    menu_PutLine0(ptr,line_number,0,"   ");

	} else {
	    menu_PutLine0(ptr,line_number,0,"-> ");

	}

    } else 
	menu_PutLine0(ptr,line_number,0,"   ");

    if (index >= 0 && index < A->list_len) {
	struct string *url_text = raw_from_url(A->list[index].url);

	if (url_text) {

	    if (COLUMNS > 3)
		menu_PutLineX(ptr,line_number,3,FRM("%-*.*S"),
			      COLUMNS-3,COLUMNS-3,url_text);

	    free_string(&url_text);
	}
    }

    if (is_current) {
	if (has_highlighting && ! arrow_cursor) {
	    menu_EndXX(ptr,pg_INVERSE);
	}
    }
    menu_Writechar(ptr,'\r');
    menu_Writechar(ptr,'\n');
}

S_(header_line_redraw select_show_current)
static void select_show_current P_((struct menu_context  *ptr,
				    struct menu_param *list,
				    int line_number,
				    int index,
				    int is_current));
static void select_show_current(ptr,list,line_number,index,is_current)
     struct menu_context  *ptr;
     struct menu_param *list;	   
     int line_number;
     int index;
     int is_current;
{

    if (has_highlighting && ! arrow_cursor) {
	select_show_header(ptr,list,line_number,index,is_current);
    } else {
	if (!is_current)
	    menu_PutLine0(ptr,line_number,0,"  ");  /* remove old pointer... */
	else
	    menu_PutLine0(ptr,line_number,0,"->");
    }
}

S_(subpage_simple_redraw sb_update_select_menu)
static int sb_update_select_menu P_((struct menu_context  *ptr,
				     struct menu_param *list));
static int sb_update_select_menu(ptr,list)
     struct menu_context  *ptr;
     struct menu_param *list;
{

    menu_ClearScreen(ptr);

    menu_print_format_center(ptr,0,
			     CATGETS(elm_msg_cat, MeSet, MeSelectMenuLine1,
				     "To select URL, press <return>.  j = move down, k = move up, q = quit menu"));

    return 1;
}

S_(subpage_simple_redraw sb_update_select_prompt)
static int sb_update_select_prompt P_((struct menu_context  *ptr,
				       struct menu_param *list));
static int sb_update_select_prompt(ptr,list)
     struct menu_context  *ptr;
     struct menu_param *list;
{

    menu_ClearScreen(ptr);

    show_last_error();

    menu_PutLineX (ptr,0, 0, 
		   CATGETS(elm_msg_cat, MeSet, MeSelectMenuPrompt,
			   "Select URL: "));

    return 1;
}


static void set_select_screen P_((struct menu_context  *page, 
				 struct screen_parts *LOC,
				 struct menu_param  *LIST,
				 subpage_simple_redraw *title));
static void set_select_screen(page,LOC,LIST,title)
     struct menu_context  *page;
     struct screen_parts *LOC;
     struct menu_param  *LIST;
     subpage_simple_redraw *title;
{
    int   LINES, COLUMNS;	
    int  headers_per_page;

    menu_get_sizes(page,&LINES, &COLUMNS);

    /* 1)  Title part of screen */

    if (! LOC->title_page)
	LOC->title_page = new_menu_subpage(page,0,2,title,LIST);
    else
	menu_subpage_relocate(LOC->title_page,page,0,2);


    /* 2) selection part */
    headers_per_page = LINES-8;
    if (headers_per_page < 1) {
	headers_per_page = 1;
    }

    if (! LOC->header_page)
	LOC->header_page = new_menu_header(page,2,
					   headers_per_page,
					   select_show_header,
					   select_show_current,
					   null_header_param_changed,
					   select_show_current,
					   LIST);
    else 
	menu_header_relocate(LOC->header_page,page,
			     2,headers_per_page);


    /* 3) menu part */

    if (LOC->menu_page)
	menu_subpage_relocate(LOC->menu_page,page,LINES-6,2);
    else 
	LOC->menu_page = new_menu_subpage(page,LINES-6,2,
					  sb_update_select_menu,LIST);

    /* 4) prompt part  */

    if (LOC->prompt_page)
	menu_subpage_relocate(LOC->prompt_page,page,LINES-4,4);
    else 
	LOC->prompt_page = new_menu_subpage(page,LINES-4,4,
					    sb_update_select_prompt,LIST);




}

static void check_select_screen P_((struct screen_parts *LOC,
				    struct menu_param *list,
				    subpage_simple_redraw *title));
static void check_select_screen(LOC,list,title)
     struct screen_parts *LOC;
     struct menu_param *list;
     subpage_simple_redraw *title;
{
    /* 1) title page */
    if (menu_resized(LOC->title_page)) {
	DPRINT(Debug,1, (&Debug, "title page resized\n"));

    }
    if (menu_need_redraw(LOC->title_page)) {
	DPRINT(Debug,1, (&Debug, "title page redraw???\n"));
	title(LOC->title_page,list);
    }

    /* 2) headers part */
    if (menu_resized(LOC->header_page)) {
	DPRINT(Debug,1, (&Debug, "header page resized\n"));
    }
    if (menu_need_redraw(LOC->header_page)) {
	DPRINT(Debug,1, (&Debug, "header page redraw\n"));
	menu_ClearScreen(LOC->header_page);
    }


    if (LOC->menu_page) {
	/* 3) menu page */
	if (menu_resized(LOC->menu_page)) {
	    DPRINT(Debug,1, (&Debug, "menu page resized\n"));
	    
	}
	if (menu_need_redraw(LOC->menu_page)) {
	    DPRINT(Debug,1, (&Debug, "menu page redraw\n"));
	    sb_update_select_menu(LOC->menu_page,list);
	}
    }

    /* 4) prompt part */
    if (menu_resized(LOC->prompt_page)) {
	DPRINT(Debug,1, (&Debug, "prompt page resized\n"));
    }
    if (menu_need_redraw(LOC->prompt_page)) {
	DPRINT(Debug,1, (&Debug, "prompt page redraw\n"));

	sb_update_select_prompt(LOC->prompt_page,list);
    }

}


CONST struct url * select_post_url(list,list_len,parent_page,title)
     struct list_elem *list;
     int               list_len;
     struct menu_context  *parent_page;
     subpage_simple_redraw *title;
{
    struct url * ret = NULL;

    struct menu_anon_param A;
    struct menu_context  * page;
    struct screen_parts  LOC  = { NULL, NULL, NULL, NULL };
    struct menu_param  PARAM[selection_mp_COUNT+1] = { 
	{ mp_anon_param,0 },
	{ mp_END,0 }
    };
    int ch;
    int update = 1;
    int i;

    /* If there is one item and it is mailto url, return it */
    if (1 == list_len) {
	struct url * url   = list[0].url;

	if (url_mailing == get_url_type(url))
	    return url;
    }

    A.list      = list;
    A.list_len  = list_len;

    mp_list_set_anon(PARAM,selection_mp_list,&A);

    page = new_menu_context();
    set_select_screen(page,&LOC,PARAM,title);

    /* Select default position */
    for (i = 0; i < list_len; i++) {
	struct url * url   = list[i].url;

	if (url_mailing == get_url_type(url)) {
	    menu_header_change(LOC.header_page, header_current,i);
	    break;
	}
    }


    for (;;) {

	if (menu_resized(page)) {
	    set_select_screen(page,&LOC,PARAM,title);
	    
	    update = 1;
	} 
	
	if (update || menu_need_redraw(page)) {
	    menu_ClearScreen(page);
	    
	    /* Call refresh routines of children */
	    menu_redraw_children(page);
	    
	    update = 0;
	    show_last_error(); 
	} 


	check_select_screen(&LOC, PARAM, title);

	{
	    int lin,col;
	    
	    menu_ClearLine(LOC.prompt_page,0);

	    menu_PutLineX (LOC.prompt_page,0, 0, 
			   CATGETS(elm_msg_cat, MeSet, MeSelectMenuPrompt,
				   "Select URL: "));
	    menu_GetXYLocation(LOC.prompt_page,&lin,&col);
	    
	    menu_CleartoEOS(LOC.prompt_page);   
	    
	    show_last_error();
	    menu_MoveCursor(LOC.prompt_page,lin,col);
	    
	    ch = menu_ReadCh(LOC.prompt_page, 
			     REDRAW_MARK|READCH_CURSOR|READCH_resize|
			     READCH_sig_char);

	    menu_CleartoEOS(LOC.prompt_page);
	    set_error("");	/* clear error buffer */
	}

	ch = do_movement(LOC.header_page,ch,list_len,&M);

	switch (ch) {
	    int cur;
	case RESIZE_MARK:
	    DPRINT(Debug,4, (&Debug, " ... resizing\n"));
	    continue;

	case ctrl('L'):
	case REDRAW_MARK:
	    update = 1;
	    break;

	case '\n':
	    cur = menu_header_get(LOC.header_page,header_current);

	    if (cur >= 0 && cur < list_len) {
		ret = list[cur].url;
		goto OUT;
	    }

	    break;

	case 'i':
	case 'q':
	case 'x':
	case TERMCH_interrupt_char:
	case EOF:
	    goto OUT;

	case 0:
	    break;

	default:
	    lib_error(CATGETS(elm_msg_cat, MeSet,
			      MeSelectUnknownCommand,		       
			      "Unknown command: %c"), 
		      ch);
	}
    }


    OUT:
	free_mailbox_screen(&LOC);
    
    erase_menu_context(&page);
    
    menu_trigger_redraw(parent_page);

    /* Force default return to parent page ... */
    menu_set_default(parent_page); 

    return ret;
}


/*
 * Local Variables:
 *  mode:c
 *  c-basic-offset:4
 *  buffer-file-coding-system: iso-8859-1
 * End:
 */




syntax highlighted by Code2HTML, v. 0.9.1