/********************************************************/
/*	handles all i g n o r e s			*/
/********************************************************/

/* ignore.c	-  i g n o r e  c o m m a n d
   distributed as part of _ s u l a _
    
    Author: Tano Fotang, Sep 1997

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License , or
    (at your option) any later version.
    see the file COPYING for more info.

*/



#include <forms.h>
#include <errno.h>
#include <sys/param.h>
#include <fnmatch.h>
#include "config.h"
#include "aux.h"
#include "sula.h"
#include "chanwin.h"
#include "etc.h"
#include "global.h"
#include "etc.h"
#include "ignore.h"
#include "cmd.h"
#include "setting.h"


typedef struct TWhat{
	char *name;
	int  what;
	char *help;
}What;

	/*ignore cmds; keep sorted!!! */
What ig_what[]={ 
		{"abs",		IG_ABS,		"Absolutely abandon (even nick, mode, topic..changes: evyrthang)"},
		{"all",		IG_ALL,		"all message types and DCCs"},
		{"channel",	IG_PUBMSG,	"normal channel messages"},
		{"ctcp",	IG_CTCP,	"all CTCPs (ping, time etc)"},
		{"dcc"  ,	IG_DCC,		"all DCC's (chat, send file requests)"},
		{"etc",		IG_MISC,	"nick, mode, topic changes by the person, plus some xtra stuff"},
		{"everythang",	IG_ABS,		"same as abs"},
		{"invites",	IG_INVITE,	"invitations"},
		{"misc",	IG_MISC,	"same as etc"},
		{"msg",		IG_PRIVMSG,	"private messages"},
		{"none",	IG_NONE,	"ignore nothing (reset)"},
		{"notes", 	IG_NOTE,	"notes"},
		{"notices",	IG_PRIVNOTICE,	"private notices"},
		{"pubmsg",	IG_PUBMSG,	"normal channel messages"},
		{"pubnotices"  ,IG_PUBNOTICE,	"public (chanel) notices"},
		};


static int binary(const char *var, int n){
	register int low, high, mid, cond;
	low=0; high=n-1;
	while(low<=high){
		mid=(low+high)/2;
		if( (cond=strcasecmp(var, ig_what[mid].name))<0 )
			high=mid-1;
		else if(cond>0)
			low=mid+1;
		else
			return mid;
	}
	return -1;
}

extern int ignored(const char *mask, int flag){
	Ignore *p=ignoreStart;
	char *pat=lowercase(mask);
	while(p!=ignoreEnd){
		if(
			!fnmatch(lowercase(p->mask), pat, /*FNM_NOESCAPE|*/ FNM_PATHNAME|FNM_PERIOD)
			&& (p->what & flag)
		)
			return 1;
		else p=p->next;
	}
	return 0;
 }

 static Ignore *get_ignore(const char *mask){
	Ignore *p=ignoreStart;
	while(p!=ignoreEnd){
		if(!strcasecmp(mask, p->mask))
			return p;
		else p=p->next;
	}
	return NULL;
 }

