// Progress.cpp : Implementation of cProgress
#include "stdafx.h"
#include "DecalControls.h"
#include "Progress.h"
#include <sstream>

/////////////////////////////////////////////////////////////////////////////
// cProgress


STDMETHODIMP cProgress::get_Value(long *pVal)
{
	_ASSERTE( pVal );
	*pVal = m_nProgress;

	return S_OK;
}

STDMETHODIMP cProgress::put_Value(long newVal)
{
	_ASSERTE( newVal <= m_nMaxProgress );
	m_nProgress = newVal;
	m_pSite->Invalidate();
	m_pSite->Reformat();

	return S_OK;
}

STDMETHODIMP cProgress::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 vValue = pElement->getAttribute(_T("value"));
	_variant_t vMaxValue = pElement->getAttribute(_T("max"));
	_variant_t vFaceColor = pElement->getAttribute(_T("facecolor"));
	_variant_t vFillColor = pElement->getAttribute(_T("fillcolor"));
	_variant_t vTextColor = pElement->getAttribute(_T("textcolor"));
	_variant_t vBorderColor = pElement->getAttribute(_T("bordercolor"));
	_variant_t vPreText = pElement->getAttribute(_T("pretext"));
	_variant_t vPostText = pElement->getAttribute(_T("posttext"));
	_variant_t vAlignment = pElement->getAttribute(_T("align"));
	_variant_t vDrawText = pElement->getAttribute(_T("drawtext"));
	_variant_t vBorderWidth = pElement->getAttribute(_T("border"));

   // This is a required element
   _ASSERTE( vValue.vt == VT_I4 || vValue.vt == VT_I2 );
   m_nProgress = vValue;

   if( vMaxValue.vt != VT_NULL )
   {
      try
      {
         m_nMaxProgress = static_cast< long >(vMaxValue);
      }
      catch( ... )
      {
         // Type conversion error
         _ASSERTE( FALSE );
      }
   }

   if( vFaceColor.vt != VT_NULL )
   {
      try
      {
         m_nFaceColor = static_cast< long >(vFaceColor);
      }
      catch( ... )
      {
         // Type conversion error
         _ASSERTE( FALSE );
      }
   }

   if( vFillColor.vt != VT_NULL )
   {
      try
      {
         m_nFillColor = static_cast< long >(vFillColor);
      }
      catch( ... )
      {
         // Type conversion error
         _ASSERTE( FALSE );
      }
   }

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

   if( vBorderColor.vt != VT_NULL )
   {
      try
      {
         m_nBorderColor = static_cast< long >(vBorderColor);
      }
      catch( ... )
      {
         // Type conversion error
         _ASSERTE( FALSE );
      }
   }

	if (vPreText.vt == VT_BSTR)
		put_PreText(vPreText.bstrVal);

	if (vPostText.vt == VT_BSTR)
		put_PostText(vPostText.bstrVal);

	if (vAlignment.vt == VT_BSTR)
		put_Alignment(vAlignment.bstrVal);

   if( vDrawText.vt != VT_NULL )
   {
      try
      {
         m_nDrawText = static_cast< long >(vDrawText);
      }
      catch( ... )
      {
         // Type conversion error
         _ASSERTE( FALSE );
      }
   }

   if( vBorderWidth.vt != VT_NULL )
   {
      try
      {
         m_nBorderWidth = static_cast< long >(vBorderWidth);
      }
      catch( ... )
      {
         // Type conversion error
         _ASSERTE( FALSE );
      }
   }

   return S_OK;
}

