#include "stdafx.h"
#include "fontagent.h"

#include "FontObject.h"
#include "RenderSystem.h"

#include "D3DXFont.h"
#include "CacheFont.h"

#include "ObjectNameCard.h"

cFontAgent* cFontAgent::mpFontAgent = NULL;

cFontAgent::cFontAgent()
{
	mpFontAgent = this;

	mFontArray.Reserve( eFont_Max );
}

cFontAgent::~cFontAgent()
{
}

/* ------------------------------------------------------------------
 * 함수이름 :	
 * 목    적 :	
 * 주의사항 :	
 * ------------------------------------------------------------------ */
bool cFontAgent::Init()
{
	sCacheInfo info;

	/// UI용 폰트 ( UI용, 고정 SystemMsg )
	cFontObject* pFont = new cCacheFont;
	if( !pFont )
		return false;

	info.texNum = 2;
	pFont->CreateFont( RENDERSYS->GetHWND(), NULL, info );
	mFontArray.PushBack( pFont );

	/// UI용 폰트 ( UI용, 고정 SystemMsg ) BOLD
	pFont = new cCacheFont;
	if( !pFont )
		return false;

	LOGFONT		font;
	font.lfHeight = -12;
	font.lfWidth = 0;//-font.lfHeight / 2;
	font.lfEscapement = 0;
	font.lfOrientation = 0;
	font.lfWeight = FW_BOLD;
	font.lfItalic = 0;
	font.lfUnderline = 0;
	font.lfStrikeOut = 0;
	font.lfCharSet = DEFAULT_CHARSET;
	font.lfOutPrecision = OUT_OUTLINE_PRECIS;
	font.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	font.lfQuality =  PROOF_QUALITY;
	font.lfPitchAndFamily = FF_SWISS;
	::lstrcpy( font.lfFaceName, _T("굴림체") );

	info.texNum = 2;
	pFont->CreateFont( RENDERSYS->GetHWND(), &font, info );
	mFontArray.PushBack( pFont );

	/// 시스템 폰트 (Tooltip, Name, GameInfo, 유동SystemMsg)
	pFont = new cCacheFont;
	if( !pFont )
		return false;

	info.texNum = 2;
	pFont->CreateFont( RENDERSYS->GetHWND(), NULL, info );
	mFontArray.PushBack( pFont );

	/// 채팅용
	pFont = new cCacheFont;
	if( !pFont )
		return false;

	info.texNum = 2;
	pFont->CreateFont( RENDERSYS->GetHWND(), NULL, info );
	mFontArray.PushBack( pFont );

	/// 공지용
	pFont = new cCacheFont;
	if( !pFont )
		return false;

	font.lfHeight = -18;
	font.lfWidth = 0;//-font.lfHeight / 2;
	font.lfEscapement = 0;
	font.lfOrientation = 0;
	font.lfWeight = FW_BOLD;
	font.lfItalic = 0;
	font.lfUnderline = 0;
	font.lfStrikeOut = 0;
	font.lfCharSet = DEFAULT_CHARSET;
	font.lfOutPrecision = OUT_OUTLINE_PRECIS;
	font.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	font.lfQuality =  PROOF_QUALITY;
	font.lfPitchAndFamily = FF_SWISS;
	::lstrcpy( font.lfFaceName, _T("굴림체") );

	info.texNum = 1;
	pFont->CreateFont( RENDERSYS->GetHWND(), &font, info );
	mFontArray.PushBack( pFont );

	/// 깊이가 있는 면에 그려질 폰트용
	pFont = new cCacheFont;
	if( !pFont )
		return false;

	info.texNum = 2;

	font.lfHeight = -12;
	font.lfWidth = 0;//-font.lfHeight / 2;
	font.lfEscapement = 0;
	font.lfOrientation = 0;
	font.lfWeight = FW_NORMAL;
	font.lfItalic = 0;
	font.lfUnderline = 0;
	font.lfStrikeOut = 0;

	font.lfCharSet = DEFAULT_CHARSET;
	font.lfOutPrecision = OUT_OUTLINE_PRECIS;
	font.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	font.lfQuality =  PROOF_QUALITY;
	font.lfPitchAndFamily = FF_SWISS;
	::lstrcpy( font.lfFaceName, _T("굴림체") );

	pFont->CreateFont( RENDERSYS->GetHWND(), &font, info );
	pFont->SetAlpha( false );
	mFontArray.PushBack( pFont );

	pFont = new cCacheFont;
	if( !pFont )
		return false;

	info.texNum = 1;
	pFont->CreateFont( RENDERSYS->GetHWND(), &font, info );
	mFontArray.PushBack( pFont );

	return true;
}

