#ifndef CODE_LISTGROUP_CXX
#define CODE_LISTGROUP_CXX

/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: listgroup.cxx,v 1.2 2003/02/19 20:59:28 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 "types.h"
#include <Xclasses/gadget.h>
#include <Xclasses/group.h>
#include <Xclasses/listgroup.h>
#include "include/listgroup_p.h"

#define BLOCK 10

listgroup::listgroup() : gadget()
{
	while (!(p=new plistgroup))
	{
		outOfMemory("listgroup");
	}
	p->o=this;
	Name("listgroup");
	p->list.Name("groupslist");
	p->list.ParentClass(this);
}
plistgroup::plistgroup() : list()
{
	anzahl=0;
	groesse=0;
	selected=0;
	sel=0;
	alllists=NULL;
	listwidth=100;
}
plistgroup::~plistgroup()
{
}
listgroup::~listgroup()
{
	if (win) Free();
	if (p) delete p;
}

void listgroup::Add(char *n,group *gp)
{
	p->anzahl++;
	if (p->anzahl>p->groesse)
	{
		struct lists *c;
		if (c=new lists[p->groesse+BLOCK])
		{
			for(int i=0;i<(p->anzahl-1);i++)
			{
				c[i]=p->alllists[i];
			}
			if (p->alllists) delete p->alllists;
			p->alllists=c;
			p->groesse+=BLOCK;
		}
		else
		{
			p->anzahl--;
			return;
		}
	}
	gp->ParentClass(this);
	p->alllists[p->anzahl-1].gp=gp;
	p->alllists[p->anzahl-1].name.Text(n);
	p->list.AddAtEnd(n);
	if (p->anzahl>1)
	{
		p->alllists[0].gp->AddShadow(gp);
	}
}

void listgroup::Selected(int s)
{
	p->selected=s;
	if (p->selected>=p->anzahl) p->selected=p->anzahl-1;
	if (p->selected<0) p->selected=0;
	p->sel=p->selected;
	if (p->alllists)
		p->alllists[p->selected].gp->Show();
	p->list.Selected(p->selected+1);
}
int listgroup::Selected(void)
{
	return p->selected;
}
void listgroup::Free(void)
{
	p->list.Free();
	if (p->anzahl>0) p->alllists[0].gp->Free();
	gadget::Free();
	if (p->alllists)
	{
		delete [] p->alllists;
		p->alllists=NULL;
		p->groesse=0;
		p->anzahl=0;
	}
	p->list.RemoveAll();
}

int listgroup::Create(void)
{
	Background(col_background());
	if (p->selected>=p->anzahl) p->selected=p->anzahl-1;
	if (p->selected<0) p->selected=0;
	p->sel=p->selected;

	char *r=GetResource("selected");
	if (r)
	{
		Selected(atoi(r));
	}

	if (!setlimit) GSetLimits();	
    if (gadget::Create())
    {
		p->list.Dimensions(win,0,0,p->listwidth,height);
		p->list.CopyFont(this);
		p->list.ShowSelected();
		if (p->list.Create())
		{
			p->list.SendEventTo(this);
			p->list.Selected(p->selected+1);
			if (p->alllists)
    	    {
	        	p->alllists[0].gp->Create(win,p->listwidth,0,width-p->listwidth,height);
			}
			return 1;
		}
		else
			gadget::Free();
    } 
    return 0;
}
void listgroup::Resize(int w,int h)
{
	gadget::Resize(w,h);
	if (p->alllists)
	{
		p->alllists[0].gp->Move(p->listwidth,0);
		p->alllists[0].gp->Resize(w-p->listwidth,h);
	}
	p->list.Resize(p->listwidth,h);
}

void listgroup::Lock(void)
{
	gadget::Lock();
	p->list.Lock();
}
void listgroup::Unlock(void)
{
	gadget::Unlock();
	p->list.Unlock();
}
void listgroup::Block(int b)
{
	gadget::Block(b);
	p->list.Block(b);
	if (p->alllists)
		p->alllists[0].gp->Block(b);
}
void listgroup::Unblock(int b)
{
	if (p->alllists)
		p->alllists[0].gp->Unblock(b);
	p->list.Unblock(b);
	gadget::Unblock(b);
}

int listgroup::GSelected(XEvent *event,int why,int wasabove)
{
	int r=0;
	if (wasfor) r=wasfor->GSelected(event,why,wasabove);

	if (r & GSR_SELECTION && wasfor==&p->list)
	{
		Selected(p->list.Selected()-1);
	}
	return r;
}
void listgroup::GSetLimits(void)
{
	int mw=0;
	p->listwidth=100;
	minheight=0;
	minwidth=0;

	if (p->alllists)
	{
		p->alllists[0].gp->GSetLimits();
		minheight=p->alllists[0].gp->gg_minheight();
		maxheight=p->alllists[0].gp->gg_maxheight();
		minwidth =p->alllists[0].gp->gg_minwidth();
		maxwidth =p->alllists[0].gp->gg_maxwidth();
	}
	for (int i=0;i<p->anzahl;i++)
	{
		if (p->alllists[i].name.width(&p->list)>mw) mw=p->alllists[i].name.width(&p->list);
	}
	p->list.GSetLimits();
	p->listwidth=p->list.gg_minwidth()+mw;
	minwidth+=p->list.gg_minwidth()+mw;
	if (minheight<p->list.gg_minheight()) minheight=p->list.gg_minheight();

	if (minwidth>maxwidth) maxwidth=minwidth;
	if (minheight>maxheight) maxheight=minheight;
	setlimit=1;
}

#endif