static char *save_ignore(char *fname){
	FILE *fp;
	Ignore *p;
	time_t t=time(NULL);
	char buf[MAXLINE];
	if(!fname){
		if(! (fname=getenv("HOME")) ) fname=".";
		sprintf(buf,"%s/%s%s", fname , P_HOME, P_IGNORE);
		fname=strdup(buf);
	}
	if(access(fname,F_OK)>-1){ 
		if(access(fname,W_OK)<0){
			return NULL;
		}
		sprintf(buf, "%s.bak", fname);
		rename(fname,buf);	/* dont care whether this succeeds or not*/
	}
	if( (fp=fopen(fname, "w"))==NULL){  /* jeez.. stop repeatin yerself*/
		 return NULL;
	}
	fprintf(fp,"%c"sula_NAME sula_VERSION"\n%cIgnore list %s\n\n",COMMENT,COMMENT,  ctime(&t));
	p=ignoreStart;
	while(p!=ignoreEnd){
		sprintf(buf, "%s\t%#x\t%hu\n", p->mask, p->what,p->period);
		fputs(buf, fp);
		p=p->next;
	}
	fflush(fp);
	fclose(fp);
	return strdup(fname);
}
static char *load_ignore(char *fname){
	
	
	FILE *fp;
                Ignore *p, *q;
                char buf[MAXLINE+1];
                if(!fname){
                        if(! (fname=getenv("HOME")) ) fname=".";
                        sprintf(buf,"%s/%s%s", fname , P_HOME, P_IGNORE);
                        fname=strdup(buf);
                }
                fprintf(stderr, "load ignore:%s\n",fname);
                if( (fp=fopen(fname, "r"))==NULL)  return NULL;
                while( fgets(buf, MAXLINE, fp)!=NULL){
                        char *l;
			int i;

                        buf[strlen(buf)-1]='\0';
                        l=clean(buf);
                        if(!l || *l==COMMENT) continue;
                        p=(Ignore *)malloc(sizeof(Ignore));
                        if(!p) {berr_ret("%s %d", __FILE__, __LINE__); break;}
                        p->mask=nextstr(l,1);
                        i=sscanf(l,"%*s %i %hu", &p->what, &p->period);
                        if(i<2) p->period=0;
                        if(i<1) p->what=IG_ALL;
                        p->starttime=time(NULL);
                        q=ignoreStart;
                        ignoreStart=(Ignore *)malloc(sizeof(Ignore));
                        *ignoreStart=*p;
                        ignoreStart->next=q;
                }
                fclose(fp);
	return strdup(fname);
}


#define ig_remove	0
#define ig_add		1
static void list_ignore(FL_OBJECT *brow);
static int remove_ignore(const char *);

