#include <menu.h>
#include <libc.h>	/* for abort() */

BOOL
button_s::operator==(C button_s& x) C
{
 return (idnum==x.idnum || idnum==ID_ANYITEM || x.idnum==ID_ANYITEM) &&
		(button==x.button || button==AnyB || x.button==AnyB);
}

Menu::operator MENU *()
{
if(!menu && !bad_arg.raise("null ptr: op MENU *")) abort();
return menu;
}

C Menu&
Menu::operator=(C Menu& x)
{
 if(menu)	menufree(menu);
 if(!x.menu && bad_arg.raise("copy of null menu: op="))	abort();
 menu = x.menu;
 return *this;
}

Menu::Menu(struct item *menuitem, int width)
{
 menu = makepopup(menuitem, width);
 if(!menu && !no_mem.raise("make popup menu")) abort();
}

Menu::Menu(int x, int y, int width, int fg, int bg, int fgm,
								int bgm, int fgna, int bgna)
{
menu = makemenu(x, y, width, fg, bg, fgm, bgm, fgna, bgna);
if(!menu && !no_mem.raise("make top-level menu")) abort();
}

button_s::button_s(enum whichbutton b)
{
 idnum = get_next_id(b); button = b;
}

button_s::button_s()
{
 idnum = get_next_id(AnyB); button = AnyB;
}

C int Smallestcomputer = 1000;
int button_s::next_id = Smallestcomputer;
BITS button_s::b_used = 0;

int
button_s::get_next_id(enum whichbutton x)
{
 BITS use = 0;
 if(x == AnyB)	{
	int i;
	for(i=FirstB;i<LastB;i++)
		use |= 1<<(i-FirstB+1);
	}
 else if(x != NoB)	use |= 1<<(x-FirstB+1);

 if(b_used & use)	{next_id++;	b_used = 0;}
 b_used |= use;

 return next_id;
}

button_s
button_s::operator|(C button_s& x) C
{
 if(idnum!=x.idnum && error.raise("operator| : unequal idnum")==0)
	abort();
 if((button==NoB || x.button==NoB || button==x.button ||
		button==AnyB || x.button==AnyB) &&
		error.raise("operator|: conflicting buttons")==0)
	abort();
 return *this;
}

button_s::operator int() C
{
 if(error.raise("op int: NoButton")==0)
	abort();
 return idnum;
}

int
button_s::operator-(C button_s &x) C
{
  return button-x.button;
}

button_s
button_s::operator+(int x) C
{
 return button_s(idnum+x, button);
}

C BOOL MENU::false = FALSE;

struct item *
Menu::operator[](void *q)
{
 MENU *C m = menu;
 struct item *p;

 for(p=m->first;p;p=p->next)
	if(q == p->value)
		return p;

 return 0;
}

