/**
*
* \file Asura_Font_System.h
*
* Created by James Paulin - 18/07/2002 11:41:31
*
* Copyright (C) 2002 Rebellion, All Rights Reserved.
*
* \brief
*
**/
#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif

#ifndef __ASURA_FONT_SYSTEM_H__
#define __ASURA_FONT_SYSTEM_H__

#ifndef ASURA_MAX_FONTS
    #ifdef ASURA_TOOLS
        // Typically have extra tools fonts around.
        #define ASURA_MAX_FONTS (9)
    #else
        #define ASURA_MAX_FONTS (6)
    #endif
#endif

#define ASURA_FONT_SUPPORT_SPACING_HACK

#ifdef ASURA_FONT_SUPPORT_SPACING_HACK
#define ASURA_FONT_PROPORTIONAL_SPACING_CONST 0.4f
#endif

// Stdlib independent.
#include <limits.h>

// Engine independent.
#include "Core/Asura_Handle.h"
// Now we need this for the translucency mode enums
#include "Rendering/Asura_Render.h"

// Engine platform-specific.
#include "Core/Asura_PlatformBasics.h"

class Asura_Bounding_Rectangle;
class Asura_Chunk_Font;
class Asura_Font;

// text between ASURA_FONT_SIZE_SPECIAL_CHAR's these specifies a ratio of current size, which
// applies to the entire line (for language localisation)
const Asura_UnicodeChar ASURA_FONT_SIZE_SPECIAL_CHAR = L'\xE000';

const u_int ASURA_FONT_MAX_FILENAME = 100;

// JP - Bitwise flags for text alignment:
// Set ASURA_TEXTFORMAT_RELATIVEPOSITION flag to use normalized coordinates.

enum ASURA_TEXTFORMAT_ID
{
	ASURA_TEXTFORMAT_DEFAULT					= 0x00000000,
	ASURA_TEXTFORMAT_RELATIVEPOSITION			= 0x00000001,
	ASURA_TEXTFORMAT_LEFTJUSTIFIED				= 0x00000002,
	ASURA_TEXTFORMAT_CENTREJUSTIFIED			= 0x00000004,
	ASURA_TEXTFORMAT_RIGHTJUSTIFIED			 	= 0x00000008,
	ASURA_TEXTFORMAT_CAMERARELATIVEPOSITION 	= 0x00000010,
	ASURA_TEXTFORMAT_VERTICALBOTTOMJUSTIFIED	= 0x00000020,
	ASURA_TEXTFORMAT_VERTICALCENTREJUSTIFIED	= 0x00000040,
	ASURA_TEXTFORMAT_WORDWRAP					= 0x00000080,
    ASURA_TEXTFORMAT_RELATIVETORECT             = 0x00000100,
    ASURA_TEXTFORMAT_CAPITALISED                = 0x00000200,
	ASURA_TEXTFORMAT_DONTRENDER					= 0x00000400,
	ASURA_TEXTFORMAT_FULLYJUSTIFIED				= 0x00000800,
	ASURA_TEXTFORMAT_FORMATSTRING				= 0x00001000,
	ASURA_TEXTFORMAT_DROPSHADOWS				= 0x00002000,
    ASURA_TEXTFORMAT_LIGHTDROPSHADOWS           = 0x00004000,
};

struct Asura_Font_Glyph
{
    enum { INVALID_KERNING_IDX = 0xFFFFu };

	float u; 
	float v;
	float width;
	Asura_UnicodeChar wcThisChar;
    u_short usKerningIndex; // Offset into the array of kerning data.
};

union Asura_Font_KerningData
{
    u_short           usCount;
    Asura_UnicodeChar wFollowingChar;
    short             sKernAmount;
};

struct Asura_Font_Glyph_V2
{
	float u; 
	float v;
	float width;
};

// (EJD - 17.09.2004) Changes to allow non-contiguous characters
class Asura_Font_GlyphPage
{
public:
    Asura_Char	   m_acTextureFileName[ASURA_FONT_MAX_FILENAME];
    int   m_iFontTextureIndex;