extern void ignore(int argc, char **argv, Winstruct *win){
	/* e.g.: ig mask -all +all -privmsg +pubotice for 10
		ig -c(lear)
		ig -d(elete) 
	*/
	char flag=ig_add, new_ig=0, has_changed=0;
	int i;
	int nvars;
	Ignore *p=NULL;

	if(!win) return;
	if( argc==1 || !strncasecmp(argv[1], "-list", 3) ){ 
		list_ignore(win->chanwin->browser);
		return;
	}
	if( !strncasecmp(argv[1], "-help", 2) ){ 
		show_std_help(uppercase(argv[0]), NULL, win->chanwin);
		return;
	}
	if( !strncasecmp(argv[1], "-load", 3) ){ 
		char *fname=load_ignore(argv[2]);
		if(!fname){
			char *errstr=strerror(errno);
			char *buf=malloc(sizeof(char)*(strlen(errstr)+
			strlen(PROMPT)+16));
			sprintf(buf,PROMPT"ignore_file: %s",errstr);
			fl_addto_browser(win->chanwin->brow2, buf);
		}else
                	if(ignore_form) fl_call_object_callback(ignore_form->update);
                return;
	}
	if( !strncasecmp(argv[1], "-save", 3) ){
		char *fname=save_ignore(argv[2]);
		if(!fname){
			char *errstr=strerror(errno);
			char *buf=malloc(sizeof(char)*(strlen(errstr)+
			strlen(PROMPT)+24));
			sprintf(buf,PROMPT"No write access: %s",errstr);
			fl_addto_browser(win->chanwin->brow2, buf);
		}
		return;
	}


	argv++;

	 if( !strncasecmp(*argv, "-clear", 2) ){ 
		Ignore *p=ignoreStart;
		fl_addto_browser(win->chanwin->brow2, PROMPT"Clearing ignore list..");
		while(p!=ignoreEnd){
			Ignore *q=p->next;
			free(p->mask);
			if(q==ignoreEnd) ignoreEnd=p; else *p=*q; free(q);
		}
		if(ignore_form) fl_call_object_callback(ignore_form->update);
		return;
	}
	
	p=get_ignore(*argv);
	if(p){  /*&& p!=NULL*/
		
		if(argc<3)p->what=IG_ALL;
	       	p->starttime=time(NULL);

	}else
	if(!p){
		p= (Ignore *)malloc(sizeof(Ignore));
		if(!p) {err_ret("ignore errer"); return;}
		new_ig=1;
		p->mask=strdup(*argv);
		p->what= argc<3? IG_ALL : 0;
		p->period=0;
		has_changed=0;
	}
	 argv++;
	 nvars=sizeof(ig_what)/sizeof(What);
	 while (*argv){
		if((*argv)[0]=='-'){ 
			flag=ig_remove; (*argv)++;
			if(!(*argv)) continue;
		}
		else{
			if(**argv=='+'){ (*argv)++;
				if(!(**argv) ) { argv++;continue;}
			}
			if(!strcasecmp(*argv, "for")){
			 	char u[8];
			   	if ( (!(*++argv) || sscanf(*argv, "%hu", &p->period)<1) ){
			   		if(win)
			      			fl_addto_browser(win->chanwin->brow2, PROMPT"ignore: for how long?");
					else  fprintf(stderr,PROMPT"ignore: for how long?");
					continue;
			   	}
			   	if(sscanf( *argv, "%*u%7s", u)<0)
					if(!(*++argv) || sscanf( *argv, "%7s", u)<0)
					 continue;
				if(!strcasecmp(u,"mins") || !strcasecmp(u,"minutes")
					|| !strcasecmp(u,"minute") || !strcasecmp(u,"min"))
						{argv++ ;}
				else
				if(!strcasecmp(u,"sec") || !strcasecmp(u,"secs")
					|| !strcasecmp(u,"second") || !strcasecmp(u,"seconds"))
						{ 
						if(p->period<60) p->period=60;
						p->period/=60; argv++;
						}
				else 
				if( !strcasecmp(u,"hour") || !strcasecmp(u,"hours")
					|| !strcasecmp(u,"hrs") || !strcasecmp(u,"hr"))
						{ p->period*=60;argv++;}
				continue;
			}else flag=ig_add;
		}
		if(!(*argv) ) break;
		i=binary(*argv, nvars);
		if(i<0){
			char *buf=(char *)malloc(sizeof(char)*(strlen(PROMPT)+strlen(*argv)+25));
			sprintf(buf, PROMPT"ignore: Unkown type \"%s\"", *argv); 
			fl_addto_browser(win->chanwin->brow2,buf);
			argv++;
			continue;
		}
		has_changed=1;
		if(ig_what[i].what==IG_NONE) p->what=0;
		else 
		p->what =flag==ig_remove? p->what & ~ig_what[i].what: p->what | ig_what[i].what;
		argv++;
	}
	if(new_ig && !has_changed) p->what=IG_ALL;
	if(p->what==0){
		char *s=(char *)malloc(sizeof(char)*(strlen(PROMPT)+strlen(p->mask)+45));
		char *tmp=strdup(p->mask);
		if(!remove_ignore(p->mask)){
			sprintf(s, PROMPT"No longer ignoring %s.",tmp);
		/*else 
			sprintf(s, PROMPT"%s couldn't be removed from ignore list",p->mask);
		*/
			fl_addto_browser(win->chanwin->brow2,s);
		}
		if(ignore_form) fl_call_object_callback(ignore_form->update);
		return;
	}
	if(new_ig){
		Ignore *q=ignoreStart;
		ignoreStart=(Ignore *)malloc(sizeof(Ignore));
		if(!ignoreStart) {err_ret("ignore errer"); return;}
		ignoreStart->mask=strdup(p->mask);
		ignoreStart->what=p->what;
		ignoreStart->starttime=time(NULL);
		ignoreStart->period=p->period>0? p->period:0;
		ignoreStart->next=q;
		
	}
	if(gflags&VERBOSE_CLIENT)
        {	char buf[MAXLINE], s[512];
		char t[20];

		p=ignoreStart;
		if(p->period>0) 
			sprintf(t,"%ld min(s)", (p->starttime + 60*p->period - time(NULL))/60);
		else strcpy(t,"infinity");
		if(p->what == IG_ABS) sprintf(s,"be careful: ignoring completely");
		else{
			 size_t ll;
			 sprintf(s," %s%s%s%s%s%s%s%s",
					p->what & IG_MISC?	"misc stuff, ":"",
					p->what & IG_PRIVMSG?	"priv msg, ":"",
					p->what & IG_PUBMSG?	"pub msg, ":"",
					p->what & IG_PRIVNOTICE?"priv notices, ":"",
					p->what & IG_INVITE?	"invites, ":"",
					p->what & IG_DCC?	"DCCs, ":"",
					p->what & IG_NOTE?	"notes, ":"",
					p->what & IG_CTCP?	" CTCPs ":""
				);
			ll=strlen(s)-1;
			if( *(s+ --ll)==',') *(s+ll)='\0';
		}
		sprintf(buf,"@f"PROMPT"Ignoring %s for %s (%s)", p->mask,t,s);
		fl_addto_browser(win->chanwin->brow2,buf);
		if(ignore_form) fl_call_object_callback(ignore_form->update);
		
	}
}

 
 