/* ------------------------------------------------------------------
* 함수이름 :	cFontAgent::Exit()
* 목    적 :	종료부
* 주의사항 :	
* ------------------------------------------------------------------ */
void cFontAgent::Exit()
{
	if( mFontArray.GetSize() )
	{
		for( unsigned int i=0; i<mFontArray.GetSize(); i++ )
		{
			cFontObject* pFont = (cFontObject*)mFontArray[i];
			if( pFont )
			{
				SAFE_DELETE(pFont);
			}
		}
		mFontArray.Clear();

	}
}

/* ------------------------------------------------------------------
 * 함수이름 :	cFontAgent::Invalidate()
 * 목    적 :	장치 소실시 유효하지 않은 메모리 해제
 * 주의사항 :	
 * ------------------------------------------------------------------ */
void cFontAgent::Invalidate()
{
	for( unsigned int i=0; i<eFont_Max; i++ )
	{
		cFontObject* pFont = (cFontObject*)mFontArray[i];
		if( pFont )
		{
			pFont->Invalidate();
		}
	}
}

/* ------------------------------------------------------------------
 * 함수이름 :	cFontAgent::Restore()
 * 목    적 :	장치 소실시 유효하지 않은 메모리 재생성
 * 주의사항 :	
 * ------------------------------------------------------------------ */
void cFontAgent::Restore()
{
	for( unsigned int i=0; i<eFont_Max; i++ )
	{
		cFontObject* pFont = (cFontObject*)mFontArray[i];
		if( pFont )
		{
			pFont->Restore();
		}
	}
}

/* ------------------------------------------------------------------
* 함수이름 :	
* 목    적 :	
* 주의사항 :	
* ------------------------------------------------------------------ */
void cFontAgent::DrawText( unsigned short fontIdx, LPTSTR text, int textLen, unsigned int posX, unsigned int posY, unsigned long textColor, bool useBack, unsigned long backColor )
{
	POINT ps;
	ps.x = (LONG)posX;
	ps.y = (LONG)posY;
	DrawText( fontIdx, text, textLen, &ps, textColor, useBack, backColor );
}