	Asura_Font_Glyph* m_pxGlyphArray;   // dynamically allocated array of Glyph data

    Asura_UnicodeChar m_wcRangeMin, m_wcRangeMax;   // inclusive range of Unicode characters described by m_pxGlyphArray (can now have gaps in the range, mainly used to know what page the glyph should be on)

    u_int m_uTexWidth, m_uTexHeight;

	u_int m_uNumChars; // If this matches m_wcRangeMax - m_wcRangeMin + 1 then the page is contiguous and we can speed up the search


    Asura_Font_GlyphPage()
    {
        m_pxGlyphArray = NULL;
    }

    ~Asura_Font_GlyphPage()
    {
        if (m_pxGlyphArray) delete[] m_pxGlyphArray;
    }

};

class Asura_Font_GlyphPage_V2
{
public:
    Asura_Char	   m_acTextureFileName[ASURA_FONT_MAX_FILENAME];
    int   m_iFontTextureIndex;

	Asura_Font_Glyph* m_pxGlyphArray;   // dynamically allocated array of Glyph data

    Asura_UnicodeChar m_wcRangeMin, m_wcRangeMax;   // inclusive range of Unicode characters described by m_pxGlyphArray

    u_int m_uTexWidth, m_uTexHeight;

    Asura_Font_GlyphPage_V2()
    {
        m_pxGlyphArray = NULL;
    }

    ~Asura_Font_GlyphPage_V2()
    {
        if (m_pxGlyphArray) delete[] m_pxGlyphArray;
    }

};

// Asura_Font_Special_Effects

/*
Versions: ASURA_CHUNK_ELEMENT_TEXT_VERSION

0:	Initial data - MxH 8/4/09
*/
#define ASURA_CHUNK_ELEMENT_TEXT_SPECIAL_EFFECTS_VERSION 0

class Asura_Chunk_Stream;

/* 
Class contains the data for the text special effects such as teletype, decryption and cursor rendering 
*/

class Asura_Font_Special_Effects
{
public:

	// When changing this enum update g_apcHorizTeletypeFlagNames[].
	enum TeletypeDir
	{
		ASURA_GUIMENU_TELETYPE_TOP_LEFT,		// Teletype from top left of word wrapped text.
		ASURA_GUIMENU_TELETYPE_TOP_RIGHT,		// Teletype from top right
		ASURA_GUIMENU_TELETYPE_BOTTOM_LEFT,		// Teletype from bottom left
		ASURA_GUIMENU_TELETYPE_BOTTOM_RIGHT,	// Teletype from bottom right

		ASURA_GUIMENU_TELETYPE_SWEEP_LEFT,		// Teletype each line from the left at the same time.
		ASURA_GUIMENU_TELETYPE_SWEEP_RIGHT,		// Teletype each line from the right at the same time.

		ASURA_GUIMENU_TELETYPE_DIR_MAX, // Must be last
	};


	Asura_Font_Special_Effects();
	virtual ~Asura_Font_Special_Effects() {};

	void Copy( const Asura_Font_Special_Effects* pxSource);

	// Start the effect running.
	void Start();
	// Stop the effect.
	void Stop();
	// Update the effect and its timers.
	u_int Update();

	// Is the effect running.
	bool IsRunning() const { return m_bRunning; }

	u_int GetLastFrameNum() const { return m_uLastFrame; }

	// How long does the effect need to run before the text starts to render.
	void SetDelayTime(float fDelayTime) { m_fDelayTime = fDelayTime; }
	float GetDelayTime() const { return m_fDelayTime; }

	// How long has the effect be running
	float GetTime() const { return m_fTime; }

	// Maximum number of chars to render
	u_int GetNumChars() const { return m_uNumChars; }

	// Calculate the age, in seconds, of a character based on its position within the string.
	// If this function return a negative age it indicates the character should not be rendered yet.
	float CalcCharacterAge(u_int uCharPos, // Position within the string,
		u_int uStringLength,  // Length of string
		u_int uLineStartPos, // Char position for start of the current line
		u_int uLineEndPos) const; // Char position for end of the current line