static int remove_ignore(const char *mask){
	Ignore *p=ignoreStart;

	while(p!=ignoreEnd){
		if(!strcasecmp(p->mask, mask)){
			Ignore *q=p->next;
			free(p->mask);
			if(q==ignoreEnd) ignoreEnd=p;else *p=*q; free(q);
			return 0;
		}
		else p=p->next;
	}
	return (-1);
}

static void list_ignore(FL_OBJECT *brow){
	Ignore *p=ignoreStart;
	char i=0;

	while(p!=ignoreEnd){
		char buf[MAXLINE], s[200];
		char t[20];
		if(p->period>0) 
			sprintf(t,"%ld min(s)", 1+(p->starttime + 60*p->period - time(NULL))/60);
		else strcpy(t,"infinity");
		if(!i){
			sprintf(buf, "@f@b%-30s %-10s Ignoring what?", "Who", "Time left");
			fl_addto_browser(brow, buf);
			i=1;
		}
		if ( p->what==IG_ABS) sprintf(s, "all traces of them");
		else if( p->what==IG_ALL) sprintf(s,"all message types");
		else{
			size_t ll;
			sprintf(s,"%s%s%s%s%s%s%s%s%s",
					p->what & IG_MISC?	"misc.(mode,nick..), ":"",
					p->what & IG_PRIVMSG?	"priv. msgs, ":"",
					p->what & IG_PUBMSG?	"chan. msgs, ":"",
					p->what & IG_PRIVNOTICE?"priv. notices, ":"",
					p->what & IG_PUBNOTICE?	"chan. notices, ":"",
					p->what & IG_INVITE?	"invites, ":"",
					p->what & IG_DCC?	"DCCs, ":"",
					p->what & IG_NOTE?	"notes, ":"",
					p->what & IG_CTCP?	"CTCPs ":""
				);
			ll=strlen(s)-1;
			if( *s && *(s+ --ll)==',') *(s+ll)='\0';
		}
		sprintf(buf,"@f%-30s %-10s %s", p->mask, t, s);
		fl_addto_browser(brow, buf);
		p=p->next;
	}

	if(i==0) fl_addto_browser(brow,PROMPT"Ignore list is empty");

	return;
}

/*

callbacks

*/

static void load_ignore_list(void){
	Ignore *p=ignoreStart;
	
	fl_freeze_form(ignore_form->ignore);
	while(p!=ignoreEnd){
		char buf[128], t[20];
		if(p->period>0){
			time_t tt= 1+(p->starttime + 60*p->period - time(NULL))/60;
			sprintf(t,"%ld minute%s",tt, tt>1?"s":"" );
		}
		else strcpy(t,"infinity");
		sprintf(buf,"@f%-40s %s", p->mask, t);
		fl_addto_browser(ignore_form->browser, buf);
		p=p->next;
	}
	fl_set_button(ignore_form->msg,0);
	fl_set_button(ignore_form->pubmsg,0);
	fl_set_button(ignore_form->notice,0);
	fl_set_button(ignore_form->pubnotice,0);
	fl_set_button(ignore_form->invites,0);
	fl_set_button(ignore_form->dcc,0);
	fl_set_button(ignore_form->note,0);
	fl_set_button(ignore_form->ctcp,0);
	fl_set_button(ignore_form->misc,0);
	fl_unfreeze_form(ignore_form->ignore);

	return;
}

