#ifndef CODE_GROUP_CXX
#define CODE_GROUP_CXX

/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: group.cxx,v 1.2 2003/02/26 14:07:45 schmitzj Exp $)
 * 
 * Copyright (C) 1998 Jürgen Schmitz
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 *-----------------------------------------------------------------------
 */

#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include "types.h"
#include <Xclasses/gadget.h>
#include <Xclasses/gfx_text.h>
#include <Xclasses/group.h>
#include <Xclasses/lefttext.h>
#include "include/group_p.h"


// #define RUNTIME

#define FENSTERRAHMEN	2

int group_free_clear=1;

group::group(void) : gadget()
{
	while (!(p=new pgroup))
	{
		outOfMemory("group");
	}
	p->o=this;

	p->shadow=this;
	p->shown=this;
	p->samesize=this;
	Font(FONT_GROUP);
	Name("group");
	SetKeyHandler(KHM_NONE);
}
pgroup::pgroup()
{
	aused=0;
	asize=0;
	stripes=0;
	shadow=NULL;
	shown=NULL;
	subs=NULL;
	
	abstand_w=0;
	abstand_h=0;

	center=0;
	right=0;
	shadowgroup=0;
	horiz=0;
	requester=0;
	req_h=0;
	req_v=0;
	allocated=0;
	maped=0;
	windowmaster=0;
	hasgps=0;
	smallest=0;
	before_x_done=0;
}
group::~group(void)
{
	if (win) Free();
	if (p) delete p;
}
pgroup::~pgroup()
{
	if (aused>0)
	{
		for (int i=0;i<aused;i++)
		{
			if (subs[i].lt)
			{
				delete subs[i].lt;
				subs[i].lt=NULL;
			}
			if (subs[i].group && subs[i].allocated && subs[i].gp->p->allocated)
			{
				delete subs[i].gp;
			}
		}
		aused=0;
	}
	if (asize>0)
	{
		if (subs) delete subs;
		asize=0;
	}
}

#define BLOCK 10
char *group::Class(void)
{
	return "group";
}

group &group::Add(class gadget &gd)
{
	Add(&gd);
	return *this;
}
group &group::Add(gadget &gd,char *lt)
{
	Add(&gd,lt);
	return *this;
}
group *group::Add(class gadget *gd)
{
	p->aused++;
	if (p->aused>p->asize)
	{
		struct sub *c;
		if (c=new sub[p->asize+BLOCK])
		{
			for(int i=0;i<(p->aused-1);i++)
			{
				c[i]=p->subs[i];
			}
			if (p->subs) delete p->subs;
			p->subs=c;
			p->asize=p->asize+BLOCK;
		}
		else
		{
			p->aused--;
			return this;
		}
	}
	p->subs[p->aused-1].gg=gd;
	p->subs[p->aused-1].lt=NULL;
	gd->ParentClass(this);
	if (strcmp(gd->Class(),"group"))
	{
		p->subs[p->aused-1].allocated=0;
		p->subs[p->aused-1].group=0;
	}
	else
	{
		p->subs[p->aused-1].allocated=((group*)gd)->p->allocated;
		p->subs[p->aused-1].group=1;	
		p->hasgps=1;
	}
	return this;
}
group *group::Add(gadget *gd,char *lt)
{
	p->aused++;
	if (p->aused>p->asize)
	{
		struct sub *c;
		if (c=new sub[p->asize+BLOCK])
		{
			for(int i=0;i<(p->aused-1);i++)
			{
				c[i]=p->subs[i];
			}
			if (p->subs) delete p->subs;
			p->subs=c;
			p->asize=p->asize+BLOCK;
		}
		else
		{
			p->aused--;
			return this;
		}
	}
	if (p->subs[p->aused-1].lt=new lefttext)
	{
		p->subs[p->aused-1].lt->Name(NULL);
		p->subs[p->aused-1].lt->Text(lt);
		p->subs[p->aused-1].lt->Gadget(gd);
		if (lt) gd->ApplyKey(gfx_text::ShortCut(lt));
		gd=p->subs[p->aused-1].lt;
	}
	p->subs[p->aused-1].gg=gd;
	gd->ParentClass(this);
	if (strcmp(gd->Class(),"group"))
	{
		p->subs[p->aused-1].allocated=0;
		p->subs[p->aused-1].group=0;
	}
	else
	{
		p->subs[p->aused-1].allocated=0;
		p->subs[p->aused-1].group=1;	
		p->hasgps=1;
	}
	return this;
}
group *group::Add(void)
{
	group *gr;
	
	if (gr=new group)
	{
		gr->p->allocated=1;
		if (Add(gr))
		{
			return gr;
		}
		else
		{
			delete gr;
		}
	}
	return NULL;
}

group &group::AddShadow(class group &gr)
{
	if (AddShadow(&gr)) return gr; else return *this;
}
group *group::AddShadow(class group *gr)
{
	if (gr)
	{
		p->shadowgroup=1;
		gr->p->shadowgroup=1;
		gr->p->shown=p->shown;
		gr->p->shadow=p->shadow;
		p->shadow=gr;
		gr->ParentClass(ParentClass());
		return gr;
	}
	return NULL;
}

void group::Show(void)
{
	if (p->shadowgroup)
	{
		if (!p->maped)
		{
			class group *s=p->shown;
			if (win)
			{
				XMapRaised(display(),win);
			}
			p->maped=1;
			if (s->win) XUnmapWindow(display(),s->win); 
			s->p->maped=0;
			s=this;
			do
			{
				s->p->shown=this;
				s=s->p->shadow;
			}
			while (s && s!=this);
		}
	}
}
int group::Create(void)
{
	return p->CreateAll(parent);
}

Window group::Create(Window root,int gx,int gy,int gwidth,int gheight)
{ // create groups, add to parent with given dimensions
	GSetLimits();
	p->ResizeG(gwidth,gheight);
	p->intern_Position(NULL,gx,gy);
	parent=root;
	return Create();
}
Window group::Create(Window root)
{ // create groups, add to parent with its dimensions

	XWindowAttributes xwa;
	int x,y;
	
	XGetWindowAttributes(display(),root,&xwa);
	x=xwa.width;
	y=xwa.height;
	p->windowmaster=1;

	return Create(root,0,0,x,y);
}
Window group::Create(Window root,int top,int bottom)
{ // create groups, add to parent with its dimensions

	XWindowAttributes xwa;
	int x,y;
	
	XGetWindowAttributes(display(),root,&xwa);
	x=xwa.width;
	y=xwa.height;
	p->windowmaster=1;

	return Create(root,0,top,x,y-top-bottom);
}
void group::Dimensions(Window root,int gx,int gy,int gwidth,int gheight)
{
	GSetLimits();
	p->ResizeG(gwidth,gheight);
	p->intern_Position(NULL,gx,gy);
	parent=root;
}
void group::Free(void)
{ // close group window
	p->pClose(NULL);
}

