#ifndef CODE_DDRAW_CXX
#define CODE_DDRAW_CXX

/*-----------------------------------------------------------------------
 * Xclasses code file
 * ($Id: Ddraw.cxx,v 1.3 2001/10/20 18:21:13 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 <string.h>
#include "types.h"
#include "../include/XCprogram_p.h"
#include "../include/defaults.h"
#include <Xclasses/gadget.h>
#include <Xclasses/Ddraw.h>
#include "include/Ddraw_p.h"


short BLACKBORDER=0;
short NOKEY=0;
#define SUB		(BLACKBORDER?1:0)
#define KEYBORDERSIZE	1

static class gfx_text txt;
static class gfx_locked lok;

static char *rtxt(gadget *g,char *t)
{
	char *t2=g->GetResource("text");
	if (t2 && strlen(t2))
		return t2;
	else
		return t;
}

Ddraw::Ddraw(void)
{
	while (!(p=new pDdraw))
	{
		outOfMemory("Ddraw");
	}
	p->o=this;
}
Ddraw::Ddraw(gadget *g)
{
	while (!(p=new pDdraw))
	{
		outOfMemory("Ddraw");
	}
	p->o=this;
	p->gg=g;
}
pDdraw::pDdraw(void)
{
	size=1;
	keyborder=0;
	stripes=0;
	resread=0;
	gg=NULL;
}
pDdraw::~pDdraw()
{
}
Ddraw::~Ddraw()
{
	if (p) delete p;
}
int Ddraw::BorderSize(int newsize)
{
	int h=p->size;
	p->size=newsize; if (p->size<0) p->size=0;
	if (p->gg && !p->resread)
	{
		char *t2=p->gg->GetResource("bordersize");
		if (t2 && strlen(t2))
			p->size=atoi(t2);
		p->resread=1;
	}
	return h;
} 
int Ddraw::RealSize(void)
{
	if (p->gg && !p->resread)
	{
		char *t2=p->gg->GetResource("bordersize");
		if (t2 && strlen(t2))
			p->size=atoi(t2);
		p->resread=1;
	}
	if (p->gg && (p->gg->specialflags & SPF_NOKEYBORDER)) p->keyborder=0;
	return p->size+SUB+p->keyborder;
}
void Ddraw::KeyBorder(void)
{
	if (!NOKEY)	p->keyborder=KEYBORDERSIZE;
}
void Ddraw::NoKeyBorder(void)
{
	p->keyborder=0;
}
void Ddraw::StripesMark(void)
{
	p->stripes=1;
}
void Ddraw::SolidMark(void)
{
	p->stripes=0;
}

#define INNEN_X(x)	(x+SUB+p->size+p->keyborder)
#define INNEN_Y(y)	(y+SUB+p->size+p->keyborder)
#define INNEN_W(w)	(w-SUB-SUB-p->size-p->size-p->keyborder-p->keyborder)
#define INNEN_H(h)	(h-SUB-SUB-p->size-p->size-p->keyborder-p->keyborder)

void Ddraw::borderlocked(class gadget *g,int x,int y,int w,int h,int flags)
{
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	if (flags & LOCK_NOBORDER)
	{
		lok.draw_locked(g,x,y,w,h); XSPEC;
	}
	else
	{
		lok.draw_locked(g,INNEN_X(x),INNEN_Y(y),INNEN_W(w),INNEN_H(h)); XSPEC;
	}
}
void Ddraw::borderUp(class gadget *g,int x,int y,int w,int h)
{
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	x+=p->keyborder;
	y+=p->keyborder;
	w-=(p->keyborder+p->keyborder);
	h-=(p->keyborder+p->keyborder);

	if (BLACKBORDER)
	{
		XSetForeground(g->display(),g->gc,g->col_black());
		XDrawRectangle(g->display(),g->win,g->gc,x,y,w-1,h-1); XSPEC;
	}

	for(int i=0;i<p->size;i++)
	{
		XSetForeground(g->display(),g->gc,(i==p->size-1 && p->size>1?g->col_shine2():g->col_shine()));
		XDrawLine(g->display(),g->win,g->gc,x+SUB+i,y+SUB+i,x+w-SUB-1-i,y+SUB+i); XSPEC;
		XDrawLine(g->display(),g->win,g->gc,x+SUB+i,y+SUB+i,x+SUB+i,y+h-SUB-1-i); XSPEC;

		XSetForeground(g->display(),g->gc,(i==p->size-1 && p->size>1?g->col_shadow2():g->col_shadow()));
		XDrawLine(g->display(),g->win,g->gc,x+1+SUB+i,y+h-SUB-1-i,x+w-SUB-1-i,y+h-SUB-1-i); XSPEC;
		XDrawLine(g->display(),g->win,g->gc,x+w-SUB-1-i,y+1+SUB+i,x+w-SUB-1-i,y+h-SUB-1-i); XSPEC;
	}
}
void Ddraw::borderDown(class gadget *g,int x,int y,int w,int h)
{	
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	x+=p->keyborder;
	y+=p->keyborder;
	w-=(p->keyborder+p->keyborder);
	h-=(p->keyborder+p->keyborder);

	if (BLACKBORDER)
	{
		XSetForeground(g->display(),g->gc,g->col_black());
		XDrawRectangle(g->display(),g->win,g->gc,x,y,w-1,h-1); XSPEC;
	}

	for(int i=0;i<p->size;i++)
	{
		if (defaults.new3D)
			XSetForeground(g->display(),g->gc,(i==p->size-1?g->col_shadow():g->col_shadow2()));
		else
			XSetForeground(g->display(),g->gc,(i==p->size-1 && p->size>1?g->col_shadow2():g->col_shadow()));
		XDrawLine(g->display(),g->win,g->gc,x+SUB+i,y+SUB+i,x+w-1-SUB-i,y+SUB+i); XSPEC;
		XDrawLine(g->display(),g->win,g->gc,x+SUB+i,y+SUB+i,x+SUB+i,y+h-1-SUB-i); XSPEC;

		if (defaults.new3D)
			XSetForeground(g->display(),g->gc,(i==p->size-1?g->col_shine():g->col_shine2()));
		else
			XSetForeground(g->display(),g->gc,(i==p->size-1 && p->size>1?g->col_shine2():g->col_shine()));
		XDrawLine(g->display(),g->win,g->gc,x+w-1-SUB-i,y+1+SUB+i,x+w-1-SUB-i,y+h-1-SUB-i); XSPEC;
		XDrawLine(g->display(),g->win,g->gc,x+1+SUB+i,y+h-1-SUB-i,x+w-1-SUB-i,y+h-1-SUB-i); XSPEC;
	}
}
void Ddraw::borderEmboss(class gadget *g,int x,int y,int w,int h)
{	
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	x+=p->keyborder;
	y+=p->keyborder;
	w-=(p->keyborder+p->keyborder);
	h-=(p->keyborder+p->keyborder);

	if (BLACKBORDER)
	{
		XSetForeground(g->display(),g->gc,g->col_black());
		XDrawRectangle(g->display(),g->win,g->gc,x,y,w-1,h-1); XSPEC;
	}

	for(int i=0;i<p->size;i++)
	{
		if (i<p->size/2)
			XSetForeground(g->display(),g->gc,(i==p->size/2-1 && i>0?g->col_shine2():g->col_shine()));
		else
			XSetForeground(g->display(),g->gc,(i==p->size/2?g->col_shadow2():g->col_shadow()));

		XDrawLine(g->display(),g->win,g->gc,x+SUB+i,y+SUB+i,x+w-1-SUB-i,y+SUB+i); XSPEC;
		XDrawLine(g->display(),g->win,g->gc,x+SUB+i,y+SUB+i,x+SUB+i,y+h-1-SUB-i); XSPEC;

		if (i<p->size/2)
			XSetForeground(g->display(),g->gc,(i==p->size/2-1 && i>0?g->col_shadow2():g->col_shadow()));
		else
			XSetForeground(g->display(),g->gc,(i==p->size/2?g->col_shine2():g->col_shine()));

		XDrawLine(g->display(),g->win,g->gc,x+w-1-SUB-i,y+1+SUB+i,x+w-1-SUB-i,y+h-1-SUB-i); XSPEC;
		XDrawLine(g->display(),g->win,g->gc,x+1+SUB+i,y+h-1-SUB-i,x+w-1-SUB-i,y+h-1-SUB-i); XSPEC;
	}
}

void Ddraw::borderUpFill(class gadget *g,int x,int y,int w,int h)
{
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	XSetForeground(g->display(),g->gc,g->col_background());
	XFillRectangle(g->display(),g->win,g->gc,x+SUB+p->size+p->keyborder,y+SUB+p->size+p->keyborder,w-SUB-SUB-p->size-p->size-p->keyborder-p->keyborder,h-SUB-SUB-p->size-p->size-p->keyborder-p->keyborder); XSPEC;
	borderUp(g,x,y,w,h);
}
void Ddraw::borderDownFill(class gadget *g,int x,int y,int w,int h)
{
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	XSetForeground(g->display(),g->gc,g->col_selected());
	XFillRectangle(g->display(),g->win,g->gc,x+SUB+p->size+p->keyborder,y+SUB+p->size+p->keyborder,w-SUB-SUB-p->size-p->size-p->keyborder-p->keyborder,h-SUB-SUB-p->size-p->size-p->keyborder-p->keyborder); XSPEC;
	borderDown(g,x,y,w,h);
}
void Ddraw::borderEmbossFill(class gadget *g,int x,int y,int w,int h)
{
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	XSetForeground(g->display(),g->gc,g->col_background());
	XFillRectangle(g->display(),g->win,g->gc,x+SUB+p->size+p->keyborder,y+SUB+p->size+p->keyborder,w-SUB-SUB-p->size-p->size-p->keyborder-p->keyborder,h-SUB-SUB-p->size-p->size-p->keyborder-p->keyborder); XSPEC;
	borderEmboss(g,x,y,w,h);
}
void Ddraw::borderUpShineFill(class gadget *g,int x,int y,int w,int h)
{
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	XSetForeground(g->display(),g->gc,g->col_shinebackground());
	XFillRectangle(g->display(),g->win,g->gc,x+SUB+p->size+p->keyborder,y+SUB+p->size+p->keyborder,w-SUB-SUB-p->size-p->size-p->keyborder-p->keyborder,h-SUB-SUB-p->size-p->size-p->keyborder-p->keyborder); XSPEC;
	borderUp(g,x,y,w,h);
}

void Ddraw::bordermark(class gadget *g,int x,int y,int w,int h)
{
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	if (NOKEY || !p->keyborder) return;
	if (p->stripes)
	{
		char dot[]={2,3,3,2,2,3,3,2};
	
		XSetDashes(g->display(),g->gc,0,dot,8);
		XSetLineAttributes(g->display(),g->gc,0,LineOnOffDash,CapButt,JoinRound);
	}
	XSetForeground(g->display(),g->gc,g->col_black());
	XDrawRectangle(g->display(),g->win,g->gc,x,y,w-1,h-1); XSPEC;
	if (p->stripes)
	{
		XSetLineAttributes(g->display(),g->gc,0,LineSolid,CapButt,JoinRound);
	}
}
void Ddraw::borderunmark(class gadget *g,int x,int y,int w,int h)
{
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	if (NOKEY || !p->keyborder) return;
	class Xcolors *base=(Xcolors*)g->ParentClass();
	if (base)
	{
		XSetForeground(g->display(),g->gc,base->col_background());
	}
	else
	{
		XSetForeground(g->display(),g->gc,g->col_background());
	}
	XDrawRectangle(g->display(),g->win,g->gc,x,y,w-1,h-1); XSPEC;
}

void Ddraw::bordertext(class gadget *g,int x,int y,int w,int h,char *txt,int adjust,XFontStruct *font)
{
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	x+=p->keyborder;
	y+=p->keyborder;
	w-=(p->keyborder+p->keyborder);
	h-=(p->keyborder+p->keyborder);

	XFontStruct *fontbak;
	fontbak=g->gg_font();	
	g->gg_font(font);
	::txt.Text(rtxt(g,txt));
	::txt.Adjust(adjust);
	::txt.draw_normal(g,x,y,w,h);
	g->gg_font(fontbak);
}
void Ddraw::borderselectedtext(class gadget *g,int x,int y,int w,int h,char *txt,int adjust,XFontStruct *font)
{
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	x+=p->keyborder;
	y+=p->keyborder;
	w-=(p->keyborder+p->keyborder);
	h-=(p->keyborder+p->keyborder);

	XFontStruct *fontbak;
	fontbak=g->gg_font();
	g->gg_font(font);
	::txt.Text(rtxt(g,txt));
	::txt.Adjust(adjust);
	::txt.draw_selected(g,x,y,w,h);
	g->gg_font(fontbak);
}
void Ddraw::borderlockedtext(class gadget *g,int x,int y,int w,int h,char *txt,int adjust,XFontStruct *font)
{
	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	x+=p->keyborder;
	y+=p->keyborder;
	w-=(p->keyborder+p->keyborder);
	h-=(p->keyborder+p->keyborder);

	XFontStruct *fontbak;
	fontbak=g->gg_font();
	g->gg_font(font);
	::txt.Text(rtxt(g,txt));
	::txt.Adjust(adjust);
	::txt.draw_locked(g,x,y,w,h);
	g->gg_font(fontbak);
}
int Ddraw::textheight(class gadget *g,char *txt,XFontStruct *font)
{
	int i;
	XFontStruct *fontbak;

	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	fontbak=g->gg_font();
	g->gg_font(font);
	::txt.Text(rtxt(g,txt));

	i=::txt.height(g);

	g->gg_font(fontbak);
	return i;
}
int Ddraw::textlength(class gadget *g,char *txt,XFontStruct *font)
{
	int i;
	XFontStruct *fontbak;

	if (g->specialflags & SPF_NOKEYBORDER) p->keyborder=0;

	fontbak=g->gg_font();	
	g->gg_font(font);
	::txt.Text(rtxt(g,txt));

	i=::txt.width(g);

	g->gg_font(fontbak);
	return i;
}

#endif
