// Static.cpp : Implementation of cStatic
#include "stdafx.h"
#include "DecalControls.h"
#include "Static.h"

/////////////////////////////////////////////////////////////////////////////
// cStatic


STDMETHODIMP cStatic::get_Font(IFontCacheDisp **pVal)
{
   _ASSERTE( pVal != NULL );

   if( m_pFont.p == NULL )
      *pVal = NULL;
   else
      m_pFont->QueryInterface( pVal );

	return S_OK;
}

STDMETHODIMP cStatic::putref_Font(IFontCacheDisp *newVal)
{
   _ASSERTE( newVal != NULL );

   if( m_pFont.p )
      m_pFont.Release();

   HRESULT hRes = newVal->QueryInterface( &m_pFont );

   _ASSERTE( SUCCEEDED( hRes ) );
   m_pSite->Invalidate();

	return S_OK;
}

STDMETHODIMP cStatic::get_Text(BSTR *pVal)
{
   _ASSERTE( pVal != NULL );

   *pVal = OLE2BSTR( m_strText );

	return S_OK;
}

STDMETHODIMP cStatic::put_Text(BSTR newVal)
{
   _ASSERTE( newVal != NULL );

   m_strText = newVal;
   m_pSite->Invalidate();

	return S_OK;
}

STDMETHODIMP cStatic::SchemaLoad(IView *pView, IUnknown *pSchema)
{
	CComPtr< IPluginSite > pPlugin;
	m_pSite->get_PluginSite( &pPlugin );

	pPlugin->CreateFontSchema( 14, 0, pSchema, &m_pFont );

	MSXML::IXMLDOMElementPtr pElement = pSchema;

	_variant_t vText = pElement->getAttribute( _T( "text" ) ),
	vTextColor = pElement->getAttribute( _T( "textcolor" ) ), 
	vWidth = pElement->getAttribute( _T( "width" ) ), 
	vHeight = pElement->getAttribute( _T( "height" ) ),
	vJustify = pElement->getAttribute( _T( "justify" ) ),
	vOutline = pElement->getAttribute( _T( "outlinecolor" ) ),
	vAntialias = pElement->getAttribute( _T( "aa" ) );

	// This is a required element
	_ASSERTE( vText.vt == VT_BSTR );

	// Store the text, assume left justification
	m_strText = vText.bstrVal;
	m_eJustify = eFontLeft;

	// Determine the proper justification
	if (vJustify.vt != VT_NULL)
	{
		_bstr_t bstrJustify = vJustify.bstrVal;
		if (::_wcsicmp(L"left", bstrJustify) == 0)
		{
			m_eJustify = eFontLeft;
		}
		else if (::_wcsicmp(L"right", bstrJustify) == 0)
		{
			m_eJustify = eFontRight;
		}
		else if (::_wcsicmp(L"center", bstrJustify) == 0)
		{
			m_eJustify = eFontCenter;
		}
	}

	// Determine the color
	if( vTextColor.vt != VT_NULL )
	{
		try
		{
			m_nTextColor = static_cast< long >( vTextColor );
		}
		catch( ... )
		{
			// Type conversion error
			_ASSERTE( FALSE );
		}
	}

	m_nOutlineColor = 0;
	m_bOutline = false;
	if( vOutline.vt != VT_NULL )
	{
		try
		{
			m_bOutline = true;
			m_nOutlineColor = static_cast< long >( vOutline );
		}
		catch( ... )
		{
			// Type conversion error
			_ASSERTE( FALSE );
		}
	}

	m_bAA = true;
	if( vAntialias.vt != VT_NULL )
	{
		try
		{
			m_bAA = static_cast< bool >( vAntialias );
		}
		catch( ... )
		{
			// Type conversion error
			_ASSERTE( FALSE );
		}
	}


	/*
	// Set the width of the static (not same as text width)
	if( vWidth.vt != VT_NULL )
	{
		try
		{
			m_nWidth = static_cast< long >( vWidth );
		}
		catch( ... )
		{
			// Type conversion error
			_ASSERTE( FALSE );
		}
	}

	// Set the height of the static (not same as text height or fontsize)
	if( vHeight.vt != VT_NULL )
	{
		try
		{
			m_nHeight = static_cast< long >( vHeight );
		}
		catch( ... )
		{
			// Type conversion error
			_ASSERTE( FALSE );
		}
	}
	*/

	return S_OK;
}