void group::Background(unsigned long c)
{
	gadget::Background(c);
}
void group::Background(char *name)
{
	Background(AllocColor(name));
}
void group::Background(unsigned short r,unsigned short g,unsigned short b)
{
	Background(AllocColor(r,g,b));
}
void group::DialogMode(void)
{
	p->requester=1;
}
void group::Center(void)
{
	p->center=1;
	p->right=0;
}
void group::Right(void)
{
	p->center=0;
	p->right=1;
}
void group::UseSmallest(void)
{
	p->smallest=1;
}
void group::SameSize(class group *gr)
{
	p->samesizegroup=1;
	p->samesize=gr;

//	if (gr)
//	{
//		p->samesizegroup=1;
//		gr->p->samesizegroup=1;
//		gr->p->samesize=p->samesize;
//		p->samesize=gr;
//		return gr;
//	}
//	return NULL;
}

void group::Resize(int gx,int gy,int nwidth,int nheight)
{
	if (x!=gx || y!=gy || width!=nwidth || height !=nheight)
	{
		width=nwidth;
		height=nheight;
		p->ResizeG(width,height);
		p->intern_Position(NULL,gx,gy);
		p->ResizeAll(NULL);
	}
}
void group::Resize(int nwidth,int nheight)
{
	if (width!=nwidth || height !=nheight)
	{
		height=nheight;
		width=nwidth; 
		p->ResizeG(width,height);
		p->intern_Position(NULL,x,y);
		p->ResizeAll(NULL);
	}
}
void group::Resize(Window root)
{
	XWindowAttributes xwa;

	XGetWindowAttributes(display(),root,&xwa);
//	if (width!=(xwa.width) || height !=(xwa.height))
	{ // Scheinbar Probleme wenn nach MakeFit() Fenster zu klein war
	  // und dann sofort Resize() aufgerufen wird...?!
		width=xwa.width;
		height=xwa.height;
		p->ResizeG(width,height);
		p->intern_Position(NULL,0,0);
		p->ResizeAll(NULL);
	}
}
void group::Resize(Window root,int top,int bottom)
{
	XWindowAttributes xwa;

	XGetWindowAttributes(display(),root,&xwa);
//	if (width!=(xwa.width) || height !=(xwa.height-top-bottom))
	{ // Scheinbar Probleme wenn nach MakeFit() Fenster zu klein war
	  // und dann sofort Resize() aufgerufen wird...?!
		width=xwa.width;
		height=xwa.height-top-bottom;
		p->ResizeG(width,height);

		p->intern_Position(NULL,0,top);
		p->ResizeAll(NULL);
	}
}
void group::Lock(void)
{
	p->Lock(NULL);
}
void group::Unlock(void)
{
	p->Unlock(NULL);
}
void group::Block(int b)
{
	p->Block(b,NULL);
}
void group::Unblock(int b)
{
	p->Unblock(b,NULL);
}
int group::AutoWeight(void)
{
	int sum=0,max=0;
	for(int i=0;i<p->aused;i++)
	{
		if (p->subs[i].group) p->subs[i].depth=p->subs[i].gp->AutoWeight(); else p->subs[i].depth=1;
		sum+=p->subs[i].depth;
		if (p->subs[i].depth>max) max=p->subs[i].depth;
	}
	for(int i=0;i<p->aused;i++)
	{
		p->subs[i].obj->Weight(100*p->subs[i].depth/sum);
	}
	return max*2;
}

// überladen
void group::BorderLimits(void)
{
	if (p->windowmaster)
	{
		borderleft=FENSTERRAHMEN;
		bordertop=FENSTERRAHMEN;
		borderright=FENSTERRAHMEN;
		borderbottom=FENSTERRAHMEN;
	}
	else
	{
		bordertop=0;
		borderleft=0;	
		borderright=0;
		borderbottom=0;
	}
}
void group::GExpose(XEvent *event)
{
}

#define BORDERADD   0

#define ABSTAND_W(x)	(x<aused-1?abstand_w:0)
#define ABSTAND_H(x)	(x<aused-1?abstand_h:0)

#define ISCENTERFLAG	(center)
#define ISRIGHTFLAG		(right)
#define ISSHADOW		(shadowgroup)
#define ISREQUESTERFLAG	(requester)
#define G_WIDTH(x)		(subs[x].obj->width+ABSTAND_W(x))
#define G_HEIGHT(x)		(subs[x].obj->height+ABSTAND_H(x))
#define MAKEREQHFLAG	req_h=1
#define ISREQHFLAG		(req_h)
#define REMREQHFLAG		req_v=0
#define MAKEREQVFLAG	req_v=1
#define ISREQVFLAG		(req_v)
#define REMREQVFLAG		req_v=0


void pgroup::plusleftf(int newWidth)
{
	if (ISCENTERFLAG)
	{
		plusleft=(newWidth-o->width)>>1;
	}
	if (ISRIGHTFLAG)
	{
		plusleft=(newWidth-o->width);
	}
}
void pgroup::plustopf(int newHeight)
{
	if (ISCENTERFLAG)
	{
		plustop=(newHeight-o->height)>>1;
	}
	if (ISRIGHTFLAG)
	{
		plustop=(newHeight-o->height);
	}
}

//	int minxaspect;	// noaspect x: 0
//	int minyaspect;	// noaspect y: 0
//	int maxxaspect;
//	int maxyaspect;

void pgroup::WAspect(class gadget *cg)
{
	if ((cg->maxxaspect*cg->height/cg->maxyaspect)<cg->width)
	{ // zu gross, Breite kleiner
		cg->width=cg->maxxaspect*cg->height/cg->maxyaspect;
	}
	if ((cg->minxaspect*cg->height/cg->minyaspect)>cg->width)
	{ // zu klein, Höhe kleiner
		cg->height=cg->minyaspect*cg->width/cg->minxaspect;
	}
}
void pgroup::HAspect(class gadget *cg)
{
	if ((cg->maxyaspect*cg->width/cg->maxxaspect)<cg->height)
	{ // zu gross, Höhe kleiner
		cg->height=cg->maxyaspect*cg->width/cg->maxxaspect;
	}
	if ((cg->minyaspect*cg->width/cg->minxaspect)>cg->height)
	{ // zu klein, Breite kleiner
		cg->width=cg->minxaspect*cg->height/cg->minyaspect;
	}
}


