/* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
/* NetHack may be freely redistributed.  See license for details. */

/* font management and such */

#include "mhfont.h"

#define MAXFONTS	64

/* font table - 64 fonts ought to be enough */
static struct font_table_entry {
	int		code;
	HFONT   hFont;
} font_table[MAXFONTS] ;
static int font_table_size = 0;
HFONT version_splash_font;
HFONT extrainfo_splash_font;

#define NHFONT_CODE(win, attr) (((attr&0xFF)<<8)|(win_type&0xFF))

static void __cdecl font_table_cleanup(void);

/* create font based on window type, charater attributes and
   window device context */
HGDIOBJ mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace)
{
	HFONT fnt = NULL;
	LOGFONT lgfnt;
	int font_size;
	int font_index;
	static BOOL once = FALSE;

	if( !once ) {
		once = TRUE;
		atexit(font_table_cleanup);
	}

	ZeroMemory( &lgfnt, sizeof(lgfnt) );

	/* try find font in the table */
	for(font_index=0; font_index<font_table_size; font_index++)
		if(NHFONT_CODE(win_type, attr)==font_table[font_index].code)
			break;

	if( !replace && font_index<font_table_size )
		return font_table[font_index].hFont;

	switch(win_type) {
	case NHW_STATUS:
		lgfnt.lfHeight			=	-iflags.wc_fontsiz_status*GetDeviceCaps(hdc, LOGPIXELSY)/72;	 // height of font
		lgfnt.lfWidth			=	0;				     // average character width
		lgfnt.lfEscapement		=	0;					 // angle of escapement
		lgfnt.lfOrientation		=	0;					 // base-line orientation angle
		lgfnt.lfWeight			=	FW_NORMAL;           // font weight
		lgfnt.lfItalic			=	FALSE;		         // italic attribute option
		lgfnt.lfUnderline		=	FALSE;			     // underline attribute option
		lgfnt.lfStrikeOut		=	FALSE;			     // strikeout attribute option
		lgfnt.lfCharSet			=	mswin_charset();     // character set identifier
		lgfnt.lfOutPrecision	=	OUT_DEFAULT_PRECIS;  // output precision
		lgfnt.lfClipPrecision	=	CLIP_DEFAULT_PRECIS; // clipping precision
		lgfnt.lfQuality			=	DEFAULT_QUALITY;     // output quality
		if( iflags.wc_font_status &&
			*iflags.wc_font_status ) {
			lgfnt.lfPitchAndFamily = DEFAULT_PITCH;		 // pitch and family
			NH_A2W( iflags.wc_font_status, lgfnt.lfFaceName, LF_FACESIZE);
		} else {
			lgfnt.lfPitchAndFamily = FIXED_PITCH;		 // pitch and family
		}
		break;

	case NHW_MENU:
		lgfnt.lfHeight			=	-iflags.wc_fontsiz_menu*GetDeviceCaps(hdc, LOGPIXELSY)/72;	 // height of font
		lgfnt.lfWidth			=	0;				     // average character width
		lgfnt.lfEscapement		=	0;					 // angle of escapement
		lgfnt.lfOrientation		=	0;					 // base-line orientation angle
		lgfnt.lfWeight			=	(attr==ATR_BOLD || attr==ATR_INVERSE)? FW_BOLD : FW_NORMAL;   // font weight
		lgfnt.lfItalic			=	(attr==ATR_BLINK)? TRUE: FALSE;		     // italic attribute option
		lgfnt.lfUnderline		=	(attr==ATR_ULINE)? TRUE : FALSE;		 // underline attribute option
		lgfnt.lfStrikeOut		=	FALSE;				// strikeout attribute option
		lgfnt.lfCharSet			=	mswin_charset();     // character set identifier
		lgfnt.lfOutPrecision	=	OUT_DEFAULT_PRECIS;  // output precision
		lgfnt.lfClipPrecision	=	CLIP_DEFAULT_PRECIS; // clipping precision
		lgfnt.lfQuality			=	DEFAULT_QUALITY;     // output quality
		if( iflags.wc_font_menu &&
			*iflags.wc_font_menu ) {
			lgfnt.lfPitchAndFamily	= DEFAULT_PITCH;		 // pitch and family
			NH_A2W( iflags.wc_font_menu, lgfnt.lfFaceName, LF_FACESIZE);
		} else {
			lgfnt.lfPitchAndFamily = FIXED_PITCH;		 // pitch and family
		}
		break;

	case NHW_MESSAGE:
		font_size = (attr==ATR_INVERSE)? iflags.wc_fontsiz_message+1 : iflags.wc_fontsiz_message;
		lgfnt.lfHeight			=	-font_size*GetDeviceCaps(hdc, LOGPIXELSY)/72;	 // height of font
		lgfnt.lfWidth			=	0;				     // average character width
		lgfnt.lfEscapement		=	0;					 // angle of escapement
		lgfnt.lfOrientation		=	0;					 // base-line orientation angle
		lgfnt.lfWeight			=	(attr==ATR_BOLD || attr==ATR_INVERSE)? FW_BOLD : FW_NORMAL;   // font weight
		lgfnt.lfItalic			=	(attr==ATR_BLINK)? TRUE: FALSE;		     // italic attribute option
		lgfnt.lfUnderline		=	(attr==ATR_ULINE)? TRUE : FALSE;		 // underline attribute option
		lgfnt.lfStrikeOut		=	FALSE;			     // strikeout attribute option
		lgfnt.lfCharSet			=	mswin_charset();     // character set identifier
		lgfnt.lfOutPrecision	=	OUT_DEFAULT_PRECIS;  // output precision
		lgfnt.lfClipPrecision	=	CLIP_DEFAULT_PRECIS; // clipping precision
		lgfnt.lfQuality			=	DEFAULT_QUALITY;     // output quality
		if( iflags.wc_font_message &&
			*iflags.wc_font_message ) {
			lgfnt.lfPitchAndFamily	= DEFAULT_PITCH;		 // pitch and family
			NH_A2W( iflags.wc_font_message, lgfnt.lfFaceName, LF_FACESIZE);
		} else {
			lgfnt.lfPitchAndFamily	= VARIABLE_PITCH;		 // pitch and family
		}
		break;

	case NHW_TEXT:
		lgfnt.lfHeight			=	-iflags.wc_fontsiz_text*GetDeviceCaps(hdc, LOGPIXELSY)/72;	 // height of font
		lgfnt.lfWidth			=	0;				     // average character width
		lgfnt.lfEscapement		=	0;					 // angle of escapement
		lgfnt.lfOrientation		=	0;					 // base-line orientation angle
		lgfnt.lfWeight			=	(attr==ATR_BOLD || attr==ATR_INVERSE)? FW_BOLD : FW_NORMAL;   // font weight
		lgfnt.lfItalic			=	(attr==ATR_BLINK)? TRUE: FALSE;		     // italic attribute option
		lgfnt.lfUnderline		=	(attr==ATR_ULINE)? TRUE : FALSE;		 // underline attribute option
		lgfnt.lfStrikeOut		=	FALSE;			     // strikeout attribute option
		lgfnt.lfCharSet			=	mswin_charset();     // character set identifier
		lgfnt.lfOutPrecision	=	OUT_DEFAULT_PRECIS;  // output precision
		lgfnt.lfClipPrecision	=	CLIP_DEFAULT_PRECIS; // clipping precision
		lgfnt.lfQuality			=	DEFAULT_QUALITY;     // output quality
		if( iflags.wc_font_text &&
			*iflags.wc_font_text ) {
			lgfnt.lfPitchAndFamily	= DEFAULT_PITCH;		 // pitch and family
			NH_A2W( iflags.wc_font_text, lgfnt.lfFaceName, LF_FACESIZE);
		} else {
			lgfnt.lfPitchAndFamily	= FIXED_PITCH;		 // pitch and family
		}
		break;
	}

	fnt = CreateFontIndirect(&lgfnt);

	/* add font to the table */
	if( font_index==font_table_size ) {
		if( font_table_size>=MAXFONTS ) panic( "font table overflow!" );
		font_table_size++;
	} else {
		DeleteObject(font_table[font_index].hFont);
	}

	font_table[font_index].code = NHFONT_CODE(win_type, attr);
	font_table[font_index].hFont = fnt;
	return fnt;
}

UINT mswin_charset()
{
	CHARSETINFO cis;
	if( iflags.IBMgraphics )
		if( TranslateCharsetInfo((DWORD*)GetOEMCP(), &cis, TCI_SRCCODEPAGE) ) 
			return cis.ciCharset;
		else
			return OEM_CHARSET;
	else 
		if( TranslateCharsetInfo((DWORD*)GetACP(), &cis, TCI_SRCCODEPAGE) ) 
			return cis.ciCharset;
		else
			return ANSI_CHARSET;
}

void __cdecl font_table_cleanup(void)
{
	int i;
	for(i=0; i<font_table_size; i++) {
		DeleteObject(font_table[i].hFont);
	}
	font_table_size = 0;
}

