/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: html_drawspec.cxx,v 1.21 1999/11/22 11:28:45 schmitzj Exp $)
 * 
 * Copyright (C) 1998 Jürgen Schmitz
 *
 * HTML Parser system
 * (c) 1998 by Jürgen Schmitz - all rights reserved
 * THIS IS NOT GPL OR SOMETHING OTHER FREE LICENSE!!
 * it may only be used together with Xclasses!
 *-----------------------------------------------------------------------
 */

#include <string.h>
#include "include/html_drawspec.h"
#include "include/html_box.h"

html_drawspec *CreateDrawspec(class html_box *b)
{
	return new html_drawspecXclasses(b);
}

// --- Xclasses ------------------------------------------------------

#include "include/html_gadget_p.h"
#include <Xclasses/gfx_text.h>

html_drawspecXclasses::html_drawspecXclasses(html_box *b) : callable(), html_drawspec(b)
{
	txtbuf=NULL;
	bufsize=0;
	owngg=1;
	phg=NULL;
	gg=new hgadget(this);
	gg->Name("html");
	background=strdup("#cccccc");
}
html_drawspecXclasses::html_drawspecXclasses(hgadget *g,class phtml_gadget *g2) : callable(), html_drawspec(NULL)
{
	txtbuf=NULL;
	bufsize=0;
	owngg=0;
	gg=g;
	phg=g2;
	background=strdup("#cccccc");
}
html_drawspecXclasses::~html_drawspecXclasses()
{
	if (owngg) delete gg;
	if (txtbuf) delete [] txtbuf;
	if (background) free(background);
}
char *html_drawspecXclasses::handleText(char *t)
{
	if (strlen(t)*2+1>bufsize)
	{
		delete [] txtbuf;
		txtbuf=new char[strlen(t)*2+1];
		bufsize=strlen(t)*2+1;
	}
	char *c=txtbuf;
	while (*t)
	{
		if (*t=='{')
		{
			*c='\\'; c++;
		}
		if (*t=='\\')
		{
			*c='\\'; c++;
		}
		*c=*t;
		t++;
		c++;
	}
	*c=0;
	return txtbuf;
}
void html_drawspecXclasses::gghandler(gadget *,int)
{
	box->Callback();
}

void html_drawspecXclasses::Create(html_drawspec *_parent,int x,int y,int width,int height)
{
	if (owngg)
	{
		if (width<1) width=1;
		if (height<1) height=1;
		parent=(html_drawspecXclasses*)_parent;
		gg->ParentClass(parent->gg);
		gg->Dimensions(parent->gg->gg_win(),x,y,width,height);
		gg->Background(gg->AllocColor(background));
		gg->Create();
	}
}
void html_drawspecXclasses::Move(int x,int y,int width,int height)
{
	if (owngg)
	{
		if (width<1) width=1;
		if (height<1) height=1;
		gg->Move(x,y);
		gg->Resize(width,height);
	}
	else
	{
		gg->scroll(x,y);
	}
}
void html_drawspecXclasses::Free(void)
{
	if (owngg)
	{
		gg->Free();
	}
}

void html_drawspecXclasses::Draw(void)
{
	box->DrawBox(1);
}