#define ISHORIZ				(horiz)
#define ISVERT				(!horiz)
#define ISGADGET(x)			(!subs[x].group)

#define WH_WIDTH(x)			(ISHORIZ?subs[x].obj->width+ABSTAND_W(x):subs[x].obj->height+ABSTAND_H(x))
#define WH_SET_WIDTH(x,w)	(ISHORIZ?subs[x].obj->width=w-ABSTAND_W(x):subs[x].obj->height=w-ABSTAND_H(x))
#define WH_MINWIDTH(x)		(ISHORIZ?subs[x].obj->minwidth+ABSTAND_W(x):subs[x].obj->minheight+ABSTAND_H(x))
#define WH_MAXWIDTH(x)		(ISHORIZ?subs[x].obj->maxwidth+ABSTAND_W(x):subs[x].obj->maxheight+ABSTAND_H(x))

#define WH_HEIGHT(x)		(ISHORIZ?subs[x].obj->height+ABSTAND_H(x):subs[x].obj->width+ABSTAND_W(x))
#define WH_SET_HEIGHT(x,w)	(ISHORIZ?subs[x].obj->height=w-ABSTAND_H(x):subs[x].obj->width=w-ABSTAND_W(x))
#define WH_MINHEIGHT(x)		(ISHORIZ?subs[x].obj->minheight+ABSTAND_H(x):subs[x].obj->minwidth+ABSTAND_W(x))
#define WH_MAXHEIGHT(x)		(ISHORIZ?subs[x].obj->maxheight+ABSTAND_H(x):subs[x].obj->maxwidth+ABSTAND_W(x))

#define WH_WEIGHT(x)		(subs[x].obj->weight)
#define WH_ISREQUESTERFLAG	(requester)
#define WH_ISASPECT(x)		(ISGADGET(x) && subs[x].obj->minxaspect)

#define WH_GROUPWIDTH		(ISHORIZ?(newWidth-o->borderleft-o->borderright-BORDERADD):(newHeight-o->bordertop-o->borderbottom-BORDERADD))
#define WH_GROUPHEIGHT		(ISHORIZ?(newHeight-o->bordertop-o->borderbottom-BORDERADD):(newWidth-o->borderleft-o->borderright-BORDERADD))
#define WH_w				(ISHORIZ?w:h)
#define WH_h				(ISHORIZ?h:w)

#define WH_READGROUPHEIGHT	(ISHORIZ?samesize->height:samesize->width)
#define WH_READWIDTH(x)		(ISHORIZ?samesize->p->subs[x].obj->width+ABSTAND_W(x):samesize->p->subs[x].obj->width+ABSTAND_H(x))