	// Use the age of a character and the alpha fade time calculate the alpha value for a character.
	float GetAlpha(float fCharAge) const;

	// Enable teletyping
	void SetTeletype(bool bEnable) { m_bTeletypeEnabled = bEnable; }
	bool GetTeletype() const { return m_bTeletypeEnabled; }

	// Set how many characters are rendered per second.
	void SetCharsPerSecond(u_int uCharsPerSecond) 
	{ 
		m_uCharsPerSecond = uCharsPerSecond; 
		m_fTimePerChar = 1.0f / static_cast<float>(uCharsPerSecond); 
	}
	u_int GetCharsPerSecond() const { return m_uCharsPerSecond; }

	// Set the direction type of the teletyping effect.
	void SetTeletypeDir(TeletypeDir eTeletypeDir) { m_eTeletypeDir = eTeletypeDir; }
	TeletypeDir GetTeletypeDir() const { return m_eTeletypeDir; }

	// Decyption settings
	void SetDecrypt(bool bEnable) { m_bDecryptEnabled = bEnable; }
	bool GetDecrypt() const { return m_bDecryptEnabled; }

	// How long does it take for a character to decrypt once its been rendered.
	void SetDecryptTime(float fDecryptTime) { m_fDecryptTime = fDecryptTime; }
	float GetDecryptTime() const { return m_fDecryptTime; }

	// How long does an encrypted character render for before changing into another character.
	void SetDecryptChangeCharTime(float fDecryptCharChangeTime) { m_fDecryptChangeCharTime = fDecryptCharChangeTime; }
	float GetDecryptChangeCharTime() const { return m_fDecryptChangeCharTime; }

	// Time it takes for a character to alpha fade
	void SetAlphaFadeTime(float fAlphaFadeTime) { m_fAlphaFadeTime = fAlphaFadeTime; }
	float GetAlphaFadeTime() const { return m_fAlphaFadeTime; }

	// Should a cursor be drawn for the effect
	void SetCursor(bool bEnable) { m_bCursor = bEnable; }
	bool GetCursor() const { return m_bCursor; }

	// If the cursor flash what rate should it flash at.
	void SetCursorFlashTime(float fFlashTime) { m_fCursorFlashTime = fFlashTime; }
	float GetCursorFlashTime() const { return m_fCursorFlashTime; }

	// How long should a cursor be drawn for at the end of a string before it disappears.
	void SetCursorStopTime(float fTime) { m_fCursorStopTime = fTime; }
	float GetCursorStopTime() const { return m_fCursorStopTime; }

#ifdef ASURA_TOOLS
	virtual void				WriteToChunkStream( Asura_Chunk_Stream& xStream) const;
#endif // ASURA_TOOLS

	virtual void				ReadFromChunkStream( Asura_Chunk_Stream& xStream);

private:

	float			m_fTime;			// Age of effect in seconds
	u_int			m_uLastFrame;		// Last frame the effect was updated on.
	bool			m_bRunning;			// Is the effect running.
	float			m_fDelayTime;		// How long should the effect run for before displaying any characters

	// Teletype data
	bool			m_bTeletypeEnabled;	// Enable teletyping effect.
	float			m_fTimePerChar;		// The time in seconds for how long it takes to render a single char
	u_int			m_uCharsPerSecond;	// The number of characters to render per second.
	float			m_fAlphaFadeTime;	// The time it take to fade in the character
	TeletypeDir		m_eTeletypeDir;		// The teletype direction
	u_int			m_uNumChars;		// The maximum number of chars to render based on m_fTimePerChar and m_fTime;

	// Decryption Data
	bool			m_bDecryptEnabled;	// Should the decryption effect be enabled.
	float			m_fDecryptChangeCharTime;	// How long it take to full decrypt a character to render the real one.
	float			m_fDecryptTime;			// How long it takes to change to another random encrypted character.

	bool			m_bCursor;				// Should a cursor be drawn.
	float			m_fCursorFlashTime;		// Should the cursor flash.
	float			m_fCursorStopTime;		// Should the cursor stop rendering after a certain amount of time.
};

class Asura_Font_System
{
	public:

