/*	XDraw.h
 *
 *		The drawing object. This encapsulates the common drawing operations
 *	that a program may use to draw stuff
 */

/*  YAAF - Yet another application framework
 *  Copyright (C) 1997, 1998 William Edward Woody
 *  
 *  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 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 MERCHANTABIILITY 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.
 *  
 *  To contact the author, either e-mail me at woody@pandawave.com, 
 *	or write to
 *  
 *          William Edward Woody
 *          In Phase Consulting
 *          1545 Ard Eevin Avenue
 *          Glendale, CA 91202
 *
 *	Or visit us on the web at http://www.pandawave.com
 */

#ifndef PandaWave_XDRAW
#define PandaWave_XDRAW

#include <XConfig.h>
#include <XDrawData.h>
#include <XDynArray.h>

#if OPT_XWIN
#include <X11/Xlib.h>
#endif

/************************************************************************/
/*																		*/
/*	Externals															*/
/*																		*/
/************************************************************************/

#if OPT_XWIN
extern Display *_GDisplay;
extern unsigned long AllocColor(Color c);
#endif

/************************************************************************/
/*																		*/
/*	Forwards															*/
/*																		*/
/************************************************************************/

class XGView;
class XGFont;
class XGPrinter;
class XGDraw;

/************************************************************************/
/*																		*/
/*	Support Routines													*/
/*																		*/
/************************************************************************/

#if OPT_WINOS

/*	MS Windows Missing Routines */

extern void			DrawResBitmap(HDC dest, short id, short x, short y);

#endif

#if OPT_XWIN

/* X Windows routines */

extern Point		GetBitmapSize(short resID);
extern void			DrawXBitmap(Display *,
								Drawable, 
								GC,
								short resID, 
								short x, 
								short y);
extern void			DrawXIcon(Display *, 
							  Drawable,
							  GC,
							  short resID, 
							  short x, 
							  short y);

#endif

/************************************************************************/
/*																		*/
/*	Drawing Constants													*/
/*																		*/
/************************************************************************/

/*	XGERectType
 *
 *		The rectangle type (enumeration)
 */

enum XGERectType {
	KXGEFrame = 1,							// black frame
	KXGEInset,								// 3D inset rectangle
	KXGEOutset,								// 3D outset rectangle
	KXGEButton,								// Outset rectangle button
	KXGEInButton,							// Inset rectangle button
	KXGEGrayFrame,							// gray (disabled) frame
	KXGEBackFrame,							// background frame
	KXGEBackground							// 3D background color
};

/*
 *	Font flags
 */

#define	KXGFontBold				0x0001
#define KXGFontItalic			0x0002
#define KXGFontUnderline		0x0004
#define KXGFontFixFont			0x0100		// fixed or variable?
#define KXGFontSerifFont		0x0200		// serif or san-serif?


/************************************************************************/
/*																		*/
/*	Font Resource Format												*/
/*																		*/
/************************************************************************/

/*	XGSFontResource
 *
 *		Font resource format
 */

struct XGSFontResource {
	short						size;
	short						fBold;
	short						fItalic;
	short						fUnderline;
	short						fFixed;
	short						fSerif;
	char						name[32];
};
/************************************************************************/
/*																		*/
/*	Drawing Support														*/
/*																		*/
/************************************************************************/

/*	@C"XGFont"
 *	@H"XDraw.h"
 *	@I
 *
 *		Font management class. This is the class object which is used
 *	to handle font by encapsulating them
 */

class XGFont {
	public:
								XGFont();
		virtual					~XGFont();
		
		/*
		 *	Font attach/lock semantics
		 */
		
		// @G"Attach/Detach Semantics"
		
		/*	@F"XGFont::Attach" @I
		 *
		 *		This increments the 'attach' count of the font. When
		 *	the font is first created, it's created with an attach count
		 *	of one.
		 */
		
		void					Attach(void)
									{
										fAttach++;
									}
		void					Detach(void);
		
		/*
		 *	Font resource management
		 */
		
		static XGFont			*LoadFont(short);
		static XGFont			*GetFontVariant(XGFont *f, short flags);
									
		/*
		 *	Font specification
		 */
		
		// @G"Font Specification"
		
		/*	@F"XGFont::GetFontFlags" @I
		 *
		 *		Get the flags associated with this font. This returns
		 *	the 'bold', 'italic' and 'underline' settings
		 */
		
		short					GetFontFlags() const
									{
										return fFontFlags;
									}
		void					GetFontName(char *) const;

		/*	@F"XGFont::GetFontSize" @I
		 *
		 *		Returns the current size of this font in points.
		 */
		
		short					GetFontSize(void) const
									{
										return fFontSize;
									}

		void					SetFontFlags(short);
		void					SetFontName(const char *);
		void					SetFontSize(short);
	
		/*
		 *	Font hooks
		 */
		
#if OPT_MACOS == 1
		void					SetFont();
#endif

#if OPT_WINOS == 1
		HFONT					GetFont(HDC dc = NULL);
#endif

#if OPT_XWIN == 1
		Font					GetFont();
		XFontStruct				*GetFontStruct();
#endif

	private:
		long					fAttach;
		short					fFontResID;
		
		short					fFontFlags;
		short					fFontSize;
		char					fFontName[64];
		