void pgroup::ResizeWH(class group *sgp,int newWidth,int newHeight,int flags)
{
	int nw,nh;

	if (ISSHADOW&&sgp!=o)
	{
		class group *cgp;
		int mw=0,mh=0;

		ResizeWH(o,newWidth,newHeight,flags);

		shadowwidth=o->width;
		shadowheight=o->height;
		mw=o->width;
		mh=o->height;

		cgp=shadow;
		while(cgp&&cgp!=this->o)
		{
			cgp->p->ResizeWH(cgp,newWidth,newHeight,flags);
			cgp->p->shadowheight=cgp->height;
			cgp->p->shadowwidth=cgp->width;
			if (cgp->width>mw) mw=cgp->width;
			if (cgp->height>mh) mh=cgp->height;			
			cgp=cgp->p->shadow;
		}
		
//		plusleftf(mw);
//		plustopf(mh);
		o->width=mw;
		o->height=mh;
		cgp=shadow;
		while(cgp&&cgp!=this->o)
		{
//			cgp->p->plusleftf(mw);
//			cgp->p->plustopf(mh);
			cgp->width=mw;
			cgp->height=mh;
			cgp=cgp->p->shadow;
		}
		return;
	}

	if (aused==0)
	{
		return;
    }
    
    nw=newWidth;
	if (newWidth<o->minwidth)
	{
		newWidth=o->minwidth;
    }
	nh=newHeight;
	if (newHeight<o->minheight)
	{
		newHeight=o->minheight;
    }

    if (ISSHADOW)
    {
   		if (newWidth>realmaxwidth)
		{
			newWidth=realmaxwidth;
	    }
		if (newHeight>realmaxheight)
		{
			newHeight=realmaxheight;
	    }
    }
    else
    {
   		if (newWidth>o->maxwidth)
		{
			newWidth=o->maxwidth;
        }
		if (newHeight>o->maxheight)
		{
			newHeight=o->maxheight;
        }
	}
	int w=0,h=0,ssh,ssh_old,ssm=0;		// breite, hoehe, soll-hoehe, usesmallest-hoehe
	int r=0,r_old=0,help=0,cp=0,cm=0;	// rest, terminator, zaehler zu gross/klein
	int gg_w,gg_rest,gg_w2,gg_add,fertig=0,samesizeok=0;

	if (samesize!=o)
	{ // prüfe samesize erlaubt
		if (aused!=samesize->p->aused
			|| horiz!=samesize->p->horiz
			|| right!=samesize->p->right
			|| center!=samesize->p->center
			|| abstand_w!=samesize->p->abstand_w
			|| abstand_h!=samesize->p->abstand_h
			)
		{
			samesize=o;
		}
	}

	if (samesize==o)
	{
		gg_w	=WH_GROUPWIDTH/stripes;
		gg_rest	=WH_GROUPWIDTH%stripes;
		gg_w2	=gg_rest/aused;
		gg_rest	=gg_rest%aused;
		ssh		=WH_GROUPHEIGHT;
	}
	else
	{ // SameSize
		int c=0;
		gg_w	=WH_GROUPWIDTH/stripes;
		gg_rest	=WH_GROUPWIDTH%stripes;
		gg_w2	=gg_rest/aused;
		gg_rest	=gg_rest%aused;
		ssh		=WH_READGROUPHEIGHT;

		for(int i=0;i<aused;i++)
		{
			WH_SET_WIDTH(i,WH_READWIDTH(i));
			c+=WH_WIDTH(i);
		}
		if (c>WH_GROUPWIDTH)
		{
			samesizeok=0;
			ssh=WH_GROUPHEIGHT;
		}
		else
			samesizeok=1;
	}

// (1) gg_w verteilen


	for(int i=0;i<aused;i++)
	{
		if (!samesizeok)
		{
			if (gg_rest>0)
			{
				gg_add=1;
				gg_rest--;
			}
			else
			{
				gg_add=0;
			}
			WH_SET_WIDTH(i,gg_w*WH_WEIGHT(i)+gg_w2+gg_add);
		}
		if (smallest && WH_GROUPHEIGHT>WH_MAXHEIGHT(i))
		{
			if (ssh>WH_MAXHEIGHT(i)) ssh=WH_MAXHEIGHT(i);
		}
		if (smallest && ssm<WH_MINHEIGHT(i))
		{
			ssm=WH_MINHEIGHT(i);
		}
	}

	do
	{
// (3) r auswerten und neu verteilen, nicht beim 1. Durchlauf!
		if (r!=0 && (r!=r_old) && ((r>0 && cp!=aused)||(r<0 && cm!=aused)))
		{ // hier keine Gewichtung !
			if (r>0)
			{
				gg_w	=r/(aused-cp);
				gg_rest	=r%(aused-cp);
			}
			else
			{
				gg_w	=r/(aused-cm);
				gg_rest	=r%(aused-cm);
			}
			for(int i=0;i<aused;i++)
			{
				if ((r>0 && !subs[i].zu_gross)||(r<0 && !subs[i].zu_klein))
				{
					if (gg_rest>0)
					{
						gg_add=1;
						gg_rest--;
					}
					else if(gg_rest<0)
					{
						gg_add=-1;
						gg_rest++;
					}
					else
					{
						gg_add=0;
					}
					WH_SET_WIDTH(i,WH_WIDTH(i)+gg_w+gg_add);
				}
			}
		}
		else
		{
			if (help>1) fertig=1;
		}

// (2) Kontrolle, Höhe setzen
		r_old=r; help++;
		if (ssh<ssm) ssh=ssm;
		ssh_old=ssh;
		cp=0; cm=0; r=0;
		for(int i=0;i<aused;i++)
		{	// Flags löschen
			subs[i].zu_gross=0;
			subs[i].zu_klein=0;

			// Höhe setzen
			WH_SET_HEIGHT(i,ssh);
			if (WH_HEIGHT(i)>WH_MAXHEIGHT(i))
			{
				WH_SET_HEIGHT(i,WH_MAXHEIGHT(i));
			}
			if (WH_HEIGHT(i)<WH_MINHEIGHT(i))
			{
				WH_SET_HEIGHT(i,WH_MINHEIGHT(i));
			}

			if (ISREQUESTERFLAG)
			{
//				WH_SET_WIDTH(i,WH_MINWIDTH(i));
				if (ISHORIZ) MAKEREQHFLAG; else MAKEREQVFLAG;
			}

			// Kontrolle der Breite
			if (WH_WIDTH(i)>WH_MAXWIDTH(i))
			{
				r+=WH_WIDTH(i)-WH_MAXWIDTH(i);
				WH_SET_WIDTH(i,WH_MAXWIDTH(i));
				subs[i].zu_gross=1;
				cp++;
			}
			else if(WH_WIDTH(i)<WH_MINWIDTH(i))
			{
				r-=WH_MINWIDTH(i)-WH_WIDTH(i);
				WH_SET_WIDTH(i,WH_MINWIDTH(i));
				subs[i].zu_klein=1;
				cm++;
			}
			if (WH_ISASPECT(i))
			{
				int ow=WH_WIDTH(i);
				if (ISHORIZ)
				{
           	    	WAspect(subs[i].gg);
				}
				else
				{
           	    	HAspect(subs[i].gg);
				}
				if (WH_WIDTH(i)>ow)
				{
					r-=WH_WIDTH(i)-ow;
				}					
				else if (WH_WIDTH(i)<ow)
				{
					r+=ow-WH_WIDTH(i);
				}
				if (smallest && WH_HEIGHT(i)<ssh)
				{
					ssh=WH_HEIGHT(i);
					if (ssh<ssm) ssh=ssm;
				}
			}

			if (!ISGADGET(i))
			{ // Gruppe aufrufen
				int ow=WH_WIDTH(i);
				subs[i].gp->p->ResizeWH(sgp,G_WIDTH(i)-ABSTAND_W(i),G_HEIGHT(i)-ABSTAND_H(i),ISHORIZ?USEHEIGHT:USEWIDTH);
				if (WH_WIDTH(i)>ow)
				{
					r-=WH_WIDTH(i)-ow;
					if (!subs[i].zu_klein)
					{
						subs[i].zu_klein=1;
						cm++;
					}
				}					
				else if (WH_WIDTH(i)<ow)
				{
					r+=ow-WH_WIDTH(i);
					if (!subs[i].zu_gross)
					{
						subs[i].zu_gross=1;
						cp++;
					}
				}					
			}
		}
	}
	while ((!fertig || ssh!=ssh_old) && help<100);
	if (help>96)
	{
		warn_printf("Group calculation looping error - giving up",o);
	}

	for(int i=0;i<aused;i++)
	{
		if (WH_HEIGHT(i)>h)
		{
		   	h=WH_HEIGHT(i);
       	}
		w+=WH_WIDTH(i);
	}

	if (ISHORIZ)
	{
		w+=o->borderleft+o->borderright+BORDERADD;
		if (ISREQHFLAG) w=nw;
		o->width=w;
		h+=o->bordertop+o->borderbottom+BORDERADD;
		o->height=h;
	}
	else
	{
		h+=o->borderleft+o->borderright+BORDERADD;
		if (ISREQVFLAG) w=nh;
		o->width=h;
		w+=o->bordertop+o->borderbottom+BORDERADD;
		o->height=w;
	}
//	plustopf(nh);
//	plusleftf(nw);
}

void pgroup::reset(class group *sgr)
{
	if (ISSHADOW&&sgr!=this->o)
	{
		class group *cgp;

		cgp=shadow;
		while(cgp&&cgp!=this->o)
		{
			cgp->p->reset(cgp);
			cgp=cgp->p->shadow;
		}
	}

	REMREQHFLAG;
	REMREQVFLAG;

	plusleft=0;
	plustop =0;

	for(int i=0;i<aused;i++)
	{
		if (!ISGADGET(i))
		{
			subs[i].gp->p->reset(sgr);
	    }
	}
}