		class Render_Effects_Glyph_Data
		{
		public:
			const Asura_Font* m_pxFont;
			const Asura_UnicodeChar* m_wszString;
			Asura_UnicodeChar m_wCurChar;
			Asura_Bounding_Rectangle m_xClipPixelRect;
			float m_fX;
			float m_fY;
			float m_fScale;
			float m_fGlyphScale;
			u_int m_uFormat;
			const Asura_Font_GlyphPage* m_pxGlyphPage;
			const Asura_Font_Glyph* m_pxThisGlyph;
			u_int m_uColour;
			u_int m_uCharCount;
			u_int m_uStringLength;
			u_int m_uStartLinePos;
			u_int m_uEndLinePos;
			bool  m_bRenderCursor;
			bool  m_bGlyphRequiresProjectRender;
			const Asura_Font_Special_Effects* m_pxSpecialEffectsSettings;
		};

		// Functions for printing at given coordinates
		static void Print(const float x, const float y, const unsigned int colour, const unsigned int format, const Asura_UnicodeChar* string, ...);
		static void Print(const float x, const float y, const unsigned int colour, const unsigned int format, const Asura_Char* string, ...);
		static void Print(const float x, const float y, const float fScale, const unsigned int colour, const unsigned int format, const Asura_UnicodeChar* string, ...);
		static void Print(const float x, const float y, const float fScale, const unsigned int colour, const unsigned int format, const Asura_Char* string, ...);

		// Functions for printing inside a rectangle
		static bool Print(const Asura_Bounding_Rectangle &xRect, const float fXOffset, const float fYOffset, const float fLineSpacing, const float fScale, const unsigned int colour, const unsigned int format, const Asura_Char* string, ...);
		static bool Print(const Asura_Bounding_Rectangle &xRect, const float fXOffset, const float fYOffset, const float fLineSpacing, const float fScale, const unsigned int colour, const unsigned int format, const Asura_UnicodeChar* string, ...);
        
        // LBF: the following doesn't support word wrapping, but doesn't rely on the string
        // fitting into the buffer size (needed for GF2 credits scrolling)
		static bool PrintShortString(const Asura_Char* string, const Asura_Bounding_Rectangle* pxRect, float fXOffset, float fYOffset, 
				float fLineSpacing, float fScale, unsigned int colour, unsigned int format);
        static bool PrintLongString(const Asura_UnicodeChar* string, const Asura_Bounding_Rectangle* pxRect, float fXOffset, float fYOffset, 
            const float fLineSpacing, float fScale, const unsigned int colour, const unsigned int format);

		// Render a string using the special effects settings.
		static bool PrintSpecialEffectsString(const Asura_UnicodeChar* wszString, const Asura_Bounding_Rectangle* pxRect, float fXOffset, float fYOffset, 
			const float fLineSpacing, float fScale, const unsigned int colour, const unsigned int format, const Asura_Font_Special_Effects* pxSpecialEffectsSettings );

		// Default function that supports Teletype, decryption and cursor rendering.
		static bool DefaultRenderSpecialEffects(Render_Effects_Glyph_Data* pxCharData);

		// Function to change the default special effects render function for project specific effects
		static void SetSpecialEffectsCallback(bool (*pfnCallback)(Render_Effects_Glyph_Data* pxCharData))
		{
			s_pfnRenderSpecialEffectCharacterCallback = pfnCallback;
		}

        static bool PrintChar(const Asura_Bounding_Rectangle* pxRect, // in screen coords (NULL if no clipping)
                                  float fStartX,                    // in screen coords
                                  float fStartY,                    // in screen coords
                                  const float fScale, 
                                  const u_int uColour, 
                                  const Asura_Font_Glyph* pxGlyph,
                                  const Asura_Font_GlyphPage* pxGlyphPage );

		// project special glyphs - return NULL for not found, if found, texture data should be in ppxGlyphPage
		static bool Project_PrintChar(const Asura_Bounding_Rectangle* pxRect, // in screen coords (NULL if no clipping)
			const float fStartX,                    // in screen coords
			const float fStartY,                    // in screen coords
			float fScale, 
			const u_int uColour, 
			const Asura_UnicodeChar wcThisChar);