		static XGPDynArray<XGFont> gFontArray;

#if OPT_MACOS == 1
		short					fFontID;
#endif

#if OPT_WINOS == 1
		HFONT					fFontHandle;
#endif

#if OPT_XWIN == 1
		XFontStruct				*fFontData;
#endif
};

/*	@C"XGDraw"
 *	@H"XDraw.h"
 *	@I
 *
 *		This provides a universal interface for drawing inside of a view.
 *
 *		This is a stack based object; this object is generally created
 *	on a stack. To draw, a view creates this object on the stack and
 *	then calls events into it. (By being stack based, it means that
 *	when the stack unwinds, this will be destroyed and the resources
 *	will be released.)
 */

class XGDraw {
	public:
								XGDraw(XGView *v, bool lc = true);
								XGDraw(XGPrinter *p);
		virtual					~XGDraw();
		
		/*
		 *	State support
		 */
		 
		// @G"State Support"
		
		/* @F"XGDraw::GetDraw" @I
		 *
		 *		Returns the current XGDraw object; this is the thing
		 *	that can be drawn in
		 */
		
		static XGDraw			*GetDraw()
									{
										return gDraw;
									}

		/* @F"XGDraw::GetView" @I
		 *
		 *		Returns the current XGView object being drawn into.
		 */

		static XGView			*GetView()
									{
										if (gDraw) return gDraw->fView;
										else return NULL;
									}
									
		/*
		 *	Low level drawing support
		 */
		 
		Point					GetResolution();
		
		void					MoveTo(short,short);
		void					LineTo(short,short);
		Point					GetPenPos(void);
		
		void					FrameOval(Rect);
		void					PaintOval(Rect);
		void					EraseOval(Rect);
		
		void					FrameArc(Rect,short,short);
		void					PaintArc(Rect,short,short);
		void					EraseArc(Rect,short,short);
		
		void					FrameRect(Rect);
		void					PaintRect(Rect);
		void					EraseRect(Rect);
		void					InvertRect(Rect);
		void					DrawFocusRect(Rect);
		
		void					FillRect(Rect,Color);
		void					FillRect(short,short,short,short,Color);
		void					Draw3DRect(Rect,XGERectType);
		
		void					SetFont(XGFont *);

		/* @F"XGDraw::GetFont" @I
		 *
		 *		Returns the current font selected into this drawing
		 *	object. This increments the 'attach' count, so you must
		 *	detach the font when done.
		 */

		XGFont					*GetFont()
									{
										fFontPtr->Attach();
										return fFontPtr;
									}
		short					GetFontAscent();
		short					GetFontDescent();
		short					GetFontHeight();
		short					StringWidth(const char *, short len = -1);
		void					DrawString(const char *, short len = -1);
		short					StringWidthA(const char *, short len = -1);
		void					DrawStringA(const char *, short len = -1);
		
		void					DrawIcon(short,short x, short y);
		void					DrawPicture(short, short x, short y);
		
		void					ClipRect(Rect *r = NULL);

		Color					ColorFromPalette(Color);
		void					SetForeColor(Color);
		void					SetBackColor(Color);
		void					SetPenWidth(short);
		
		/*
		 *	Local OS dependant state information
		 */
		
#if OPT_WINOS == 1
		HDC						GetDC() const
									{
										return fDC;
									}
#endif

#if OPT_XWIN == 1
		Display					*GetDisplay() const
									{
										return _GDisplay;
									}
		GC						GetGC() const
									{
										return fGC;
									}
		Drawable				GetDrawable() const;
#endif

#if (OPT_XWIN == 1) || (OPT_WINOS == 1)
		static void				UpdateRect(Rect *r = NULL)
									{
										gUpdate = r;
									}
#endif

	private:
		/*
		 *	Context management routines
		 */
		
		void					CreateContext(bool);
		void					SaveContext();
		void					RestoreContext();
		void					DestroyContext();
	
		/*
		 *	Internal globals
		 */
		
		static XGDraw			*gDraw;		// Draw stack
		XGDraw					*fLast;
		XGView					*fView;
		XGFont					*fFontPtr;	// internal font to use
		XGPrinter				*fPrinter;	// printer with my view...
		
		/*
		 *	Internal state information
		 */
		
		short					fPenWidth;
		
#if OPT_MACOS == 1
		PenState				fPenState;
		short					fFont;
		short					fFace;
		short					fSize;
		short					fMode;
		RGBColor				fForeColor;
		RGBColor				fBackColor;
		Fixed					fSpExtra;
		
		RgnHandle				fClip;
		Point					fOffset;
		GrafPtr					fPort;
#endif

#if OPT_WINOS == 1
		COLORREF				fForeColor;
		COLORREF				fBackColor;

		HGDIOBJ					fDefFont;
		HDC						fDC;
		long					fDCSave;
#endif

#if OPT_XWIN == 1
		GC						fGC;
		
		Color					fForeground;
		Color					fBackground;
		
		short					fXOrigin;
		short					fYOrigin;
		short					fXPen;
		short					fYPen;
#endif

#if (OPT_XWIN == 1) || (OPT_WINOS == 1)
		static Rect				*gUpdate;
#endif

};

#endif // PandaWave_XDRAW
