/****************************************************************************/
/*	File : xbutton.c														*/
/*																			*/
/*																1993/10/12	*/
/****************************************************************************/
#include			<stdio.h>

#include			"xwins.h"
#include			"app_glob.c"

#define				WINDMASK		(ExposureMask | ButtonReleaseMask | ButtonPressMask)
#define				WINDMASK2		(WINDMASK | EnterWindowMask | LeaveWindowMask)


typedef struct{
	char			*label;
	int				(*action)(caddr_t);
	caddr_t			action_args;
}D_BUTTON;


static int	button_handler(XWIN *);
static int	button16_handler(XWIN *);
static int	label_handler(XWIN *);
static int	label16_handler(XWIN *);
static int	labelV16_handler(XWIN *);
static int	label216_handler(XWIN *);
static int	labelV16S_handler(XWIN *);

static int		(*handler[])() = {
					button_handler,
					button16_handler,
					label_handler,
					label16_handler,
					labelV16_handler,
					label216_handler,
					labelV16S_handler,
				};

static long		ev_mask[] = {
					WINDMASK2,
					WINDMASK2,
					WINDMASK,
					WINDMASK,
					WINDMASK,
					WINDMASK,
					WINDMASK,
				};

/****************************************************************************/
/*																			*/
/****************************************************************************/
XWIN *MakeXButton(int x, int y,
		unsigned width, unsigned height, unsigned bdwidth,
		unsigned long bdcolor, unsigned long bgcolor,
		Window parent, char *label, int (*button_action)(),
		caddr_t action_data, int mode)
{
	XWIN			*new_button;
	D_BUTTON		*p_data;


	if((p_data = (D_BUTTON *)calloc(1,sizeof(D_BUTTON))) == NULL){
		fprintf(stderr,"No memory for button's data");
		exit(1);
	}

	if((new_button = (XWIN *)calloc(1,sizeof(XWIN))) == NULL){
		fprintf(stderr,"No memory for button");
		exit(1);
	}

	p_data->action            = button_action;
	p_data->action_args       = action_data;
	p_data->label             = label;
	new_button->data          = p_data;
	new_button->event_handler = handler[mode];
	new_button->xid           = XCreateSimpleWindow(display,parent,x,y,width,height,bdwidth,
									bdcolor,bgcolor);

	if(XSaveContext(display,new_button->xid,xwin_context,(caddr_t)new_button) != 0){
		fprintf(stderr,"Error saving xwin_context data");
		exit(1);
	}

	XSelectInput(display,new_button->xid,ev_mask[mode]);

	XMapRaised(display,new_button->xid);

	return new_button;
}



int button_handler(XWIN *p_xwin)
{
	int					x, y, n;
	XWindowAttributes	attr;
	D_BUTTON			*p_data = (D_BUTTON *)p_xwin->data;

	if(event.xany.window == p_xwin->xid){
		switch(event.type){
			case Expose :
				if(event.xexpose.count == 0){
					XGetWindowAttributes(display,p_xwin->xid,&attr);
					x = (attr.width / 2) - (XTextWidth(font,p_data->label,n=strlen(p_data->label)) / 2);
					y = (attr.height / 2) + (FONTHEIGHT / 2);
					XClearWindow(display,p_xwin->xid);
					XDrawString(display,p_xwin->xid,xorgc,x,y,p_data->label,n);
				}
				break;
			case ButtonRelease :
				if(p_data->action != NULL)	(*p_data->action)(p_data->action_args);
				break;
			case EnterNotify :
				XSetWindowBackground(display,p_xwin->xid,FG);
				XClearArea(display,p_xwin->xid,0,0,0,0,True);
				break;
			case LeaveNotify :
				XSetWindowBackground(display,p_xwin->xid,BG);
				XClearArea(display,p_xwin->xid,0,0,0,0,True);
				break;
		}
	}
}