void pgroup::ResizeG(int newWidth,int newHeight)
{
	reset(NULL);
	ResizeWH(NULL,newWidth,newHeight);
}
void pgroup::zurueck(void)
{
	int w=ISHORIZ?o->width-o->borderright:o->height-o->borderbottom;

	for (int i=aused-1;i>=0;i--)
	{
		if (ISHORIZ)
		{
			if (subs[i].obj->x+G_WIDTH(i)>w)
			{
				subs[i].obj->x=w-(G_WIDTH(i));
			}
			w=subs[i].obj->x;
		}
		else
		{
			if (subs[i].obj->y+G_HEIGHT(i)>w)
			{
				subs[i].obj->y=w-(G_HEIGHT(i));
			}
			w=subs[i].obj->y;
		}
	}
}
void pgroup::plusleft_GG(int i)
{
	if (ISCENTERFLAG)
	{
		subs[i].obj->x+=(o->width-o->borderleft-o->borderright-BORDERADD-subs[i].obj->width)>>1;
	}
	if (ISRIGHTFLAG)
	{
		subs[i].obj->x+=(o->width-o->borderleft-o->borderright-BORDERADD-subs[i].obj->width);
	}
}
void pgroup::plustop_GG(int i)
{
	if (ISCENTERFLAG)
	{
		subs[i].obj->y+=(o->height-o->bordertop-o->borderbottom-BORDERADD-subs[i].obj->height)>>1;
	}
	if (ISRIGHTFLAG)
	{
		subs[i].obj->y+=(o->height-o->bordertop-o->borderbottom-BORDERADD-subs[i].obj->height);
	}
}
void pgroup::intern_Position(class group *sgp,int gx,int gy)
{
	if (ISSHADOW&&sgp!=this->o)
	{
		class group *cgp;

		intern_Position(o,gx,gy);
		cgp=shadow;
		while(cgp&&cgp!=this->o)
		{
			cgp->p->intern_Position(cgp,gx,gy);
			cgp=cgp->p->shadow;
		}
		return;
	}
	o->y=gy;
	o->x=gx;
	gx=o->borderleft+plusleft;
	gy=o->bordertop+plustop;
	if (ISSHADOW)
	{ // Sonderbehandlung zum zentrieren
		if (!ISVERT || (!ISRIGHTFLAG && !ISCENTERFLAG))
			gx+=(o->width-shadowwidth)/2;
		if (!ISHORIZ || (!ISRIGHTFLAG && !ISCENTERFLAG))
			gy+=(o->height-shadowheight)/2;
	}

	class gadget *gh;
	int i=0,l=0,ox=0;

	if (ISREQHFLAG || ISREQVFLAG)
	{
		ox=ISHORIZ?gx:gy;

		if (ISHORIZ)
			l=(o->width-o->borderleft-o->borderright)/aused;
		else
			l=(o->height-o->bordertop-o->borderbottom)/aused;
		if (aused==1)
		{
			if (ISHORIZ)
				gx=ox+((l-subs[0].obj->width)>>1);
			else
				gy=ox+((l-subs[0].obj->height)>>1);
		}
	} // Requester-Mode

	for(i=0;i<aused;i++)
	{
		if (ISGADGET(i))
		{
	        gh=subs[i].gg;

			gh->y=gy;
			gh->x=gx;
			if (ISVERT)
			{
				plusleft_GG(i);
				if (ISREQVFLAG)
				{
                    int zw;
   	                zw=gy;

					if ((i+1)<aused)
					{
						gy=ox+(i+1)*l+((l-G_HEIGHT(i+1))>>1);
	                    if (gy<zw+G_HEIGHT(i))
    	                {
        	            	gy=zw+G_HEIGHT(i);
            	        }
					}
					else
					{
                        if (i==aused-1 && aused>1)
                        {
                        	gh->y=o->height-o->borderbottom-G_HEIGHT(i);
							if (gh->y<gy)
							{
								gy=o->height+1;	/* Hauptsache grösser */
							}
						}
					}
				} // Requester-Mode
				else
				{
					gy+=G_HEIGHT(i);
				}
            }
            else
            {
				plustop_GG(i);
				if (ISREQHFLAG)
				{
                    int zw;
   	                zw=gx;

					if ((i+1)<aused)
					{
						gx=ox+(i+1)*l+((l-G_WIDTH(i+1))>>1);
	                    if (gx<zw+G_WIDTH(i))
    	                {
        	            	gx=zw+G_WIDTH(i);
            	        }
					}
					else
					{
                        if (i==aused-1 && aused>1)
                        {
                        	gh->x=o->width-o->borderright-G_WIDTH(i);
							if (gh->x<gx)
							{
								gx=o->width+1;	/* Hauptsache grösser */
							}
						}
					}
				} // Requester-Mode
				else
				{
					gx+=G_WIDTH(i);
                }
            }
//			gh->before_x=o->before_x;
		}
		else
		{
//			if (o->before_x>0) subs[i].gp->before_x=o->before_x;
			subs[i].gp->p->intern_Position(NULL,gx,gy);
			if (ISVERT)
			{
				plusleft_GG(i);
				if (ISREQVFLAG)
				{
                    int zw;
   	                zw=gy;

					if ((i+1)<aused)
					{
						gy=ox+(i+1)*l+((l-G_HEIGHT(i+1)-subs[i+1].gp->p->plustop*2)>>1);
	                    if (gy<zw+G_HEIGHT(i))
    	                {
        	            	gy=zw+G_HEIGHT(i);
            	        }
					}
					else
					{
                        if (i==aused-1 && aused>1) 
                        {
                        	subs[i].gp->y=o->height-o->borderbottom-G_HEIGHT(i);
                        	gy+=G_HEIGHT(i);
						}
					}
				} // Requester-Mode
				else
				{
					gy+=G_HEIGHT(i)+subs[i].gp->p->plustop*2;
				}
            }
	        else
    	    {
				plustop_GG(i);
				if (ISREQHFLAG)
				{
                    int zw;
   	                zw=gx;

					if ((i+1)<aused)
					{
						gx=ox+(i+1)*l+((l-G_WIDTH(i+1)-subs[i+1].gp->p->plusleft*2)>>1);
	                    if (gx<zw+G_WIDTH(i))
    	                {
        	            	gx=zw+G_WIDTH(i);
            	        }
					}
					else
					{
                        if (i==aused-1 && aused>1) 
                        {
                        	subs[i].gp->x=o->width-o->borderright-G_WIDTH(i);
                        	gx+=G_WIDTH(i);
						}
					}
				} // Requester-Mode
				else
				{
					gx+=G_WIDTH(i)+subs[i].gp->p->plusleft*2;
				}
			}
		}
		if ((ISREQHFLAG && gx>o->width-o->borderright)
		  ||(ISREQVFLAG && gy>o->height-o->borderbottom))
		{
			zurueck();
		} // Requester-Mode
	}
}