        static const Asura_UnicodeChar* FindSplitPoint(const Asura_UnicodeChar* wszString, float fWidthPixels, float fScale, float& fLineWidth, int& iOutNumWords);

		static void			 SetFont(Asura_Handle fontHandle);
//		static void			 SetFont( const Asura_Char* szName );
		static void			 SetFontScale(Asura_Handle hFontHandle, float fScaleFactor);
        static Asura_Handle  GetFontHandle(const Asura_Char* szName);
		static Asura_Handle  GetFontHandle(const Asura_Hash_ID uFontNameHash);
		static float		 GetFontScale(Asura_Handle iFontHandle);
		static bool          IsFontLoaded(const Asura_Char* szName);
		static bool          IsFontLoaded(const Asura_Hash_ID uFontNameHash);
		static bool			 DoesFontHandleExist(Asura_Handle iFontHandle)	{ return (iFontHandle != ASURA_INVALID_HANDLE) && s_apxFontStorage[iFontHandle]; }
		static Asura_Handle	 GetCurrentFontID(){ return (static_cast<Asura_Handle>(s_iCurrentFontID)); }
		static void			 SetStartGlyph(Asura_Handle fontHandle, int offset);
		static float		 GetFontHeight(void);
        static void			 SetPixelSpacing( float fPixelSpacing )			{ s_fPixelSpacing = fPixelSpacing; }
        
		static void Initialise();
		static void Shutdown();
		static void Reset();

        static float GetWidthOfChar( Asura_Char cChar, float fScale = 1.0f );
        static float GetWidthOfChar( Asura_UnicodeChar wChar, float fScale = 1.0f );
        static float GetWidthOfString( const Asura_Char* szStr, float fScale = 1.0f, u_int uNumCharsToCount = UINT_MAX );
        static float GetWidthOfString( const Asura_UnicodeChar* wszStr, float fScale = 1.0f, u_int uNumCharsToCount = UINT_MAX );
		
		// function to get total height of text when rendered in the clip rectangle
		// Useful for dealing with scrollbars
		static float GetHeightOfText( const Asura_UnicodeChar*  pcString,           // The text
									  const Asura_Bounding_Rectangle* pxClipRect,	// The rectangle the text should be clipped to (NULL if full screen)
									  const float fLineSpacing,					    // Line spacing mulitplier
									  float fScale,							        // Scale size for the font when it's drawn
									  const u_int uFormat );						// Text formating flags see Asura_Font_System.h
		static float GetWidthOfText( const Asura_UnicodeChar* wszString,			// The text
									 const Asura_Bounding_Rectangle* pxClipRect,	// The rectangle the text should be clipped to (NULL if full screen)
									 float fScale,							        // Scale size for the font when it's drawn
									 const u_int uFormat );							// Text formating flags see Asura_Font_System.h

	    static bool StoreFontDetails(Asura_Font* newFont); //called by chunk loader
        static bool StoreKerningData( Asura_Font_KerningData* pxKerningData, u_int uNumEntries );
        static const Asura_Font* GetFont( Asura_Handle iFontHandle ) { return s_apxFontStorage[iFontHandle]; }
        static void DestroyFont( Asura_Handle iFontHandle );

		// (PSJE) - Stores the Y coordinate of the next line after the last line of text was printed
		// I've added this, so dredd can use a large text rectangle for each objective, and know where it finished printing,
		// and where to start the next objective printing.
        // (MP - 15.10.2005) Return values should not be relied upon if
        // PrintLongString() returns false (ie. reports that it did not print
        // anything.)
		static float GetNextLinesYCoordinate()		{	return (s_fLastPrintedYHeight);	}
		static float GetLastPrintedXCoordinate()    {   return s_fLastPrintedXCoord; }
		static float GetMaxPrintedXCoordinate()		{	return s_fMaxPrintedXCoord; }