static gfx_text gfxtxt;
void html_drawspecXclasses::Cursor(int _x,int _y)
{
	x=_x;
	y=_y;
}
void html_drawspecXclasses::Text(char *t)
{
	gfxtxt.NoUnderlineText(handleText(t));
	XClearArea(gg->display(),gg->gg_win(),
		x,y,gfxtxt.width(gg),gfxtxt.height(gg),False);
	gfxtxt.draw_normal(gg,x,y,gfxtxt.width(gg)+1,gfxtxt.height(gg)+1);
}
int html_drawspecXclasses::TextLength(char *t)
{
	gfxtxt.NoUnderlineText(handleText(t));
	return gfxtxt.width(gg);
}
int html_drawspecXclasses::TextHeight(char *t)
{
	gfxtxt.NoUnderlineText(handleText(t));
	return gfxtxt.height(gg);
}
void html_drawspecXclasses::MarkedText(char *t,int x1,int x2)
{
	int i=0,l=strlen(t),w,xx1=x1,xx2=x2;
	while (i<=l)
	{
		w=XTextWidth(gg->gg_font(),t,i);
		if (w>=x1)
			break;
		else
			xx1=w;
		i++;
	}

	while (i<=l)
	{
		w=XTextWidth(gg->gg_font(),t,i);
		xx2=w;
		if (w>x2)
			break;
		i++;
	}
	gfxtxt.NoUnderlineText(handleText(t));

	XClearArea(gg->display(),gg->gg_win(),
		x,y,gfxtxt.width(gg),gfxtxt.height(gg),False);
	XSetForeground(gg->display(),gg->gg_gc(),gg->col_markbackground());
	XFillRectangle(gg->display(),gg->gg_win(),gg->gg_gc(),
		x+xx1,y,xx2-xx1,gfxtxt.height(gg));
	gfxtxt.draw_normal(gg,x,y,gfxtxt.width(gg)+1,gfxtxt.height(gg)+1);
}
char *html_drawspecXclasses::CutText(char *t,int x1,int x2,int &size)
{
	int i=0,l=strlen(t),w,i2=0;
	char *txt=t;
	while (i<=l)
	{
		w=XTextWidth(gg->gg_font(),t,i);
		if (w>=x1)
			break;
		else
			txt=t+i;
		i++;
	}

	i2=i;
	while (i<=l)
	{
		w=XTextWidth(gg->gg_font(),t,i);
		if (w>x2)
			break;
		i++;
	}
	size=i-i2;
	return txt;
}
void html_drawspecXclasses::Font(FONTSTYLE style,enum FONTSIZE size)
{
	static char fnt[100];
	char *fontName,*fontWeight,*fontSlant;
	int fontSize;

	fontName="times";
	fontWeight="medium";
	fontSlant="r";

	if (style & FSY_FIXED)
		fontName="courier";

	if (style & FSY_BOLD)
		fontWeight="bold";

	if (style & FSY_ITALIC)
		fontSlant="i";

	if (style & FSY_UNDERLINE)
		fontName=fontName;
	
	switch (size)
	{
		case FONT1:
			fontSize=20;
			break;
		case FONT2:
			fontSize=18;
			break;
		case FONT3:
			fontSize=14;
			break;
		case FONT4:
			fontSize=12;
			break;
		case FONT5:
			fontSize=10;
			break;
		case FONT6:
			fontSize=8;
			break;
		case NORMAL:
		default:
			fontSize=12;
			break;
	}
	sprintf(fnt,"-*-%s-%s-%s-*-*-*-%d0-*-*-*-*-*-*",fontName,fontWeight,fontSlant,fontSize);
	gg->Font(fnt);
}
void html_drawspecXclasses::Color(char *c)
{
	XSetForeground(gg->display(),gg->gg_gc(),gg->AllocColor(c));
}
void html_drawspecXclasses::BackgroundColor(char *c)
{
	if (background) free(background);
	background=strdup(c);
	gg->Background(gg->AllocColor(background));
	XClearWindow(gg->display(),gg->gg_win());
}
void html_drawspecXclasses::Line(int x1,int y1,int x2,int y2)
{


}
void html_drawspecXclasses::Callback(void)
{
	gg->MCursor(XC_hand2);
	gg->Mode(gg->gg_mode()|GM_BUTTON1);
	gg->Callback(this,(CALLBACK)&html_drawspecXclasses::gghandler);
}
void html_drawspecXclasses::Position(int &x,int &y)
{
	x=0;
	y=0;
	if (box) box->Position(x,y);
}
char *html_drawspecXclasses::Mark(int x1,int y1,int x2,int y2)
{
	if (box)
	{
		int x=0,y=0;
		html_box *b=box->GetMasterBox();
		if (box!=b) box->Position(x,y);
		return b->Mark(x1+x,y1+y,x2+x,y2+y);
	}
	else
		return NULL;
}
void html_drawspecXclasses::Unmark(void)
{
	if (box)
	{
		html_box *b=box->GetMasterBox();
		b->Unmark();
	}
}
class phtml_gadget *html_drawspecXclasses::ParentHTMLGadget(void)
{
	if (phg) return phg;
	if (parent && parent->phg) return parent->phg;
	return NULL;
}
