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

/******************************************************************************
 *  The Elm (ME+) Mail System  -  $Revision: 1.6 $   $State: Exp $
 *
 *  Author: Kari Hurtta <elm@elmme-mailer.org>
 *****************************************************************************/

#include "def_screen.h"
#include "def_scommon.h"

DEBUG_VAR(Debug,__FILE__,"screen");

#define MENU_HEADER_magic       0xF804
struct menu_header {
    struct subpage_common  c;
    unsigned short         magic;      /* MENU_HEADER_magic */

    int       params[HEADER_PARAMS_COUNT];     
    header_line_redraw     * line_redraw;
    header_line_redraw     * current_redraw;
    header_param_changed   * param_change;
    header_line_redraw     * status_redraw;
};


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

S_(w_menu_init mheader_init)
static void mheader_init P_((struct menu_context *ctx));
static void mheader_init(ctx)
     struct menu_context *ctx;
{
    int i;

    DPRINT(Debug,10, (&Debug, "mheader_init: %p\n",
		      ctx));

    ctx->u.header = safe_malloc (sizeof (* ctx->u.header));

    /* bzero is defined hdrs/defs.h */
    bzero((void *)ctx->u.header,sizeof (* ctx->u.header));

    scommon_zero(&(ctx->u.header->c)); 
    ctx->u.header->magic          = MENU_HEADER_magic;

    for (i = 0; i < HEADER_PARAMS_COUNT; i++)
	ctx->u.header->params[i] = 0;

    ctx->u.header->line_redraw     = header_line_noredraw;
    ctx->u.header->current_redraw  = header_line_noredraw;
    ctx->u.header->param_change    = null_header_param_changed;
    ctx->u.header->status_redraw     = header_line_noredraw;
}

S_(w_menu_free mheader_free)
static void mheader_free P_((struct menu_context *ctx));
static void mheader_free(ctx)
     struct menu_context *ctx;
{

    DPRINT(Debug,10, (&Debug, "mheader_free: %p\n",
		      ctx));

    if (MENU_HEADER_magic != ctx->u.header->magic)
	panic("SCREEN PANIC",__FILE__,__LINE__,"subpage_free",
	      "Bad magic number",0);

    scommon_clear( & (ctx->u.header->c) );

    ctx->u.header->magic = 0;    /* Invalidate */
    free(ctx->u.header);
    ctx->u.header = NULL;
}


static void header_change_current P_((struct menu_context *ctx,
				      int old_value));
static void header_change_current(ctx,old_value)
     struct menu_context *ctx;
     int old_value;
{
    int current = ctx->u.header->params[header_current];
    int top     = ctx->u.header->params[header_top_line];

    int i;

    i = old_value - top;
    if (i >= 0 && i < ctx->lines)
	ctx->u.header->current_redraw(ctx, 
				   ctx->u.header->c.param_ptr,
				   i,
				   old_value,
				   0);
	
    i = current - top;
    if (i >= 0 && i < ctx->lines)
	ctx->u.header->current_redraw(ctx, 
				   ctx->u.header->c.param_ptr,
				   i,
				   current,
				   1);
}

S_(w_menu_do_redraw mheader_do_redraw)
static int mheader_do_redraw P_((struct menu_context *ctx));
static int mheader_do_redraw(ctx)
     struct menu_context *ctx;
{
    int current, line,i;

    if (MENU_HEADER_magic != ctx->u.header->magic) 
	panic("SCREEN PANIC",__FILE__,__LINE__,"header_do_redraw",
	      "Bad magic number",0);

    current = ctx->u.header->params[header_current];
    line     = ctx->u.header->params[header_top_line];

    for (i = 0; i < ctx->lines; i++) {
	ctx->u.header->line_redraw(ctx, 
				   ctx->u.header->c.param_ptr,
				   i,
				   line,
				   line == current);
	line++;
    }

    return 1;
}

static struct  menu_draw_routine HEADER_ROUTINES = {
    MENU_DRAW_magic,

    mheader_init,
    mheader_free,
	
    scommon_Writechar,
    scommon_PutLineS,
    scommon_PutLine0,
    scommon_CleartoEOLN,
    scommon_CleartoEOS,
    scommon_ReadCh2,
    scommon_ScreenSize,
    scommon_GetXYLocation,
    scommon_ClearScreen,
    scommon_MoveCursor,
    scommon_changemode,
    scommon_SyncEnter,
    scommon_SyncLeave,
    scommon_resized,
    scommon_calculate_line,
    scommon_get_linelimit,
    scommon_reset_redraw,
    mheader_do_redraw,
};


void header_line_noredraw(ptr,list,line_number,index,is_current)
     struct menu_context  *ptr;
     struct menu_param *list;
     int line_number;
     int index;
     int is_current;
{
    return;
}

void null_header_param_changed(ptr,list,param_index)
     struct menu_context  *ptr;
     struct menu_param *list;	       
     int param_index;
{
    return;
}