STDMETHODIMP cStatic::Render( ICanvas *pCanvas )
{
   if( m_pFont.p == NULL )
   {
      // Create the default font
      CComPtr< IPluginSite > pPlugin;
      m_pSite->get_PluginSite( &pPlugin );

	  BSTR bstrFontName;
	  pPlugin->get_FontName(&bstrFontName);
      pPlugin->CreateFont( bstrFontName /*_bstr_t( _T( "Times New Roman" ) )*/, 14, 0, &m_pFont );
   }

    SIZE   Size;
	char  *token;
	POINT  ptText = { 0, 0 };

	//_bstr_t strText= m_strText.copy();
	//_bstr_t temp=_bstr_t("");

	// Determine control size
	RECT rcPos;
	m_pSite->get_Position(&rcPos);
	int nWidth = rcPos.right - rcPos.left;
	int nHeight = rcPos.bottom - rcPos.top;

	// Copy the string for parsing
	std::string strText((const char *) m_strText);

	// Determine line height
	m_pFont->MeasureText(_bstr_t(strText.data()), &Size);
	int height = Size.cy;

	// Break it into lines (can't use strtok or we miss blank lines)
	std::vector<_bstr_t> lines;
	int                  nStart = 0, nEnd;
	bool                 bDone = false;
	while (!bDone)
	{
		// Get the next CR
		nEnd = strText.find("\n", nStart);
		if (nEnd == std::string::npos)
		{
			bDone = true;
			nEnd = strText.length();
		}

		// Store the line
		lines.push_back(strText.substr(nStart, nEnd - nStart).data());

		// Move one character beyond
		nStart = nEnd + 1;
	}

	// Loop through the lines
	_bstr_t bstrSpace(" "), bstrEmpty("");
	int     nIndex, nLines = lines.size();
	for (nIndex = 0, bDone = false; !bDone && (nIndex < nLines); nIndex++)
	{
		// Copy the line for parsing
		_bstr_t strLine((const char *) lines[nIndex]);

		// Line to be built
		_bstr_t strOut = bstrEmpty;

		// Loop through the "words" on the line
		for (token = ::strtok((char *) strLine, " "); !bDone && (token != NULL); token = ::strtok(NULL, " "))
		{
			_bstr_t bstrToken(token);

			// Measure this token
			m_pFont->MeasureText(strOut + bstrToken, &Size);

			// Is this line full???
			if (Size.cx > nWidth)
			{
				DrawText(&ptText, strOut, pCanvas);
				ptText.y += height;

				// Does the next line put us over the top
				bDone = ((ptText.y + height) > nHeight) ? true : false;

				// Clear the line
				strOut = bstrEmpty;
			}

			// Store the token
			strOut += bstrToken + bstrSpace;
		}

		// Draw as needed
		if (!bDone) 
		{
			DrawText(&ptText, strOut, pCanvas);
			ptText.y += height;
		}

		// Does the next line put us over the top
		bDone = ((ptText.y + height) > nHeight) ? true : false;
	}

	/*
	if(Size.cx > nWidth)
	{
		for( token = ::strtok( (char*)strText, " " ); token !=NULL; token = ::strtok( NULL, " " ) )
		{
			m_pFont->MeasureText(temp + _bstr_t(token), &Size);

			if(Size.cx > nWidth)
			{
				DrawText( &ptText, temp, pCanvas );
				ptText.y+=height;//14;
				if(ptText.y+height>nHeight)
					return S_OK;
				temp = _bstr_t(token) + _bstr_t(" ");
			}
			else
				temp += _bstr_t(token) + _bstr_t(" ");
		}

		DrawText( &ptText, temp, pCanvas );

	}
	else
	{
		DrawText( &ptText, strText, pCanvas );
	}
	*/

   return S_OK;
}

STDMETHODIMP cStatic::get_TextColor(long *pVal)
{
   _ASSERTE( pVal != NULL );

   *pVal = m_nTextColor;

	return S_OK;
}

STDMETHODIMP cStatic::put_TextColor(long newVal)
{
   _ASSERTE( ( newVal & 0xFF000000L ) == 0 );

   m_nTextColor = newVal;
   m_pSite->Invalidate();

	return S_OK;
}

void cStatic::DrawText(LPPOINT ppt, BSTR szText, ICanvas *pCanvas)
{
	POINT pt = *ppt;

	RECT rcPos;
	m_pSite->get_Position(&rcPos);
	int nWidth = rcPos.right - rcPos.left;
	int nHeight = rcPos.bottom - rcPos.top;

	// Act based on justification style
	switch (m_eJustify)
	{
	case eFontRight:
		{
			SIZE Size;
			m_pFont->MeasureText(szText, &Size);
			pt.x = nWidth - Size.cx;
		}
		break;

	case eFontCenter:
		{
			SIZE Size;
			m_pFont->MeasureText(szText, &Size);
			pt.x = (nWidth / 2) - (Size.cx / 2);
		}
		break;

	case eFontLeft:
	default:
		{
			// No-Op
		}
		break;
	}

	long lFlags = 0;

	if( m_bAA )
		lFlags |= eAA;

	if( m_bOutline )
		lFlags |= eOutlined;

	m_pFont->DrawTextEx( &pt, szText, m_nTextColor, m_nOutlineColor, lFlags, pCanvas );
}