		// SNH: enable / disable font squishing
		static void SetUsePlatformYScaleFactor(bool bUse)			{ s_bUsePlatformYScaleFactor = bUse; }

#ifdef ASURA_FONT_SUPPORT_SPACING_HACK
		static void SetCharacterPixelSpacing(float fPixelsBetweenChars) { s_fPixelSpacing = fPixelsBetweenChars; }
		static float GetCharacterPixelSpacing() { return s_fPixelSpacing; }

		static void SetCharacterProportionalSpacing(float fProportionalSpaceBetweenChars) { s_fProportionalSpacing = fProportionalSpaceBetweenChars; }
		static float GetCharacterProportionalSpacing() { return s_fProportionalSpacing; }
#endif

		// Returns previous translucency mode
		static ASURA_TRANSLUCENCY_MODE SetTranslucencyMode( ASURA_TRANSLUCENCY_MODE eNewMode );  

        static void DoUnitTests( void );

		static u_int s_uStringColour;	 // Current Character colour (can be modified through special chars tags)
		static u_int s_uCharacterColour; // Current Character colour (can be modified through special chars tags)

		static u_int s_uCharacterFormat;// copy of the current character format, since it;s not passed into function PrintChar
		static float s_fShadowOffsetX;	// shadow offset
		static float s_fShadowOffsetY;	// shadow offset
		
	private:

        // Should return spacing required to following the specified
        // character, possibly relative to the one that's following.
        static float GetCharSpacing( Asura_UnicodeChar wChar, Asura_UnicodeChar wNextChar, float fScale );
        static float Project_GetCharSpacing( Asura_UnicodeChar wChar, Asura_UnicodeChar wNextChar, float fScale );

		// function to get scale that may be set inside the text (e.g. to use smaller
		// scale for text in some languages).
		static float GetInlinedScaleFactor(const Asura_UnicodeChar* pcString);
		
		// utility function to convert normalised coords to pixels
		static void GetPixelClipRectAndScaleOffsets(Asura_Bounding_Rectangle& xClipPixelRect,	// output
													float& fXOffset,							// output
													float& fYOffset,							// output
													const Asura_Bounding_Rectangle* pxClipRect, // input
													const u_int uFormat);						// input

		//  AAB:  (03/09/2004 10:09:21):  The following two functions are necessary because
		// their internal use within Asura_Font_System implies that they must be unscaled,
		// but their public versions are called from elsewhere, requiring them to be scaled
		// with the font scale factor.
		static float GetWidthOfChar_Unscaled( Asura_UnicodeChar wChar, float fScale = 1.0f );
		static const Asura_UnicodeChar* FindSplitPoint_Unscaled( const Asura_UnicodeChar* wszString,
                                                                 float fWidthPixels,
                                                                 float fScale,
                                                                 float* pfLineWidth,
                                                                 int* piNumWordsInLine,
                                                                 bool* pbNeedHyphen );

		// private utility functions to find width/height of text
        static float GetTextHeight( const Asura_UnicodeChar* pcString, 
									const u_int uFormat, 
									const float fCharacterHeight, 
									const float fRectWidthPixels,
									const float fScale, 
									const float fLineHeight );
        static float GetTextWidth ( const Asura_UnicodeChar* wszString,
                                    const u_int uFormat,
                                    const float fRectWidthPixels,
                                    const float fScale );

		//Private function to get Y scaling (to account for aspect ratio- ==1 on 
		//	everything other than the PS2)
		//	SNH: don't need to call this if s_bUsePlatformYScaleFactor is false
		static float GetPlatformYScaleFactor(void);

        static int FindFontInternal( const char* szName );
		static int FindFontInternal( const Asura_Hash_ID uFontNameHash);

		static int s_iCurrentFontID;
		static int ConsoleRemoveFont(int iIn, bool bHelp, bool binterrogate);
		static Asura_Font* s_apxFontStorage[ASURA_MAX_FONTS];
		static bool s_bAnyFontHasLoaded;
		static float s_fPixelSpacing;
		static float s_fProportionalSpacing;
		// (PSJE) - Stores the Y coordinate of the next line after the last line of text was printed
		// I've added this, so dredd can use a large text rectangle for each objective, and know where it finished printing,
		// and where to start the next objective printing
		static float s_fLastPrintedYHeight;
		static float s_fLastPrintedXCoord;
		static float s_fMaxPrintedXCoord;

