/*	Support.cpp
 *
 *		Miscellaneous support routines that are missing
 */

/*  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
 */

#include <XConfig.h>			// must be first to optimize compile on MSVC++
#include <XDraw.h>

/************************************************************************/
/*																		*/
/*	X Windows															*/
/*																		*/
/************************************************************************/

#if OPT_XWIN

/*	ToWord
 *
 *		Take byte to word
 */

static unsigned short ToWord(unsigned char c)
{
	return (((unsigned short)c) << 8) | c;
}

static short			GSize;
static unsigned long	GPixels[128];
static Color			GColors[128];

/*	FindColor
 *
 *		Find a color I've already allocated. Return false if this fails
 */

static bool FindColor(Color c, unsigned long *pixel)
{
	short i;
	
	for (i = 0; i < GSize; i++) {
		if (GColors[i] == c) {
			*pixel = GPixels[i];
			return true;
		}
	}
	return false;
}

/*	@F"AllocColor"
 *	@H"XDraw.h"
 *	@I
 *
 *		(X) Allocate a color. This finds the color if it was already
 *	asked for from the X server. This is used internally by YAAF.
 */

unsigned long AllocColor(Color c)
{
	XColor color;
	Colormap defmap;
	unsigned long pixel;
	
	if (FindColor(c,&pixel)) return pixel;
	if (GSize >= 128) {
		return BlackPixel(_GDisplay,DefaultScreen(_GDisplay));
	}
	
	/*
	 *	Allocate a new color in the server. This ain't exactly
	 *	the best way to do this, I think...
	 */
	
	defmap = DefaultColormap(_GDisplay,DefaultScreen(_GDisplay));
	color.red = ToWord(GetRValue(c));
	color.green = ToWord(GetGValue(c));
	color.blue = ToWord(GetBValue(c));
	color.pixel = 0;
	color.flags = DoRed | DoGreen | DoBlue;
	if (!XAllocColor(_GDisplay,defmap,&color)) {
		return BlackPixel(_GDisplay,DefaultScreen(_GDisplay));
	}
	
	GColors[GSize] = c;
	GPixels[GSize] = color.pixel;
	GSize++;
	return color.pixel;
}

#endif

/************************************************************************/
/*																		*/
/*	Microsoft Windows													*/
/*																		*/
/************************************************************************/

#if OPT_WINOS

extern "C" {
	extern HINSTANCE _GInstance;
}

/*	@F"DrawResBitmap"
 *	@H"XDrawData.h"
 *	@I
 *
 *		(Windows) Draw the bitmap specified from a resource file. This loads it
 *	myself, thus preserving the color information for the bitmap
 */

void DrawResBitmap(HDC dest, short resID, short x, short y)
{
	HRSRC find;
	HGLOBAL handle;
	LPBITMAPINFO header;
	short sx,sy;
	short ncolors;
	unsigned char *bptr;
	
	/*
	 *	Explicitly load DIB bitmap
	 */
	
	find = FindResource(_GInstance,MAKEINTRESOURCE(resID),RT_BITMAP);
	if (find == NULL) return;
	handle = LoadResource(_GInstance,find);
	if (handle == NULL) return;
	header = (LPBITMAPINFO)LockResource(handle);
	
	/*
	 *	Now figure out the size of this thing
	 */
	
	sx = header->bmiHeader.biWidth;
	sy = header->bmiHeader.biHeight;
	
	ncolors = header->bmiHeader.biClrUsed;
	if (ncolors == 0) {
		switch (header->bmiHeader.biBitCount) {
			case 1:
				ncolors = 2;
				break;
			case 4:
				ncolors = 16;
				break;
			case 8:
				ncolors = 256;
				break;
			default:
				ncolors = 0;
				break;
		}
	}
	bptr = (unsigned char *)header;
	bptr += header->bmiHeader.biSize;
	bptr += ncolors * sizeof(RGBQUAD);
	
	/*
	 *	Draw it
	 */
	
	StretchDIBits(dest,
				  x,y,						// destination offset
				  sx,sy,					// image size (from bitmap)
				  0,0,						// copy from origin
				  sx,sy,					// the entire thing
				  bptr,						// the bits
				  (BITMAPINFO *)header,		// the image header
				  DIB_RGB_COLORS,
				  SRCCOPY);
	
	/*
	 *	Unlock resource
	 */
	
	UnlockResource(handle);
	FreeResource(handle);
}

#endif // OPT_WINOS