void pgroup::intern_SetBeforeX(class group *sgp)
{
	if (before_x_done) return;
	if (ISSHADOW&&(sgp!=o))
	{
		class group *cgp;

		intern_SetBeforeX(o);
		cgp=shadow;
		while(cgp&&cgp!=o)
		{
			cgp->p->intern_SetBeforeX(cgp);
			cgp=cgp->p->shadow;
		}
		return;
	}
	before_x_done=1;
	int befw=0,befcount=0;

	for(int i=0;i<aused;i++)
	{
		if (ISGADGET(i))
		{
			subs[i].obj->before_x=0;
			subs[i].obj->GSetLimits();
			if (subs[i].gg->before_x>0) befcount+=2;
			befw=(subs[i].gg->before_x>befw)?(subs[i].gg->before_x):(befw);
		}
		else
		{
			subs[i].gp->GSetLimits(); // neu, testen!!!!!!
			subs[i].gp->p->intern_SetBeforeX(NULL);
			if (ISVERT && subs[i].gp->before_x>0) befcount++;
			befw=(subs[i].gp->before_x>befw)?(subs[i].gp->before_x):(befw);
		}
	}
	if (befcount>1) o->before_x=befw;
}

void pgroup::intern_SetLimits(class group *sgp)
{
	unsigned int maxw=0,maxh=0,minw=0,minh=0;
	int sm_w=0,sm_h=0,req_minw=0;

	if (ISSHADOW&&(sgp!=o))
	{
		class group *cgp;

		intern_SetLimits(o);
		maxw=o->maxwidth;
		maxh=o->maxheight;
		minw=o->minwidth;
		minh=o->minheight;
		realmaxwidth =o->maxwidth;
		realmaxheight=o->maxheight;
		cgp=shadow;
		while(cgp&&cgp!=o)
		{
			cgp->p->intern_SetLimits(cgp);
			maxw=((maxw!=NO_LIMIT && cgp->maxwidth>maxw) || cgp->maxwidth==NO_LIMIT) ?(cgp->maxwidth):(maxw);
			maxh=((maxh!=NO_LIMIT && cgp->maxheight>maxh)|| cgp->maxheight==NO_LIMIT)?(cgp->maxheight):(maxh);
			minw=(cgp->minwidth>minw) ?(cgp->minwidth):(minw);
			minh=(cgp->minheight>minh)?(cgp->minheight):(minh);
			cgp->p->realmaxwidth =cgp->maxwidth;
			cgp->p->realmaxheight=cgp->maxheight;
			cgp=cgp->p->shadow;
		}
		o->maxwidth =maxw;
		o->maxheight=maxh;
		o->minwidth =minw;
		o->minheight=minh;
		cgp=shadow;

		while(cgp&&cgp!=o)
		{
			cgp->maxwidth	=maxw;
			cgp->maxheight	=maxh;
			cgp->minwidth	=minw;
			cgp->minheight	=minh;
			cgp=cgp->p->shadow;
		}
		return;
	}
	o->BorderLimits();
	stripes=0;

	for(int i=0;i<aused;i++)
	{
		stripes+=subs[i].obj->weight;
		if (!ISGADGET(i)) subs[i].obj->GSetLimits();

		if (ISREQUESTERFLAG)
		{
			subs[i].obj->minwidth+=8;
			if (subs[i].obj->minwidth>subs[i].obj->maxwidth) subs[i].obj->minwidth=subs[i].obj->maxwidth;
			if (subs[i].obj->minwidth>req_minw) req_minw=subs[i].obj->minwidth;
		}
#ifdef USEMINWIDTH
		if (subs[i].obj->useminwidth())
		{
			subs[i].obj->maxwidth=subs[i].obj->minwidth;
		}
		if (subs[i].obj->useminheight())
		{
			subs[i].obj->maxheight=subs[i].obj->minheight;
		}
#endif

		if (ISGADGET(i))
		{
			class gadget *gh;
			gh=subs[i].gg;
			if (gh->before_x)
			{
				gh->minwidth+=o->before_x-gh->before_x;
				if (gh->maxwidth!=NO_LIMIT) gh->maxwidth+=o->before_x-gh->before_x;
	            gh->before_x=o->before_x;
			}
			if (gh->minxaspect)
			{
				if ((gh->minxaspect*gh->minheight/gh->minyaspect)<gh->minwidth)
				{
					gh->minwidth=gh->minxaspect*gh->minheight/gh->minyaspect;
				}
				else
				{
					gh->minheight=gh->minyaspect*gh->minwidth/gh->minxaspect;
				}
				if (gh->maxwidth!=NO_LIMIT && gh->maxheight!=NO_LIMIT)
				{
					if (gh->maxheight!=NO_LIMIT && (gh->maxxaspect*gh->maxheight/gh->maxyaspect)<gh->maxwidth)
					{
						gh->maxwidth=gh->maxxaspect*gh->maxheight/gh->maxyaspect;
					}
					else
					{
						gh->maxheight=gh->maxyaspect*gh->maxwidth/gh->maxxaspect;
					}
				}
			}
			
			if (ISHORIZ)
			{
				if (maxw==NO_LIMIT||gh->maxwidth==NO_LIMIT||ISREQUESTERFLAG)
				{
					maxw=NO_LIMIT;
                }
                else
                {
					maxw+=gh->maxwidth+ABSTAND_W(i);
                }
				minw+=gh->minwidth+ABSTAND_W(i);
				if (smallest)
				{
					if (gh->maxheight!=NO_LIMIT)
						maxh=((gh->maxheight+ABSTAND_H(i))<maxh)?(gh->maxheight+ABSTAND_H(i)):(maxh);
					else
						sm_h++;
				}
				else
				{
					if (gh->maxheight!=NO_LIMIT)
						maxh=((gh->maxheight+ABSTAND_H(i))>maxh)?(gh->maxheight+ABSTAND_H(i)):(maxh);
					else
						maxh=NO_LIMIT;
				}
				minh=((gh->minheight+ABSTAND_H(i))>minh)?(gh->minheight+ABSTAND_H(i)):(minh);

				if (ISREQUESTERFLAG)
				{
					maxh=minh+6;
				} // Requester-Mode
			}
			else
			{
				if (maxh==NO_LIMIT||gh->maxheight==NO_LIMIT||ISREQUESTERFLAG)
				{
					maxh=NO_LIMIT;
                }
                else
                {
					maxh+=gh->maxheight+ABSTAND_H(i);
                }
				minh+=gh->minheight+ABSTAND_H(i);
				if (smallest)
				{
					if (gh->maxwidth!=NO_LIMIT)
						maxw=((gh->maxwidth+ABSTAND_W(i))<maxw)?(gh->maxwidth+ABSTAND_W(i)):(maxw);
					else
						sm_w++;
				}
				else
				{
					if (gh->maxwidth!=NO_LIMIT)
						maxw=((gh->maxwidth+ABSTAND_W(i))>maxw)?(gh->maxwidth+ABSTAND_W(i)):(maxw);
					else
						maxw=NO_LIMIT;
				}
				minw=((gh->minwidth+ABSTAND_W(i))>minw)?(gh->minwidth+ABSTAND_W(i)):(minw);
			}
		}
		else
		{
			if (ISHORIZ)
			{
				if (maxw==NO_LIMIT || subs[i].gp->maxwidth==NO_LIMIT)
				{
					maxw=NO_LIMIT;
                }
                else
                {
					maxw+=subs[i].gp->maxwidth+ABSTAND_W(i);
                }
				minw+=subs[i].gp->minwidth+ABSTAND_W(i);
				if (smallest)
				{
					if (subs[i].gp->maxheight!=NO_LIMIT)
						maxh=(subs[i].gp->maxheight+ABSTAND_H(i)<maxh)?(subs[i].gp->maxheight+ABSTAND_H(i)):(maxh);
					else
						sm_h++;
				}
				else
				{
					if (subs[i].gp->maxheight!=NO_LIMIT)
						maxh=(subs[i].gp->maxheight+ABSTAND_H(i)>maxh)?(subs[i].gp->maxheight+ABSTAND_H(i)):(maxh);
					else
						maxh=NO_LIMIT;
				}
				minh=(subs[i].gp->minheight+ABSTAND_H(i)>minh)?(subs[i].gp->minheight+ABSTAND_H(i)):(minh);

				if (ISREQUESTERFLAG)
				{
					maxh=minh+6;
				} // Requester-Mode - hier für Gruppen kopieren
			}
			else
			{
				if (maxh==NO_LIMIT||subs[i].gp->maxheight==NO_LIMIT)
				{
					maxh=NO_LIMIT;
                }
                else
                {
					maxh+=subs[i].gp->maxheight+ABSTAND_H(i);
                }
				minh+=subs[i].gp->minheight+ABSTAND_H(i);
				if (smallest)
				{
					if (subs[i].gp->maxwidth!=NO_LIMIT)
						maxw=(subs[i].gp->maxwidth+ABSTAND_W(i)<maxw)?(subs[i].gp->maxwidth+ABSTAND_W(i)):(maxw);
					else
						sm_w++;
				}
				else
				{
					if (subs[i].gp->maxwidth!=NO_LIMIT)
						maxw=(subs[i].gp->maxwidth+ABSTAND_W(i)>maxw)?(subs[i].gp->maxwidth+ABSTAND_W(i)):(maxw);
					else
						maxw=NO_LIMIT;
				}
				minw=(subs[i].gp->minwidth+ABSTAND_W(i)>minw)?(subs[i].gp->minwidth+ABSTAND_W(i)):(minw);
			}
            if (o->before_x>0) subs[i].gp->before_x=o->before_x;
		}
	}
	o->minwidth	=minw+o->borderleft+o->borderright+BORDERADD;
	o->minheight=minh+o->bordertop+o->borderbottom+BORDERADD;

	if (smallest)
	{
		if (ISHORIZ)
		{
			if (sm_h==aused) maxh=NO_LIMIT;
		}
		else
		{
			if (sm_w==aused) maxw=NO_LIMIT;
		}
	}
	if (ISVERT && ISREQUESTERFLAG) maxw=req_minw;

	if (maxw<minw) maxw=minw;
	if (maxh<minh) maxh=minh;

	if (maxw==NO_LIMIT || maxw==0)
	{
		o->maxwidth=NO_LIMIT;
	}
	else
	{
		o->maxwidth=maxw+o->borderleft+o->borderright+BORDERADD;
	}
	if (maxh==NO_LIMIT || maxh==0)
	{
		o->maxheight=NO_LIMIT;
	}
	else
	{
		o->maxheight=maxh+o->bordertop+o->borderbottom+BORDERADD;
	}

	if (ISREQUESTERFLAG)
	{
		for(int i=0;i<aused;i++)
		{
			if (req_minw>=subs[i].obj->minwidth && req_minw<=subs[i].obj->maxwidth)
			{
				subs[i].obj->maxwidth=req_minw;
				if (subs[i].obj->maxwidth<subs[i].obj->minwidth) subs[i].obj->maxwidth=subs[i].obj->minwidth;
			}
		}
	}
}
void group::GSetLimits(void)
{
	if (!setlimit)
	{
		char *r=GetResource("direction");
		if (r)
		{
			if (!strcmp(r,"Horiz")) Horiz();
			if (!strcmp(r,"Vert")) Vert();
		}
		if (!p->before_x_done) p->intern_SetBeforeX(NULL);
		p->intern_SetLimits(NULL);

		if (minwidth<5)
		{
			minwidth=5;
		}
		if (minheight<5)
		{
			minheight=5;
		}

		width=minwidth;
		height=minheight;
		setlimit=1;
	}
}

