#ifndef CODE_CHOICE_CXX
#define CODE_CHOICE_CXX

/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: choice.cxx,v 1.9 2001/10/22 17:32:48 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/choice.h>
#include "include/choice_p.h"
#include <Xclasses/tools.h>
#include <Xclasses/gfx_text.h>

choice::choice() : gadget(), Ddraw(this)
{
	while (!(p=new pchoice))
	{
		outOfMemory("choice");
	}
	p->o=this;
	Name("choice");
	p->pup.ParentClass(this);
	SetKeyHandler(KHM_SELECT);
}
pchoice::pchoice() : pup()
{
	anzahl=0;
	txts=NULL;
}
pchoice::~pchoice()
{
}
choice::~choice()
{
	if (win) Free();
	if (p) delete p;
}
void choice::Items(char *gtxts[])
{
	char *sub=NULL;
	p->txts=gtxts;
	p->anzahl=0;
	while (p->txts[p->anzahl])    
	{
		p->anzahl++;
	}

	p->pup.Clear();

	for(int i=0;i<p->anzahl;i++)
	{
		if (p->txts[i][0]=='>')
		{
			char *c=p->txts[i];
			int has=0;
			while (*c)
			{
				if (*c=='/')
				{
					has=1;
					c++;
					break;
				}
				c++;
			}
			if (has)
			{
				char *csub=strdup(p->txts[i]+1);
				if (csub)
				{
					csub[c-p->txts[i]-2]=0;
					if (!sub || strcmp(csub,sub))
					{
						if (sub)
						{
							free(sub);
							p->pup.EndSub();
						}
						else
							p->pup.AddRuler();
						sub=csub;
						p->pup.AddSub(sub);
					}
					else
						free(csub);
				}
				p->pup.Add(c,NULL,i+1);
			}
			else
			{
				if (sub)
				{
					free(sub);
					sub=NULL;
					p->pup.EndSub();
					p->pup.AddRuler();
				}
				p->pup.Add(p->txts[i],NULL,i+1);
			}
		}
		else
		{
			if (sub)
			{
				free(sub);
				sub=NULL;
				p->pup.EndSub();
			}
			p->pup.Add(p->txts[i],NULL,i+1);
		}
	}

	if (sub) free(sub);
	p->selected=0;
	if (win) p->draw();
}
void choice::Selected(int s)
{
	p->selected=s;
	if (p->selected>=p->anzahl) p->selected=p->anzahl-1;
	if (p->selected<0) p->selected=0;
	if (win) p->draw();
}
int choice::Selected(void)
{
	return p->selected;
}
void choice::Free(void)
{
	p->pup.Free();
	gadget::Free();
}

int choice::Create(void)
{
	Background(col_background());
	BorderSize(2);
	KeyBorder();

	char *r;
	if (r=GetResource("selected"))
	{
		int s=atoi(r);
		if (s>=0 && s<p->anzahl) Selected(s);
	}
	
    if (gadget::Create())
    {
    	char *res=GetResource("hilight");
    	if (!res || strcasecmp(res,"True"))
    	    Mode(GM_BUTTON1|GM_ONEEXPOSE|GM_KEY);
		else
	        Mode(GM_BUTTON1|GM_ONEEXPOSE|GM_KEY|GM_ABOVE|GM_LOCKATONCE);
        p->pup.SendEventTo(this);
        p->pup.CopyFont(this);
        return p->pup.Create();
    } 
    return 0;
}

