#ifndef CODE_MXGADGET_CXX
#define CODE_MXGADGET_CXX

/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: mxgadget.cxx,v 1.2 1998/07/31 06:35:12 beckerr 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/mxgadget.h>
#include <Xclasses/selgadget.h>
#include "include/mxgadget_p.h"

mxgadget::mxgadget(): gadget(), Ddraw(this)
{
	while (!(p=new pmxgadget))
	{
		outOfMemory("mxgadget");
	}
	p->o=this;
	Name("mxgadget");
	p->grp.ParentClass(this);
	BorderSize(0);
	KeyBorder();
}
pmxgadget::pmxgadget(): grp()
{
	anzahl=0; selected=0; key=0; zselected=0;
	manageonly=0;
	grp.Vert();
	buts=NULL;
}
pmxgadget::~pmxgadget()
{
	if (buts) delete buts;
}
mxgadget::~mxgadget()
{
	if (win) Free();
	if (p) delete p;
}
void mxgadget::Items(selgadget **ggs)
{
	if (p->buts) delete p->buts;
	p->buts=NULL;
	p->anzahl=0;
	while (ggs[p->anzahl])    
	{
		p->anzahl++;
	}

	if (p->buts=new selgadget*[p->anzahl])
	{
		for(int i=0;i<p->anzahl;i++)
		{
			p->buts[i]=ggs[i];
			p->buts[i]->SendEventTo(this);
			p->buts[i]->ID(i);
			if (i==p->selected) p->buts[i]->State(PRESSED); else p->buts[i]->State(RELEASED);
			if (!p->manageonly)
				p->grp.Add(p->buts[i]);
		}
	}
//	if (!p->manageonly)
//		p->grp.GSetLimits();
}
void mxgadget::Horiz(void)
{
	p->grp.Horiz();
//	if (p->anzahl>0 && !p->manageonly)
//		p->grp.GSetLimits();
}
void mxgadget::ManageOnly(void)
{
	p->manageonly=1;
}
void mxgadget::Free(void)
{
	if (p->anzahl>0)
	{
		if (!p->manageonly)
			p->grp.Free();
		p->anzahl=0;
	}
	gadget::Free();
}
int mxgadget::Create(void)
{ 
	Background(col_background());
	p->grp.Background(col_background());

	char *r;
	if (r=GetResource("selected"))
	{
		int s=atoi(r);
		if (s>=0 && s<p->anzahl) Selected(s);
	}
		
	if (gadget::Create())
    {
    	Mode(GM_KEY);
//    	for(int i=0;i<p->anzahl;i++) p->buts[i].CopyFont(font);
		if (!p->manageonly)
			p->grp.Create(win,RealSize(),RealSize(),width-RealSize()-RealSize(),height-RealSize()-RealSize());
	    return 1;
    }
    return 0;
}
void mxgadget::Selected(int s)
{
	p->buts[p->selected]->State(RELEASED);
	if (s>=p->anzahl) s=p->anzahl-1;
	if (s<0) s=0;
	p->selected=s; p->zselected=s;
	p->buts[p->selected]->State(PRESSED);	
}
int mxgadget::Selected(void)
{
	return p->selected;
}
void mxgadget::GExpose(XEvent *event)
{
	if (wasfor)
	{
		wasfor->GExpose(event);	
	}
	else
	{
		if (!p->manageonly)
		{
		    if (p->key)
		    {
   			    bordermark(this,0,0,width,height);
		    }
		    else
	    	{
   		    	borderunmark(this,0,0,width,height);
		    }
		}
	}
}
void mxgadget::GActionPress(int mx,int my,int rx,int ry,unsigned int state,int button,int reason)
{
	if (reason&GB_KEY)
	{
		gadget *oo=wasfor;
//		if (!wasfor)
//		{
//			p->zselected=p->selected;
//		}
		if (!p->key && !wasfor) //p->zselected==p->selected)
		{
			p->buts[p->zselected]->ActivateKey();
		}
		if (!p->key && wasfor)
		{
	    	for(int i=0;i<p->anzahl;i++)
	    	{
	    		if (wasfor==p->buts[i])
	    		{
	    			p->zselected=i;
	    		}
	    	}
		}
		p->key=GB_KEY;
		wasfor=NULL;
		GExpose(NULL);
		wasfor=oo;
		if (wasfor)
		{
			wasfor->GActionPress(mx,my,rx,ry,state,button,reason);
		}
	}
	else
	{
		if (wasfor)
		{
			p->buts[p->selected]->State(RELEASED);
			p->buts[wasfor->ID()]->State(PRESSED);
		}
	}
}
void mxgadget::GActionRelease(int mx,int my,int rx,int ry,unsigned int state,int button,int reason)
{ 
	if (reason&GB_KEY)
	{
		gadget *oo=wasfor;
		p->key=0;
		wasfor=NULL;
		GExpose(NULL);
		wasfor=oo;
		if (wasfor)
		{
			wasfor->GActionRelease(mx,my,rx,ry,state,button,reason);
		}
	}
	else
	{
		if (wasfor)
		{
			p->buts[wasfor->ID()]->State(RELEASED);
			p->buts[p->selected]->State(PRESSED);
		}
	}
}
int mxgadget::GActivate(XEvent *event,int why)
{	
	if (wasfor && why!=GA_KEY)
	{
		if (((selgadget*)wasfor)->State()==PRESSED) return 0;
		return wasfor->GActivate(event,why) & GAR_ACTIVE;
	}
	else
	{ // kann fast nur Key sein!
		if (why==GA_KEY)
		{
			int c;
			char taste[5];
			KeySym key;
			c=XLookupString((XKeyEvent*)event,taste,sizeof(taste),&key,0);

			switch (key)
			{
				case XK_Up:
				case XK_Left:
					p->zselected--;
					if (p->zselected<0) p->zselected=0;
					p->buts[p->zselected]->ActivateKey();
					break;
				case XK_Down:
				case XK_Right:
					p->zselected++;
					if (p->zselected>=p->anzahl) p->zselected=p->anzahl-1;
					p->buts[p->zselected]->ActivateKey();
					break;
				default:
					c=DefaultKeyHandler(event);
					if (c==DKH_SELECT)
					{
						Selected(p->zselected);
						return GAR_ACTIVE;
					}
					if (c==DKH_DEACTIVATED)
					{
						return 0;
					}
					break;
			}
		}
	}
	return 0;
}
int mxgadget::GSelected(XEvent *event,int why,int wasabove)
{
	if (wasfor && why!=GA_KEY)
	{
		int r=0; 
		if (wasfor->GSelected(event,why,wasabove) && why!=GA_KEY)
		{
			for(int i=0;i<p->anzahl;i++)
			{ 
				if (wasfor==p->buts[i] && (p->selected!=i)) 
				{
					r=GSR_SELECTION|GSR_MESSAGE;
					Selected(i); 
					wasfor->ActivateKey();
				}
			}
		}
		return r;
	}
	else
	{
	    return (wasabove|(why==GA_KEY))?GSR_SELECTION|GSR_MESSAGE:0;   // selected if above
	}
	return 0;
}
void mxgadget::GSetLimits(void)
{
	if (p->manageonly)
	{
		minwidth =1;
		minheight=1;
		maxwidth =1;
		maxheight=1;
	}
	else
	{
		p->grp.GSetLimits();
		minwidth =p->grp.gg_minwidth()+RealSize()+RealSize();
		minheight=p->grp.gg_minheight()+RealSize()+RealSize();
		maxwidth =p->grp.gg_maxwidth()+RealSize()+RealSize();
		maxheight=p->grp.gg_maxheight()+RealSize()+RealSize();
	}
}
void mxgadget::Resize(int w,int h)
{
	if (!p->manageonly)
	{
		p->grp.Resize(w-RealSize()-RealSize(),h-RealSize()-RealSize());
		gadget::Resize(w,h);
	}
}
void mxgadget::Lock(void)
{
	if (!p->manageonly)
	{
		p->grp.Lock();
	}
	else
	{
		for(int i=0;i<p->anzahl;i++)
		{
			p->buts[i]->Lock();
		}
	}
	gadget::Lock();
}
void mxgadget::Unlock(void)
{
	if (!p->manageonly)
	{
		p->grp.Unlock();
	}
	else
	{
		for(int i=0;i<p->anzahl;i++)
		{
			p->buts[i]->Unlock();
		}
	}
	gadget::Unlock();
}
void mxgadget::Block(int b)
{
	if (!p->manageonly)
	{
		p->grp.Block(b);
	}
	else
	{
//		for(int i=0;i<p->anzahl;i++)
//		{
//			p->buts[i]->Block(b);
//		}
	}
	gadget::Block(b);
}
void mxgadget::Unblock(int b)
{
	if (!p->manageonly)
	{
		p->grp.Unblock(b);
	}
	else
	{
//		for(int i=0;i<p->anzahl;i++)
//		{
//			p->buts[i]->Unblock(b);
//		}
	}
	gadget::Unblock(b);
}

#endif