struct menu_context * new_menu_header(parent,rel_start_line,lines,
				      line_redraw,current_redraw,
				      param_change,status_redraw,list)
     struct menu_context  *parent;
     int rel_start_line;
     int lines;
     header_line_redraw line_redraw;
     header_line_redraw current_redraw;
     header_param_changed param_change;
     header_line_redraw status_redraw;
     /* only rereference is saved */
     struct menu_param *list;
{
    int rline = 0;
    int lline = 0;

    struct menu_context  *ret =  new_menu_type(&HEADER_ROUTINES);

    if (MENU_CONTEXT_magic != parent->magic)
	panic("SCREEN PANIC",__FILE__,__LINE__,"new_menu_header",
	      "Bad parent magic number",0);

    ret->lines                = lines;
    ret->columns              = parent->columns;
    ret->u.header->c.rel_start_line = rel_start_line;
    ret->u.header->c.param_ptr     = list;

    ret->u.header->line_redraw     = line_redraw; 
    ret->u.header->current_redraw  = current_redraw; 
    ret->u.header->param_change    = param_change;
    ret->u.header->status_redraw   = status_redraw;

    if (MENU_DRAW_magic  != parent->routine->magic)
	panic("SCREEN PANIC",__FILE__,__LINE__,"new_menu_header",
	      "Bad parent draw magic number",0);

    parent->routine->wra_calculate_line(parent,rel_start_line,&rline);

    lline = rline + lines -1;    /* calculate_printing_area() fixes */

    attach_subpage(parent,ret,rline,lline);

    calculate_printing_area(ret);

    return ret;
}


void menu_header_change(subpage,param,value)
     struct menu_context  *subpage;
     enum header_params  param;
     int value;
{
    int old_value;

    if (&HEADER_ROUTINES != subpage->routine)
	panic("SCREEN PANIC",__FILE__,__LINE__,"menu_header_change",
	      "Not a header subpage",0);

    if (MENU_HEADER_magic != subpage->u.header->magic)
	panic("SCREEN PANIC",__FILE__,__LINE__,"menu_header_change",
	      "Bad magic number",0);

    if (param < 0 || param >= HEADER_PARAMS_COUNT)
	panic("SCREEN PANIC",__FILE__,__LINE__,"menu_header_change",
	      "Bad param number",0);
	
    old_value = subpage->u.header->params[param];

    subpage->u.header->params[param] = value;


    switch (param) {
    case header_top_line:
	if (value != old_value)
	    menu_trigger_redraw(subpage);
	break;
    case header_current:
	if (value != old_value)
	    header_change_current(subpage,old_value);
	break;
    }

}

int menu_header_get(subpage,param)
     struct menu_context  *subpage;
     enum header_params  param;
{
    if (&HEADER_ROUTINES != subpage->routine)
	panic("SCREEN PANIC",__FILE__,__LINE__,"menu_header_get",
	      "Not a header subpage",0);

    if (MENU_HEADER_magic != subpage->u.header->magic)
	panic("SCREEN PANIC",__FILE__,__LINE__,"menu_header_get",
	      "Bad magic number",0);

    if (param < 0 || param >= HEADER_PARAMS_COUNT)
	panic("SCREEN PANIC",__FILE__,__LINE__,"menu_header_get",
	      "Bad param number",0);
	
    return subpage->u.header->params[param];
}

void menu_header_relocate(subpage,parent,rel_start_line,lines)
     struct menu_context  *subpage;
     struct menu_context  *parent;
     int rel_start_line;
     int lines;
{
    if (&HEADER_ROUTINES != subpage->routine)
	panic("SCREEN PANIC",__FILE__,__LINE__,"menu_header_relocate",
	      "Not a header subpage",0);

    scommon_relocate(subpage,parent,rel_start_line,lines);
}

void menu_header_status_update(subpage,item)
     struct menu_context  *subpage;
     int item;
{
    int i, current, top;

    if (&HEADER_ROUTINES != subpage->routine)
	panic("SCREEN PANIC",__FILE__,__LINE__,"menu_header_status_update",
	      "Not a header subpage",0);

    if (MENU_HEADER_magic != subpage->u.header->magic)
	panic("SCREEN PANIC",__FILE__,__LINE__,"menu_header_status_update",
	      "Bad magic number",0);

    current = subpage->u.header->params[header_current];
    top     = subpage->u.header->params[header_top_line];

    i = item - top;
    if (i >= 0 && i < subpage->lines) {
	DPRINT(Debug,11, (&Debug, 
			  "menu_header_status_update(%p,%d): current=%d, top=%d => i=%d\n",
			  subpage,item,current,top,i));

	subpage->u.header->status_redraw(subpage, 
					 subpage->u.header->c.param_ptr,
					 i,
					 item,
					 current == item);
    } else {
	DPRINT(Debug,11, (&Debug, 
			  "menu_header_status_update(%p,%d): current=%d, top=%d => i=%d (OUT OF RANGE), lines=%d\n",
			  subpage,item,current,top,i,subpage->lines));	
    }

}

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


syntax highlighted by Code2HTML, v. 0.9.1