char *pchoice::cuttxts(int s)
{
	if (txts && txts[s] && txts[s][0]=='>')
	{
		char *c=txts[s];
		int has=0;
		while (*c)
		{
			if (*c=='/')
			{
				has=1;
				c++;
				break;
			}
			c++;
		}
		if (has)
		{
			return c;
		}
	}
	return txts[s];
}
void pchoice::draw(int md)
{ // 0: normal
  // 1: hilight

	int m=(o->height-6-8)/2;
	if (md)
		o->borderUpShineFill(o,0,0,o->width,o->height);
	else
		o->borderUpFill(o,0,0,o->width,o->height);

	gfx_text gt;
	gt.NoUnderlineText(cuttxts(selected));
	gt.Adjust(ADJUST_CENTER|ADJUST_MIDDLE);
	gt.draw_normal(o,0,0,o->width-30,o->height);
	for(int i=0;i<BUTSIZE;i++)
	{
		XSetForeground(o->display(),o->gc,(i==BUTSIZE-1?o->col_shine2():o->col_shine()));
		XDrawLine(o->display(),o->win,o->gc,o->width-25+i,4+i+m,o->width-10-i,4+i+m);
		XDrawLine(o->display(),o->win,o->gc,o->width-25+i,4+i+m,o->width-25+i,4+6-i+m);

		XSetForeground(o->display(),o->gc,(i==BUTSIZE-1?o->col_shadow2():o->col_shadow()));
		XDrawLine(o->display(),o->win,o->gc,o->width-25+i,4+6-i+m,o->width-10-i,4+6-i+m);
		XDrawLine(o->display(),o->win,o->gc,o->width-10-i,4+i+m,o->width-10-i,4+6-i+m);
	}
	
	if (o->locked)
	{
		gt.draw_locked(o,0,0,o->width-30,o->height);
		o->borderlocked(o,0,0,o->width,o->height);
	}
    if (o->active & GA_KEY)
    {
		o->bordermark(o,0,0,o->width,o->height);   	    
    }	
    else
    {
		o->borderunmark(o,0,0,o->width,o->height);
    }
}

void choice::GExpose(XEvent *event)
{
	if (wasfor)
	{
		wasfor->GExpose(event);
		return;
	}
	p->draw();
}
void choice::GActionPress(int mx,int my,int rx,int ry,unsigned int state,int button,int reason)
{
	if (p->pup.PopupOpen())
	{
		p->pup.GActionPress(mx,my,rx,ry,state,button,reason);
	}
	else
	{
		if (reason&GB_KEY)
		{
			bordermark(this,0,0,width,height);
		}
	}
}
void choice::GActionRelease(int mx,int my,int rx,int ry,unsigned int state,int button,int reason)
{
	if (p->pup.PopupOpen())
	{
		p->pup.GActionRelease(mx,my,mx,my,state,button,reason);
	}
	else
	{
		if (reason&GB_KEY)
		{
			borderunmark(this,0,0,width,height);
		}
	}
}
int choice::GActivate(XEvent *event,int why)
{
	if (p->pup.PopupOpen())
	{
		return p->pup.GActivate(event,why)&GAR_ACTIVE;
	}
	else
	{
		switch (why)
		{
			case GA_BUTTONPRESS:
				{
					int x,y;
					GetPositionOnRoot(display(),win,x,y);
					ActivateKey();
					if (p->anzahl>0)
					{
						p->pup.OpenAt(x+4,y,p->selected,width-30);
						return GAR_ACTIVE;
					}
					return 0;
				}
				break;
			case GA_KEY:
				{
					int r;
					r=DefaultKeyHandler(event);
				    if (r==DKH_SELECT)
				    {
						int x,y;
						GetPositionOnRoot(display(),win,x,y);
						p->pup.OpenAt(x+4,y,p->selected,width-30);
			    		return 0;
				    }
			    }
			    break;
			case GA_ABOVE:
				p->draw(1);
				return GAR_ACTIVE;
				break;
		}
	}
    return 0;
}
int choice::GSelected(XEvent *event,int why,int wasabove)
{
	if (p->pup.PopupOpen())
	{
		if (p->pup.GSelected(event,why,wasabove))
		{
			if (p->pup.PID()>0)
			{
				Selected(p->pup.PID()-1);
				return GSR_SELECTION|GSR_MESSAGE;
			}
			else
				return 0;
		}
	}
	if (why==GA_ABOVE) p->draw();
    return 0;
}
int choice::GMouseMove(int mx,int my,int rx,int ry,unsigned int state,int button)
{
	if (p->pup.PopupOpen())
	{
		return p->pup.GMouseMove(mx,my,rx,ry,state,button) & GSR_SELECTION;
	}
	return 0;
}
void choice::GSetLimits(void)
{
	int mw=0,mh=0;
	minheight=0;
	minwidth=0;
	if (p->anzahl>0)
	{
		for (int i=0;i<p->anzahl;i++)
		{
			mw=textlength(this,p->cuttxts(i))+6+8;
			if (mw>minwidth) minwidth=mw;
			mh=textheight(this,p->cuttxts(i))+6+4;
			if (mh>minheight) minheight=mh;
		}
	}
	else
	{
		minwidth=textlength(this,"MOMOMOMO")+6+8;
		if (mw>minwidth) minwidth=mw;
		minheight=textheight(this," ")+6+4;
		if (mh>minheight) minheight=mh;
	}
	minwidth+=30;
	maxheight=minheight;
}



#endif