void cFontAgent::DrawText( unsigned short fontIdx, LPTSTR text, int textLen, POINT* textPos, unsigned long textColor, bool useBack, unsigned long backColor )
{
	/// 예외 처리
	if( fontIdx >= eFont_Max )
		return;

	if( textPos->x<0 || textPos->y<0 )
		return;

	if( textPos->x >= (int)RENDERSYS->GetScreenWidth() ||  textPos->y >= (int)RENDERSYS->GetScreenHeight() )
		return;

	cFontObject* pFont = (cFontObject*)mFontArray[fontIdx];
	if( pFont == NULL )
	{
		return;
	}

	if( textLen == -1 )
	{
		textLen = ::_tcslen( text );
	}

	if( textLen == 0 )
	{
		return;
	}

	/// 그려질 영역 계산
	RECT rect = { textPos->x, textPos->y, 0, 0 };
	rect.right = rect.left + GetTextExtent( fontIdx, text, textLen ) + GetTextWidth( fontIdx ) / 4;
	rect.bottom = rect.top + GetTextHeight( fontIdx );

	/// 영역이 화면 밖이면 
	if( rect.right < 0 || rect.bottom < 0 )
		return;
	if( rect.right > (LONG)RENDERSYS->GetScreenWidth() || rect.bottom  > (LONG)RENDERSYS->GetScreenHeight() )
		return;

	/// 뒷배경
//	if( useBack )
//	{
/*
		cFontObject* pBackFont = (cFontObject*)mFontArray[fontIdx];
		RECT br = rect;
		br.left = rect.left+1;
		br.right = rect.right+1;
		br.top = rect.top;
		br.bottom = rect.bottom;
		pBackFont->DrawText( text, textLen, &br, backColor );

		br.left = rect.left-1;
		br.right = rect.right-1;
		br.top = rect.top;
		br.bottom = rect.bottom;
		pBackFont->DrawText( text, textLen, &br, backColor );

		br.left = rect.left;
		br.right = rect.right;
		br.top = rect.top+1;
		br.bottom = rect.bottom+1;
		pBackFont->DrawText( text, textLen, &br, backColor );

		br.left = rect.left;
		br.right = rect.right;
		br.top = rect.top-1;
		br.bottom = rect.bottom-1;
		pBackFont->DrawText( text, textLen, &br, backColor );

		br.left = rect.left+1;
		br.right = rect.right+1;
		br.top = rect.top+1;
		br.bottom = rect.bottom+1;
		pBackFont->DrawText( text, textLen, &br, backColor );

		br.left = rect.left+1;
		br.right = rect.right+1;
		br.top = rect.top-1;
		br.bottom = rect.bottom-1;
		pBackFont->DrawText( text, textLen, &br, backColor );

		br.left = rect.left-1;
		br.right = rect.right-1;
		br.top = rect.top+1;
		br.bottom = rect.bottom+1;
		pBackFont->DrawText( text, textLen, &br, backColor );

		br.left = rect.left-1;
		br.right = rect.right-1;
		br.top = rect.top-1;
		br.bottom = rect.bottom-1;
		pBackFont->DrawText( text, textLen, &br, backColor );
*/
//	}
//	else
//	{
		cFontObject* pBackFont = (cFontObject*)mFontArray[fontIdx];
		RECT br = rect;
		br.left = rect.left+1;
		br.right = rect.right+1;
		br.top = rect.top;
		br.bottom = rect.bottom;
		pBackFont->DrawText( text, textLen, &br, backColor );

		br.left = rect.left;
		br.right = rect.right;
		br.top = rect.top+1;
		br.bottom = rect.bottom+1;
		pBackFont->DrawText( text, textLen, &br, backColor );

		br.left = rect.left+1;
		br.right = rect.right+1;
		br.top = rect.top+1;
		br.bottom = rect.bottom+1;
		pBackFont->DrawText( text, textLen, &br, backColor );
//	}

	/// 텍스트 등록..
	pFont->DrawText( text, textLen, &rect, textColor );
}

/* ------------------------------------------------------------------
 * 함수이름 :	GetTextExtent( unsigned short fontIdx, char* text, unsigned int textLen )
 * 목    적 :	UI에서 문자열의 길이를 알고자 할때 사용한다.
 * 주의사항 :	
 * ------------------------------------------------------------------ */
long cFontAgent::GetTextExtent( unsigned short fontIdx, LPCTSTR text, unsigned int textLen )
{
	cFontObject* pFont = (cFontObject*)mFontArray[fontIdx];
	if( !pFont ) 
	{
		return 0;
	}

	return pFont->GetTextExtent( RENDERSYS->GetHWND(), text, textLen);
}

/* ------------------------------------------------------------------
 * 함수이름 :	GetTextWidth( unsigned short fontIdx )
 * 목    적 :	글꼴에서 문자의 평균 너비를 반환
 * 주의사항 :	
 * ------------------------------------------------------------------ */
long cFontAgent::GetTextWidth( unsigned short fontIdx )
{
	cFontObject* pFont = (cFontObject*)mFontArray[fontIdx];
	if( !pFont ) 
	{
		return 0;
	}

	return pFont->GetTextWidth();
}

/* ------------------------------------------------------------------
 * 함수이름 :	GetTextHeight( unsigned short fontIdx )
 * 목    적 :	문자 셀 또는 글꼴 문자의 높이를 반환
 * 주의사항 :	
 * ------------------------------------------------------------------ */
long cFontAgent::GetTextHeight( unsigned short fontIdx )
{
	cFontObject* pFont = (cFontObject*)mFontArray[fontIdx];
	if( !pFont ) 
	{
		return 0;
	}

	/// 1은 밑줄 표시를 위해서 더해준다.
	return pFont->GetTextHeight() + 1;
}