STDMETHODIMP cProgress::Reformat()
{
   if (!m_pFont.p)
   {
      // No font was specified, 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);
   }

	// build string
	std::stringstream strText;
	strText << m_strPre << m_nProgress << m_strPost;
	m_bstrText = strText.str().c_str();

   RECT rc;
   m_pSite->get_Position(&rc);

   SIZE szText;
   m_pFont->MeasureText(m_bstrText, &szText);

	// align vertically center
	m_ptText.y = ((rc.bottom - rc.top) - szText.cy) / 2;

	// align left
	if (m_nAlignment == 0)
		m_ptText.x = m_nBorderWidth + 1;

	// align center
	if (m_nAlignment == 1)
		m_ptText.x = ((rc.right - rc.left) - szText.cx) / 2;

	// align right
	if (m_nAlignment == 2)
		m_ptText.x = ((rc.right - szText.cx) - m_nBorderWidth) - 6;

	return S_OK;
}

STDMETHODIMP cProgress::Render(ICanvas *pCanvas)
{
   _ASSERTE( pCanvas != NULL );
   _ASSERTE( m_pSite.p != NULL );

   RECT rcPos;
   m_pSite->get_Position(&rcPos);

   RECT rcClient = { 0, 0, rcPos.right - rcPos.left, rcPos.bottom - rcPos.top };
	RECT rcCenter = { m_nBorderWidth, m_nBorderWidth, 
		(rcPos.right - rcPos.left) - m_nBorderWidth,
		(rcPos.bottom - rcPos.top) - m_nBorderWidth };

	pCanvas->Fill(&rcClient, m_nBorderColor); // draw border
	pCanvas->Fill(&rcCenter, m_nFaceColor); // fill background

	// calculate fill width
	long nPixelWidth = ((float)rcCenter.right / (float)m_nMaxProgress) * (float)m_nProgress;

	RECT rcProgress = { m_nBorderWidth, m_nBorderWidth,
		nPixelWidth - m_nBorderWidth,
		rcCenter.bottom };

	pCanvas->Fill(&rcProgress, m_nFillColor); // fill progress

	// draw text
	if (m_nDrawText)
		m_pFont->DrawText(&m_ptText, m_bstrText, m_nTextColor, pCanvas);

   return S_OK;
}

STDMETHODIMP cProgress::put_FaceColor(long newVal)
{
	m_nFaceColor = newVal;
	m_pSite->Invalidate();

	return S_OK;
}

STDMETHODIMP cProgress::put_FillColor(long newVal)
{
	m_nFillColor = newVal;
	m_pSite->Invalidate();

	return S_OK;
}

STDMETHODIMP cProgress::put_TextColor(long newVal)
{
	m_nTextColor = newVal;
	m_pSite->Invalidate();

	return S_OK;
}

STDMETHODIMP cProgress::put_MaxValue(long newVal)
{
	m_nMaxProgress = newVal;
	m_pSite->Invalidate();

	return S_OK;
}


STDMETHODIMP cProgress::put_PreText(BSTR newVal)
{
	USES_CONVERSION;
	m_strPre = OLE2A(newVal);
	m_pSite->Invalidate();

	return S_OK;
}

STDMETHODIMP cProgress::put_PostText(BSTR newVal)
{
	USES_CONVERSION;
	m_strPost = OLE2A(newVal);
	m_pSite->Invalidate();

	return S_OK;
}

STDMETHODIMP cProgress::put_Alignment(BSTR newVal)
{
	USES_CONVERSION;
	std::string val = OLE2A(newVal);

	if (!val.compare("left"))
		m_nAlignment = 0;
	if (!val.compare("center"))
		m_nAlignment = 1;
	if (!val.compare("right"))
		m_nAlignment = 2;

	m_pSite->Invalidate();
	return S_OK;
}

STDMETHODIMP cProgress::put_DrawText(VARIANT_BOOL newVal)
{
	if (newVal == VARIANT_TRUE)
		m_nDrawText = true;
	else
		m_nDrawText = false;

	m_pSite->Invalidate();
	return S_OK;
}


STDMETHODIMP cProgress::put_BorderWidth(long newVal)
{
	m_nBorderWidth = newVal;
	m_pSite->Invalidate();

	return S_OK;
}

STDMETHODIMP cProgress::put_BorderColor(long newVal)
{
	m_nBorderColor = newVal;
	m_pSite->Invalidate();

	return S_OK;
}