int button16_handler(XWIN *p_xwin)
{
	register int		i, x, y, n;
	unsigned short		*s;
	XWindowAttributes	attr;
	XChar2b				*str;
	D_BUTTON			*p_data = (D_BUTTON *)p_xwin->data;

	n   = jstrlen(p_data->label);
	if((str = (XChar2b *)calloc((unsigned)n,sizeof(XChar2b))) == NULL){
		fprintf(stderr,"No memory for XChar2b");
		exit(1);
	}

	s = (unsigned short *)(p_data->label);
	for(i=0; i<n; i++){
		(str+i)->byte1 = (unsigned char)(sjis2jis(*s) >> 8);
		(str+i)->byte2 = (unsigned char)(sjis2jis(*s) & 0x00ff);
		s ++;
	}


	if(event.xany.window == p_xwin->xid){
		switch(event.type){
			case Expose :
				if(event.xexpose.count == 0){
					XGetWindowAttributes(display,p_xwin->xid,&attr);
					x = (attr.width / 2) - (XTextWidth16(font16,str,n) / 2);
					y = (attr.height / 2) + (FONT16HEIGHT / 2);
					XClearWindow(display,p_xwin->xid);
					XDrawString16(display,p_xwin->xid,xorgc16,x,y,str,n);
				}
				break;
			case ButtonRelease :
				if(p_data->action != NULL)	(*p_data->action)(p_data->action_args);
				break;
			case EnterNotify :
				XSetWindowBackground(display,p_xwin->xid,FG);
				XClearArea(display,p_xwin->xid,0,0,0,0,True);
				break;
			case LeaveNotify :
				XSetWindowBackground(display,p_xwin->xid,BG);
				XClearArea(display,p_xwin->xid,0,0,0,0,True);
				break;
		}
	}

	free((char *)str);
}



int label_handler(XWIN *p_xwin)
{
	int					x, y, n;
	XWindowAttributes	attr;
	D_BUTTON			*p_data = (D_BUTTON *)p_xwin->data;

	if(event.xany.window == p_xwin->xid){
		switch(event.type){
			case Expose :
				if(event.xexpose.count == 0){
					XGetWindowAttributes(display,p_xwin->xid,&attr);
					x = font->max_bounds.width / 2;
					y = FONTHEIGHT;
					XClearWindow(display,p_xwin->xid);
					XDrawString(display,p_xwin->xid,gc,x,y,p_data->label,strlen(p_data->label));
				}
				break;
			case ButtonRelease :
				if(p_data->action != NULL)	(*p_data->action)(p_data->action_args);
				break;
		}
	}
}



int label16_handler(XWIN *p_xwin)
{
	register int		i, x, y, n;
	unsigned short		*s;
	XWindowAttributes	attr;
	XChar2b				*str;
	D_BUTTON			*p_data = (D_BUTTON *)p_xwin->data;

	n   = jstrlen(p_data->label);
	if((str = (XChar2b *)calloc((unsigned)n,sizeof(XChar2b))) == NULL){
		fprintf(stderr,"No memory for XChar2b");
		exit(1);
	}

	s = (unsigned short *)(p_data->label);
	for(i=0; i<n; i++){
		(str+i)->byte1 = (unsigned char)(sjis2jis(*s) >> 8);
		(str+i)->byte2 = (unsigned char)(sjis2jis(*s) & 0x00ff);
		s ++;
	}


	if(event.xany.window == p_xwin->xid){
		switch(event.type){
			case Expose :
				if(event.xexpose.count == 0){
					XGetWindowAttributes(display,p_xwin->xid,&attr);
					x = font->max_bounds.width / 2;
					y = FONT16HEIGHT;
					XClearWindow(display,p_xwin->xid);
					XDrawString16(display,p_xwin->xid,xorgc16,x,y,str,n);
				}
				break;
			case ButtonRelease :
				if(p_data->action != NULL)	(*p_data->action)(p_data->action_args);
				break;
		}
	}

	free((char *)str);
}



int labelV16_handler(XWIN *p_xwin)
{
	register int		i, x, y, n;
	unsigned short		*s;
	XWindowAttributes	attr;
	XChar2b				*str;
	D_BUTTON			*p_data = (D_BUTTON *)(p_xwin->data);

	n   = jstrlen(p_data->label);
	if((str = (XChar2b *)calloc((unsigned)n,sizeof(XChar2b))) == NULL){
		fprintf(stderr,"No memory for XChar2b");
		exit(1);
	}

	s = (unsigned short *)(p_data->label);
	for(i=0; i<n; i++){
		(str+i)->byte1 = (unsigned char)(sjis2jis(*s) >> 8);
		(str+i)->byte2 = (unsigned char)(sjis2jis(*s) & 0x00ff);
		s ++;
	}


	if(event.xany.window == p_xwin->xid){
		switch(event.type){
			case Expose :
				if(event.xexpose.count == 0){
					XGetWindowAttributes(display,p_xwin->xid,&attr);
					x = font->max_bounds.width / 2;
					y = FONT16HEIGHT;
					XClearWindow(display,p_xwin->xid);
					for(i=0; i<n; i++){
						XDrawString16(display,p_xwin->xid,xorgc16,x,y,str+i,1);
						y += FONT16HEIGHT;
					}
				}
				break;
			case ButtonRelease :
				if(p_data->action != NULL){
					(*p_data->action)(p_data->action_args);
				}
				break;
		}
	}

	free((char *)str);
}