void pgroup::ResizeAll(class group *sgp)
{
	if (!o->win) return;

	if (ISSHADOW&&(sgp!=o))
	{
		class group *cgp;

		ResizeAll(o);
		cgp=shadow;
		while(cgp&&cgp!=o)
		{
			cgp->p->ResizeAll(cgp);
			cgp=cgp->p->shadow;
		}
		return;
	}

	o->gadget::Move(o->x,o->y);
	o->gadget::Resize(o->width,o->height); XSPEC;
	XFlush(o->display());

	int i;
	for(int j=aused-1;j>=0;j--)
//	for(int j=0;j<aused;j++)
	{
//		if (hasgps)
//		{
			i=j;
//		}
//		else
//		{
//			if (j&1) i=aused-1-j+((aused-1)&1); else i=j;
//		}
		if (ISGADGET(i))
		{
			if (subs[i].gg->win)
			{
				subs[i].gg->Move(subs[i].gg->x,subs[i].gg->y);
				subs[i].gg->Resize(subs[i].gg->width,subs[i].gg->height); XSPEC;
			}
		}
		else
		{
			subs[i].gp->p->ResizeAll(NULL);
		}
	}

	char *res=o->GetResource("disableexpose");
	if (!res || strcasecmp(res,"TRUE"))
	{
		XEvent myevent;

		i=-aused;
		XSync(o->display(),0); 

		while (i<=aused && XCheckMaskEvent(o->display(),ExposureMask,&myevent))
		{
			if (o->HandleEvent(&myevent)!=-1)
			{
				XPutBackEvent(o->display(),&myevent);
			}
			i++;
		}
	}
}
Window pgroup::CreateAll(Window gparent)
{
	// Window anlegen

	if (o->width==0)
	{
		fatal_printf("Internal error, group width was calculated to zero!!\nTerminating",o);
		exit(10);
	}
	if (o->height==0)
	{
		fatal_printf("Internal error, group height was calculated to zero!!\nTerminating",o);
		exit(10);
	}
	if (ISSHADOW)
	{
		if (o->ParentClass() && !shadow->ParentClass()) shadow->ParentClass(o->ParentClass());
		if (shadow->ParentClass() && !o->ParentClass()) o->ParentClass(shadow->ParentClass());
	}

	o->parent=gparent;
	o->Background(o->col_background());
	if (o->gadget::Create())
	{
		o->Mode(GM_ONEEXPOSE);
		// Window unsichtbar machen
		if (ISSHADOW && shown!=o)
		{
			XUnmapWindow(o->display(),o->win); 
			maped=0;
		}
		else
		{
			maped=1;
		} XSPEC;
		for(int i=0;i<aused;i++)
		{
			if (ISGADGET(i))
			{
				// Gadgets erzeugen
				subs[i].gg->parent=o->win;
				if (subs[i].gg->width==0)
				{
					fatal_printf("Internal error, gadget width of was calculated to zero!!\nTerminating",subs[i].gg);
					subs[i].gg->width=1;
					exit(10);
				}
				if (subs[i].gg->height==0)
				{
					fatal_printf("Internal error, gadget height was calculated to zero!!\nTerminating",subs[i].gg);
					subs[i].gg->height=1;
					exit(10);
				}
				if (!subs[i].gg->Create()) warn_printf("Can't create gadget\n",subs[i].gg);
				XSPEC;
			}
			else
			{
				subs[i].gp->parent=o->win;
				subs[i].gp->Create();
			}
		}
	} 
	else
	{
		warn_printf("Can't create group window\n",o);
	}

//	XFlush(o->display());

	if (ISSHADOW)
	{
		if (!shadow->win)
		{
			shadow->parent=o->parent;
			if (!shadow->Create()) warn_printf("Can't create shadow group",shadow);
		}
	}
	return o->win;
}
void pgroup::pClose(class group *sgp)
{ // close group window

	if (ISSHADOW&&(sgp!=o))
	{
		class group *cgp;

		pClose(o);
		cgp=shadow;
		while(cgp&&cgp!=o)
		{
			cgp->p->pClose(cgp);
			cgp=cgp->p->shadow;
		}
		return;
	}
	before_x_done=0;
	o->before_x=0;
	if (aused>0)
	{
		for (int i=0;i<aused;i++)
		{
			if (ISGADGET(i))
			{
				if (subs[i].gg) subs[i].gg->Free(); // slow
			}
			else
			{
				if (subs[i].gp) subs[i].gp->Free();
				if (group_free_clear && subs[i].gp->p->allocated)
				{
					delete subs[i].gp;
				}
			}
			if (group_free_clear) subs[i].obj=NULL;
		}
		if (group_free_clear) aused=0;
	}
	if (o->win)
	{
		o->gadget::Free();
		maped=0;
	}
}
void pgroup::Lock(class group *sgp)
{

	if (ISSHADOW&&(sgp!=o))
	{
		class group *cgp;

		Lock(o);
		cgp=shadow;
		while(cgp&&cgp!=o)
		{
			cgp->p->Lock(cgp);
			cgp=cgp->p->shadow;
		}
		return;
	}
	if (aused>0)
	{
		for (int i=0;i<aused;i++)
		{
			subs[i].gg->Lock();
		}
	}
	o->gadget::Lock();
}
void pgroup::Unlock(class group *sgp)
{

	if (ISSHADOW&&(sgp!=o))
	{
		class group *cgp;

		Unlock(o);
		cgp=shadow;
		while(cgp&&cgp!=o)
		{
			cgp->p->Unlock(cgp);
			cgp=cgp->p->shadow;
		}
		return;
	}
	if (aused>0)
	{
		for (int i=0;i<aused;i++)
		{
			subs[i].gg->Unlock();
		}
	}
	o->gadget::Unlock();
}
void pgroup::Block(int b,class group *sgp)
{

	if (ISSHADOW&&(sgp!=o))
	{
		class group *cgp;

		Block(b,o);
		cgp=shadow;
		while(cgp&&cgp!=o)
		{
			cgp->p->Block(b,cgp);
			cgp=cgp->p->shadow;
		}
		return;
	}
	if (aused>0)
	{
		for (int i=0;i<aused;i++)
		{
			subs[i].gg->Block(b);
		}
	}
	o->gadget::Block(b);
}
void pgroup::Unblock(int b,class group *sgp)
{

	if (ISSHADOW&&(sgp!=o))
	{
		class group *cgp;

		Unblock(b,o);
		cgp=shadow;
		while(cgp&&cgp!=o)
		{
			cgp->p->Unblock(b,cgp);
			cgp=cgp->p->shadow;
		}
		return;
	}
	if (aused>0)
	{
		for (int i=0;i<aused;i++)
		{
			subs[i].gg->Unblock(b);
		}
	}
	o->gadget::Unblock(b);
}

int group::minWidth(void)
{
	return minwidth;
}
int group::maxWidth(void)
{
	return maxwidth;
}
int group::minHeight(void)
{
	return minheight;
}
int group::maxHeight(void)
{
	return maxheight;
}

void group::Horiz(void)
{
	p->horiz=1;
}
void group::Vert(void)
{
	p->horiz=0;
}
void group::XDistance(int d)
{
	p->abstand_w=d;
}
void group::YDistance(int d)
{
	p->abstand_h=d;
}
int group::Direction(void)
{	// 0: Vert, 1: Horiz
	return p->horiz?1:0;
}
#endif