	    // Project-specific functions
        static void Project_Initialise();
        static void Project_Shutdown();

		// AJG - 28/01/04 - Added to allow projects to mess about with char widths if they feel the scale is going to make their
		// character too small/big (or if they just want to make it a particular size all the time, or whatever).
		static float Project_GetWidthOfChar(Asura_UnicodeChar wcChar, float fScale);

		static inline bool IsRomajiCharacter(Asura_UnicodeChar wcChar)
		{
			// (AW - 19/1/06) - Helper function to assist decision of where to put line-breaks in Japanese. Return
			// true if we've hit a latin or romaji set character. Only tests for a-z 0-9, perhaps needs to be more inclusive.
			return ((wcChar >= 0x0041 && wcChar <= 0x005a) ||		// A - Z standard ASCII
				    (wcChar >= 0x0061 && wcChar <= 0x007a) ||		// a - z standard ASCII
				    (wcChar >= 0x0030 && wcChar <= 0x0039) ||		// 0 - 9 standard ASCII
					(wcChar >= 0xff21 && wcChar <= 0xff3a) ||		// A - Z 'proper' Romaji unicode range
					(wcChar >= 0xff41 && wcChar <= 0xff5a) ||		// a - z 'proper' Romaji unicode range
					(wcChar >= 0xff10 && wcChar <= 0xff19));		// 0 - 9 'proper' Romaji unicode range
		}

		static bool s_bNextGlyphRequiresProjectRender;
		
		// SNH: since RT is using pre-squished fonts we don't need to call GetPlatformYScaleFactor()
		//	Skip the call if this is false. Defaults to true == previous behaviour
		static bool s_bUsePlatformYScaleFactor;

        static ASURA_TRANSLUCENCY_MODE s_eTranslucencyMode;

		// call back to call when rendering special effects characters
		static bool (*s_pfnRenderSpecialEffectCharacterCallback)(Asura_Font_System::Render_Effects_Glyph_Data* pxCharData);

	public:
        static const Asura_Font_Glyph* Project_GetGlyphData(Asura_UnicodeChar wcThisChar, u_int uFormat = ASURA_TEXTFORMAT_DEFAULT, 
            const Asura_Font_GlyphPage** ppxGlyphPage = NULL);

        static Asura_UnicodeChar Project_GetUnsupportedGlyphReplacementCharacter();
};


class Asura_Font
{

	public:

		int FillFontData( Asura_Font* newFont );

        const Asura_Font_Glyph* GetGlyphData(Asura_UnicodeChar wcThisChar, u_int uFormat = ASURA_TEXTFORMAT_DEFAULT, 
            const Asura_Font_GlyphPage** ppxGlyphPage = NULL) const;
		float GetFontHeight() const;

		//Items contained in chunk header	
		float m_fFontHeight;

		// A font may be required to hold glyphs from a wide 
		// range of unicode characters. We therefore catalogue the 
		// glyphs according to 'pages', which define a contiguous 
        // range of characters stored in a single texture.

		Asura_Font_GlyphPage* m_pxGlyphPages; // dynamically allocated and in ascending order.

        u_int m_uNumGlyphPages; // size of the above array
        
        // store a filename as a unique identifier
        Asura_Char	   m_szFileName[ASURA_FONT_MAX_FILENAME];

		// Scale factor to be applied to all instances of this font.
		// This is to facilitate swapping fonts.
		float m_fFontScale;

        // For every character that requires kerning relative to some other
        // following characters, this array contains:
        // (count, other char, kern amount, other char, kern amount, ...)
        Asura_Font_KerningData* m_pxKerningData;
#ifdef ASURA_ASSERT
        u_int m_uNumKerningDataEntries;
#endif

    private:

        friend class Asura_Chunk_Font;
        friend class Asura_Font_System;
#ifdef _FONTMAKER
        friend bool WriteFontFiles( HDC hDC );
#endif

		Asura_Font( void );
		~Asura_Font( void );
        
};




#endif//__ASURA_FONT_SYSTEM_H__
