#ifndef CODE_GFXAUTOautotext_CXX
#define CODE_GFXAUTOautotext_CXX

/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: gfx_autotext.cxx,v 1.1.1.1 1998/07/16 19:29:31 cvs 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 <string.h>
#include <math.h>
#include "types.h"
#include <Xclasses/Xcolors.h>
#include <Xclasses/gadget.h>
#include <Xclasses/gfx_object.h>
#include <Xclasses/gfx_autotext.h>
#include "include/gfx_autotext_p.h"

gfx_autotext::gfx_autotext(void) : gfx_object()
{
	while (!(p=new pgfx_autotext))
	{
		outOfMemory("gfx_autotext");
	}
	p->o=this;
	Name("gfx_autotext");
}
gfx_autotext::gfx_autotext(char *t) : gfx_object()
{
	while (!(p=new pgfx_autotext))
	{
		outOfMemory("gfx_autotext");
	}
	p->o=this;
	Name("gfx_autotext");
	Text(t);
}
pgfx_autotext::pgfx_autotext(void)
{
	teile=NULL;
	adjust=ADJUST_LEFT|ADJUST_TOP;
	total_lines=1;
	total_parts=0;
	total_chars=0;
	allowunderline=0;
}
pgfx_autotext::~pgfx_autotext()
{
	if (teile)
	{
		parts *p1,*p2;
		p1=teile;
		while (p1)
		{
			p2=p1->next;
			delete [] (char*)p1;
			p1=p2;
		}
	}
}
gfx_autotext::~gfx_autotext()
{
	if (p) delete p;
}

void gfx_autotext::Adjust(int a)
{
	p->adjust=a;
}
void gfx_autotext::NoUnderlineText(char *txt)
{
	p->allowunderline=1;
	Text(txt);
}
void gfx_autotext::Text(char *txt)
{
	struct pgfx_autotext::parts *pp,*p1;
	char *start;
	int l,u,z;

	if (p->teile)
	{
		pgfx_autotext::parts *p1,*p2;
		p1=p->teile;
		while (p1)
		{
			p2=p1->next;
			delete [] (char*)p1;
			p1=p2;
		}
	}

	z=1; u=-1;
	p->total_parts=0;
	p->total_lines=1;
	p->total_chars=0;
	p->teile=NULL;
	if (txt)
	{
		start=txt;
		l=0;
		p1=(pgfx_autotext::parts*)&p->teile;
		while (*txt)
		{
			l++;
			if (*txt=='_' && !p->allowunderline)
			{
				u=l-1;
			}
			if (*txt=='\n' || *txt==' ')
			{
				if (pp=(pgfx_autotext::parts*)new char[sizeof(pgfx_autotext::parts)+l])
				{
					p->total_parts++;
					l--;
					p1->next=pp;
					pp->next=NULL;
					pp->length=l;
					pp->under=u;
					if (*txt=='\n')
					{
						pp->newline=1;
						p->total_lines++;
					}
					else
					{
						pp->newline=0;
					}
					strncpy(pp->text,start,l);
					pp->text[l]=0;
					if (u>=0)
					{
						pp->length--;
						strcpy(&pp->text[u],&pp->text[u+1]);
					}
					p->total_chars+=pp->length+1;
					start=txt+1;
					l=0; z++; u=-1;
					p1=pp;
				}
			}
			txt++;
		}
		if (l>0)
		{
			if (pp=(pgfx_autotext::parts*)new char[sizeof(pgfx_autotext::parts)+l])
			{
				p1->next=pp;
				pp->next=NULL;
				pp->under=u;
				pp->length=l;
				strncpy(pp->text,start,l);
				pp->text[l]=0;
				if (u>=0)
				{
					pp->length--;
					strcpy(&pp->text[u],&pp->text[u+1]);
				}
				start=txt+1;
				l=0;
				p1=pp;
			}
		}
		else
		{
			z--;
		}
	}
	p->allowunderline=0;
}

int pgfx_autotext::X(int w,int cw)
{
	switch (adjust & (1|2))
	{
		case ADJUST_LEFT:
			return 0;
			break;
		case ADJUST_CENTER:
			return (w-cw)/2;
			break;
		case ADJUST_RIGHT:
			return (w-cw);
			break;
	}
	return 0;
}
void pgfx_autotext::UL(gadget *g,int x,int y,struct parts *p)
{
	if (p->under>=0)
	{
		XCharStruct cs;
		int dhint,fasc,fdec;
		int x1,x2;
		XTextExtents(g->gg_font(),p->text,p->under,&dhint,&fasc,&fdec,&cs);
		x1=cs.width;
		XTextExtents(g->gg_font(),p->text,p->under+1,&dhint,&fasc,&fdec,&cs);
		x2=cs.width-1;
		XDrawLine(o->display(),g->gg_win(),g->gg_gc(),x+x1,y+fasc+fdec-1,x+x2,y+fasc+fdec-1);
	}
}
void pgfx_autotext::draw(class gadget *g,int x,int y,int w,int h)
{
	XCharStruct cs;
	int dhint,fasc,fdec,f;
	int gw,space,voll,z=0,x1,y1;
	struct parts *pp=teile,*pb;
	XFontStruct *ft;

	ft=g->gg_font();
	XTextExtents(ft," ",1,&dhint,&fasc,&fdec,&cs);
	space=cs.width;
	while (pp)
	{
		pb=pp;
		f=(fasc+fdec)*z;
		if (f>=0 && f<=h)
		{
			voll=0;
			gw=0;
			while (pb && !voll)
			{
				XTextExtents(ft,pb->text,pb->length,&dhint,&fasc,&fdec,&cs);
				pb->width=cs.width;
				if (pb->newline) voll=1;
				if (gw+cs.width<w)
				{
					gw+=cs.width+space;
					pb=pb->next;
				}
				else
				{
					voll=1;
				}
			}

			voll=0;
			x1=x;
			y1=y+f;
			while (pp && pp!=pb)
			{
				XDrawString(o->display(),g->gg_win(),g->gg_gc(),
							x1+X(w,gw),y1+fasc,pp->text,pp->length);
				UL(g,x1+X(w,gw),y1,pp);
				x1+=pp->width+space;
				pp=pp->next;
			}
			z++;
		}
		else
		{
			pp=pp->next;
		}
	}
}
void gfx_autotext::draw_normal(class gadget *g,int x,int y,int w,int h)
{
	XSetForeground(display(),g->gg_gc(),col_text());
	p->draw(g,x,y,w,h);
}
void gfx_autotext::draw_selected(class gadget *g,int x,int y,int w,int h)
{
}
void gfx_autotext::draw_locked(class gadget *g,int x,int y,int w,int h)
{
}
void gfx_autotext::draw_selectedlocked(class gadget *g,int x,int y,int w,int h)
{
	draw_locked(g,x,y,w,h);
}

int gfx_autotext::height(class gadget *g)
{
	int a;
	a=g->gg_font()->ascent+g->gg_font()->descent;
	a=(int)(a*p->total_lines+a*(p->total_chars/140+1));
	return a;
}
int gfx_autotext::width(class gadget *g)
{
	int a;
	XCharStruct cs;
	int dhint,fasc,fdec;
	XTextExtents(g->gg_font(),"MMM",3,&dhint,&fasc,&fdec,&cs);
	a=(int)(cs.width*p->total_chars/(sqrt(p->total_parts)+p->total_lines+p->total_chars/140)/3);
	return a;
}

#endif