static void ignore_browser(void){
	int n;
	char *buf, *mask;
	Ignore *p;

	n=fl_get_browser(ignore_form->browser);
	if(n<1){ return; }
	buf=(char *) fl_get_browser_line(ignore_form->browser,n);
	mask=(char *)malloc(sizeof(char)*strlen(buf));
	if(!mask){berr_ret("%s %d", __FILE__, __LINE__); return;}
	if(sscanf(buf,"@f%s", mask)<1){
		#if DEBUG
		err_quit("%s %d error.......",__FILE__, __LINE__ );
		#endif
		return;
	}
	p=get_ignore(mask);
	if(!p){
		char buf[128];
		sprintf(buf,"\"%s\" has expired (?)", mask);
		fit_object_label(ignore_form->status, buf);
		/*fl_call_object_callback(ignore_form->update); endless loop!*/
		return;
	}else{
	fl_set_button(ignore_form->msg,p->what & IG_PRIVMSG);
	fl_set_button(ignore_form->pubmsg,p->what & IG_PUBMSG);
	fl_set_button(ignore_form->notice,p->what & IG_PRIVNOTICE);
	fl_set_button(ignore_form->pubnotice,p->what & IG_PUBNOTICE);
	fl_set_button(ignore_form->invites,p->what & IG_INVITE);
	fl_set_button(ignore_form->dcc,p->what & IG_DCC);
	fl_set_button(ignore_form->note,p->what & IG_NOTE);
	fl_set_button(ignore_form->ctcp,p->what & IG_CTCP);
	fl_set_button(ignore_form->misc,p->what & IG_MISC);

	}

}

static void ignore_remove(void){
	int n;
	char *buf, *mask;
	
	n=fl_get_browser(ignore_form->browser);
	if(n<1){ fl_set_object_label(ignore_form->status,"Remove what??"); return; }
	buf=(char *) fl_get_browser_line(ignore_form->browser,n);
	mask=(char *)malloc(sizeof(char)*strlen(buf));
	if(!mask){berr_ret("%s %d", __FILE__, __LINE__); return;}
	if(sscanf(buf,"@f%s", mask)<1){
		#if DEBUG
		fprintf(stderr,"%s %d error.......",__FILE__, __LINE__ );
		#endif
		return;
	}
	if(!remove_ignore(mask)){
		buf=(char *)malloc(sizeof(char)*(strlen(mask)+45));
		sprintf(buf, "No longer ignoring %s",mask);
		fit_object_label(ignore_form->status, buf);
		free(buf);
	}
	else{
		buf=(char *)malloc(sizeof(char)*(strlen(mask)+45));
		sprintf(buf,"\"%s\" has expired (?)", mask);
		fit_object_label(ignore_form->status, buf);
		free(buf);
	}
	fl_call_object_callback(ignore_form->update);
       	return;
}