int normal_handler(XWIN *p_xwin)
{
	int					x, y, n;
	XWindowAttributes	attr;
	D_BUTTON			*p_data = (D_BUTTON *)p_xwin->data;

	if(event.xany.window == p_xwin->xid){
		switch(event.type){
			case Expose :
				if(event.xexpose.count == 0){
					XGetWindowAttributes(display,p_xwin->xid,&attr);
					x = font->max_bounds.width / 2;
					y = FONTHEIGHT;
					XClearWindow(display,p_xwin->xid);
					XDrawString(display,p_xwin->xid,gc,x,y,p_data->label,strlen(p_data->label));
				}
				break;
			case ButtonRelease :
				if(p_data->action != NULL)	(*p_data->action)(p_data->action_args);
				break;
		}
	}
}



int label216_handler(XWIN *p_xwin)
{
	register int		i, x, y, n;
	unsigned short		*s;
	XWindowAttributes	attr;
	XChar2b				*str;
	D_BUTTON			*p_data = (D_BUTTON *)p_xwin->data;

	n   = jstrlen(p_data->label);
	if((str = (XChar2b *)calloc((unsigned)n,sizeof(XChar2b))) == NULL){
		fprintf(stderr,"No memory for XChar2b");
		exit(1);
	}

	s = (unsigned short *)(p_data->label);
	for(i=0; i<n; i++){
		(str+i)->byte1 = (unsigned char)(sjis2jis(*s) >> 8);
		(str+i)->byte2 = (unsigned char)(sjis2jis(*s) & 0x00ff);
		s ++;
	}


	if(event.xany.window == p_xwin->xid){
		switch(event.type){
			case Expose :
				if(event.xexpose.count == 0){
					XGetWindowAttributes(display,p_xwin->xid,&attr);
					x = (attr.width / 2) - (XTextWidth16(font16,str,n) / 2);
					y = (attr.height / 2) + (FONT16HEIGHT / 2);
					XClearWindow(display,p_xwin->xid);
					XDrawString16(display,p_xwin->xid,xorgc16,x,y,str,n);
				}
				break;
			case ButtonRelease :
				if(p_data->action != NULL)	(*p_data->action)(p_data->action_args);
				break;
		}
	}

	free((char *)str);
}



int labelV16S_handler(XWIN *p_xwin)
{
	register int		i, x, y, n, *nn;
	unsigned short		*s;
	XWindowAttributes	attr;
	XChar2b				*str;
	D_BUTTON			*p_data = (D_BUTTON *)(p_xwin->data);

	n   = jstrlen(p_data->label);
	if((str = (XChar2b *)calloc((unsigned)n,sizeof(XChar2b))) == NULL){
		fprintf(stderr,"No memory for XChar2b");
		exit(1);
	}

	s = (unsigned short *)(p_data->label);
	for(i=0; i<n; i++){
		(str+i)->byte1 = (unsigned char)(sjis2jis(*s) >> 8);
		(str+i)->byte2 = (unsigned char)(sjis2jis(*s) & 0x00ff);
		s ++;
	}


	if(event.xany.window == p_xwin->xid){
		switch(event.type){
			case Expose :
				if(event.xexpose.count == 0){
					XGetWindowAttributes(display,p_xwin->xid,&attr);
					x = font->max_bounds.width / 2;
					y = FONT16HEIGHT;
					XClearWindow(display,p_xwin->xid);
					nn = (int *)(p_data->action_args);
					if(!(*nn)){
						XSetStipple(display, xorgc16, pattern);
						XSetFillStyle(display, xorgc16, FillStippled);
					}
					for(i=0; i<n; i++){
						XDrawString16(display,p_xwin->xid,xorgc16,x,y,str+i,1);
						y += FONT16HEIGHT;
					}
					if(!(*nn)){
						XSetFillStyle(display, xorgc16, FillSolid);
					}
				}
				break;
			case ButtonRelease :
				if(p_data->action != NULL){
					(*p_data->action)(p_data->action_args);
				}
				break;
		}
	}

	free((char *)str);
}



