#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include <panel.h>
#include "pldefs.h"
void *pl_emalloc(int n){
	void *v;
	v=mallocz(n, 1);
	if(v==0){
		fprint(2, "Can't malloc!\n");
		exits("no mem");
	}
	setmalloctag(v, getcallerpc(&n));
	return v;
}
void *pl_erealloc(void *v, int n)
{
	v=realloc(v, n);
	if(v==0){
		fprint(2, "Can't realloc!\n");
		exits("no mem");
	}
	setrealloctag(v, getcallerpc(&v));
	return v;
}
void pl_unexpected(Panel *g, char *rou){
	fprint(2, "%s called unexpectedly (%s %#p)\n", rou, g->kind, g);
	abort();
}
void pl_drawerror(Panel *g){
	pl_unexpected(g, "draw");
}
int pl_hiterror(Panel *g, Mouse *m){
	USED(m);
	pl_unexpected(g, "hit");
	return 0;
}
void pl_typeerror(Panel *g, Rune c){
	USED(c);
	pl_unexpected(g, "type");
}
Point pl_getsizeerror(Panel *g, Point childsize){
	pl_unexpected(g, "getsize");
	return childsize;
}
void pl_childspaceerror(Panel *g, Point *ul, Point *size){
	USED(ul, size);
	pl_unexpected(g, "childspace");
}
void pl_scrollerror(Panel *g, int dir, int button, int num, int den){
	USED(dir, button, num, den);
	pl_unexpected(g, "scroll");
}
void pl_setscrollbarerror(Panel *g, int top, int bot, int den){
	USED(top, bot, den);
	pl_unexpected(g, "setscrollbar");
}
int pl_prinormal(Panel *, Point){
	return PRI_NORMAL;
}
Panel *pl_newpanel(Panel *parent, int ndata){
	Panel *v;
	if(parent && parent->flags&LEAF){
		fprint(2, "newpanel: can't create child of %s %#p\n", parent->kind, parent);
		exits("bad newpanel");
	}
	v=pl_emalloc(sizeof(Panel));
	v->r=Rect(0,0,0,0);
	v->flags=0;
	v->ipad=Pt(0,0);
	v->pad=Pt(0,0);
	v->size=Pt(0,0);
	v->sizereq=Pt(0,0);
	v->lastmouse=0;
	v->next=0;
	v->child=0;
	v->echild=0;
	v->b=0;
	v->pri=pl_prinormal;
	v->scrollee=0;
	v->xscroller=0;
	v->yscroller=0;
	v->parent=parent;
	v->scr.pos=Pt(0,0);
	v->scr.size=Pt(0,0);
	if(parent){
		if(parent->child==0)
			parent->child=v;
		else
			parent->echild->next=v;
		parent->echild=v;
	}
	v->draw=pl_drawerror;
	v->hit=pl_hiterror;
	v->type=pl_typeerror;
	v->getsize=pl_getsizeerror;
	v->childspace=pl_childspaceerror;
	v->scroll=pl_scrollerror;
	v->setscrollbar=pl_setscrollbarerror;
	v->free=0;
	v->snarf=0;
	v->paste=0;
	if(ndata)
		v->data=pl_emalloc(ndata);
	else
		v->data=0;
	return v;
}
void plfree(Panel *p){
	Panel *cp, *ncp;
	if(p==0)
		return;
	if(p==plkbfocus)
		plkbfocus=0;
	for(cp=p->child;cp;cp=ncp){
		ncp=cp->next;
		plfree(cp);
	}
	if(p->free) p->free(p);
	if(p->data) free(p->data);
	free(p);
}