static void ignore_add(void){
	FD_edit_ig *form=create_form_edit_ig();

	fl_set_cursor(ignore_form->ignore->window, XC_watch);
	fl_deactivate_form(ignore_form->ignore);
	fl_set_form_atclose(form->edit_ig, dont_close_win, 0);
	/* prehandler:*/
	form->mask->u_ldata=form->period->u_ldata=(long)XC_xterm;
	fl_set_object_prehandler(form->mask, set_cursor);
	fl_set_object_prehandler(form->period, set_cursor);
	
	fl_addto_choice(form->unit,"seconds|minutes|hours");
	fl_set_choice(form->unit,2);
	fl_set_choice_fontsize(form->unit,14);
 	fl_set_choice_fontstyle(form->unit,FL_TIMES_STYLE);
	fl_set_choice_align(form->unit,FL_ALIGN_LEFT);

	fl_show_form(form->edit_ig,FL_PLACE_MOUSE,FL_FULLBORDER,sula_NAME sula_VERSION": Add an ignore mask");
	while(fl_do_forms()!=form->close);
	

}
static void ignore_edit(void){
	FD_edit_ig *form=create_form_edit_ig();
	int n;
	char *buf, *mask;
	Ignore *p;

	n=fl_get_browser(ignore_form->browser);
	if(n<1){ fl_set_object_label(form->status,"edit, edit what??"); return; }

	fl_set_cursor(ignore_form->ignore->window, XC_watch);
	fl_deactivate_form(ignore_form->ignore);
	fl_set_form_atclose(form->edit_ig, dont_close_win, 0);

	buf=(char *) fl_get_browser_line(ignore_form->browser,n);
	mask=(char *)malloc(sizeof(char)*strlen(buf));
	if(!mask){berr_ret("%s %d", __FILE__, __LINE__); return;}
	if(sscanf(buf,"@f%s", mask)<1){
		#if DEBUG
		err_quit("%s %d bug...",__FILE__, __LINE__ );
		#endif
		return;
	}
	p=get_ignore(mask);
	if(!p){
		char buf[128];
		sprintf(buf,"cant find \"%s\". gone?? bug then", mask);
		fl_set_object_label(ignore_form->status,buf);
		return;
	}else{
	       	char buf[12];
		sprintf(buf,"%d",p->period);
		fl_set_input(form->mask, p->mask);
       		fl_set_input(form->period, buf);
	}

	/* prehandler:*/
	form->mask->u_ldata=form->period->u_ldata=(long)XC_xterm;
	fl_set_object_prehandler(form->mask, set_cursor);
	fl_set_object_prehandler(form->period, set_cursor);
	
	fl_addto_choice(form->unit,"seconds | minutes | hours");
	fl_set_choice(form->unit,2);
	fl_set_choice_fontsize(form->unit,14);
 	fl_set_choice_fontstyle(form->unit,FL_TIMES_STYLE);
	fl_set_choice_align(form->unit,FL_ALIGN_LEFT);

	
	fl_show_form(form->edit_ig,FL_PLACE_MOUSE,FL_FULLBORDER,sula_NAME sula_VERSION": Edit an ignore mask");
	while(fl_do_forms()!=form->close);

}

void ig_edit_cb(FL_OBJECT *ob, long data){
FD_edit_ig *form=(FD_edit_ig *)ob->form->fdui;

if(data){
	fl_hide_form(form->edit_ig);
	fl_free_form(form->edit_ig);
	fl_reset_cursor(ignore_form->ignore->window);
	fl_activate_form(ignore_form->ignore);
}else
   {
        char *mask;
	u_short t;
	Ignore *p;
	char buf[128];

	mask=nextstr(fl_get_input(form->mask),1);
	if(!mask){
		fl_set_object_label(form->status, "Specify a mask or cancel!");
		fl_ringbell(0);
		return;
	}
	switch(fl_get_choice(form->unit)){
		default:
		case 0: /* NO SELECTION */
		case 2: t=atoi(fl_get_input(form->period));/*minutes */
			break;
		case 1:t=atoi(fl_get_input(form->period));	/* secs*/
			t=t>59? t/60:1; 
			break;
		case 3:	t=atof(fl_get_input(form->period))*60;	/* hour */ 
			break;
	}

	p=get_ignore(mask);
	if(p){  
	       	
#warning you may prefer not to reset starttime; comment out:
	       	p->starttime=time(NULL);

		p->period=t;
		sprintf(buf,"\"%s\" exists. Times updated", mask);
		
	}else
	{
		Ignore *q=ignoreStart;
		ignoreStart=(Ignore *)malloc(sizeof(Ignore));
		if(!ignoreStart) err_sys("%s %d",__FILE__,__LINE__);
		ignoreStart->mask=strdup(mask);
		ignoreStart->what= IG_ALL;
		ignoreStart->starttime=time(NULL);
		ignoreStart->period=t;
		ignoreStart->next=q;
				
		sprintf(buf,"\"%s\" has been added to ignore list", mask);
		
	}
	fit_object_label(form->status, buf);
	fl_call_object_callback(ignore_form->update);

   }
}

static void ig_ok(void){
	int n;
	char *buf, *mask;
	Ignore *p;

	n=fl_get_browser(ignore_form->browser);
	if(n<1){ return; }
	buf=(char *) fl_get_browser_line(ignore_form->browser,n);
	mask=(char *)malloc(sizeof(char)*strlen(buf));
	if(!mask){berr_ret("%s %d", __FILE__, __LINE__); return;}
	if(sscanf(buf,"@f%s", mask)<1){
		#if DEBUG
		fl_set_object_label(ignore_form->status, "error.......");
		#endif
		return;
	}
	p=get_ignore(mask);
	if(!p){
		char buf[128];
		sprintf(buf,"\"%s\" has expired (?)", mask);
		fit_object_label(ignore_form->status, buf);
		fl_call_object_callback(ignore_form->update);
		return;
	}else{
		p->what=0;
		if(fl_get_button(ignore_form->msg))	 	p->what|= IG_PRIVMSG;
		if(fl_get_button(ignore_form->pubmsg))		p->what|= IG_PUBMSG;
		if(fl_get_button(ignore_form->notice))		p->what|= IG_PRIVNOTICE;
		if(fl_get_button(ignore_form->pubnotice))	p->what|= IG_PUBNOTICE;
		if(fl_get_button(ignore_form->invites))		p->what|= IG_INVITE;
		if(fl_get_button(ignore_form->dcc))		p->what|= IG_DCC;
		if(fl_get_button(ignore_form->note))		p->what|= IG_NOTE;
		if(fl_get_button(ignore_form->ctcp))		p->what|= IG_CTCP;
		if(fl_get_button(ignore_form->misc))		p->what|= IG_MISC;

		if(p->what==0){
			if(!remove_ignore(p->mask)){
			char buf[128];
			sprintf(buf, "No longer ignoring %s",mask);
			fit_object_label(ignore_form->status, buf);
			}
		}
		fl_call_object_callback(ignore_form->update);
	}
}

void ig_save(void){
	char  *ptr;
	char buf[512];
	fl_set_cursor(ignore_form->ignore->window, XC_watch);
	fl_deactivate_form(ignore_form->ignore);
	ptr=getstr2("File name:",
		sula_NAME sula_VERSION": Save ignore list","ignore.txt",  1);
	fl_activate_form(ignore_form->ignore);
	fl_reset_cursor(ignore_form->ignore->window);
	ptr=clean(ptr);
	if(!ptr) return;

	if(!save_ignore(ptr))
		sprintf(buf,"Cant write %s: %s",ptr,strerror(errno));
	else sprintf(buf,"ignore list saved as %s",ptr);
	fit_object_label(ignore_form->status, buf);
}
void ig_load(void){
	char  *ptr;
	char buf[512];

	fl_set_cursor(ignore_form->ignore->window, XC_watch);
	fl_deactivate_form(ignore_form->ignore);
	ptr=getstr2("File name:",
		sula_NAME sula_VERSION": Load ignore file","",  1);
	fl_activate_form(ignore_form->ignore);
	fl_reset_cursor(ignore_form->ignore->window);
	ptr=clean(ptr);
	if(!ptr) return;
	if(!load_ignore(ptr))
		sprintf(buf,"cant read %s: %s",ptr, strerror(errno));
	else{
		 sprintf(buf,"ignore %s loaded",ptr);
		 fl_trigger_object(ignore_form->update);
	}
	fit_object_label(ignore_form->status, buf);
}

	


void ignore_form_cb(FL_OBJECT *ob, long data){
switch(data){
	case 0:	/* browser*/
		ignore_browser();
		break;
	case 1:/* remove*/
		ignore_remove(); break;
	case 2: ignore_edit();break;
	case 3: ignore_add();break;
case 4:	/*save*/
	ig_save();break;
case 5:	/*load*/
	ig_load(); break;
case 6:{ 	/*update*/
	int n=fl_get_browser(ignore_form->browser), m;

	fl_clear_browser(ignore_form->browser);
	load_ignore_list();
	m=fl_get_browser_maxline(ignore_form->browser);
	if(m>0){
		if(m>n && n>0)	fl_select_browser_line(ignore_form->browser, n);
		else fl_select_browser_line(ignore_form->browser, m);
		
	}
	/*fl_call_object_callback(ignore_form->browser);*/
	fl_trigger_object(ignore_form->browser);
	break;
}
	case 7: {/*dismiss*/
		FD_ignore *form=(FD_ignore *)ob->form->fdui;
		fl_hide_form(form->ignore);
		(*((FD_ignore **)form->done->u_vdata))=NULL;
		fl_free_form(form->ignore);
		break;
	}
	case 8: /* ok*/
       		ig_ok();break;
	default:break;
	} /* switch*/
}


