// Button.cpp : Implementation of cButton
#include "stdafx.h"
#include "Inject.h"
#include "Button.h"

/////////////////////////////////////////////////////////////////////////////
// cButton

cButton::cButton()
: m_nModule( 0 ),
m_nBackground( 0 ),
m_nPressed( 0 ),
m_nReleased( 0 ),
m_bPressed( VARIANT_FALSE ),
m_bMouseIn( VARIANT_FALSE ),
m_nMatte( RGB( 0, 255, 255 ) )
{
}

STDMETHODIMP cButton::SetImages(long dwModule, long dwReleased, long dwPressed)
{
   m_nModule = dwModule;
   m_nReleased = dwReleased;
   m_nPressed = dwPressed;

   m_pSite->Invalidate();

	return S_OK;
}

STDMETHODIMP cButton::Render(ICanvas *pCanvas)
{
   _ASSERTE( pCanvas != NULL );

   // ::MessageBox( NULL, _T( "cButton::Render" ), _T( "Inject.dll" ), MB_OK );

   _ASSERTE( m_pSite.p != NULL );

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

   if( m_nMatte != RGB( 0, 255, 255 ) )
   {
      // That's the transparent color
      RECT rcMatte = { 0, 0, rc.right - rc.left, rc.bottom - rc.top };
      pCanvas->Fill( &rcMatte, m_nMatte );
   }

   CComPtr< IPluginSite > pPlugin;
   m_pSite->get_PluginSite( &pPlugin );

   _ASSERTE( pPlugin.p != NULL );

   CComPtr< IIconCache > pIcons;
   SIZE sz = { rc.right - rc.left, rc.bottom - rc.top };
   pPlugin->GetIconCache( &sz, &pIcons );

   _ASSERTE( pIcons.p != NULL );

   long nImage = ( m_bPressed && m_bMouseIn ) ? m_nPressed : m_nReleased;

   POINT pt = { 0, 0 };

   if (m_nBackground != 0) pIcons->DrawIcon( &pt, m_nBackground, 0, pCanvas );
   pIcons->DrawIcon( &pt, nImage, m_nModule, pCanvas );

   _ASSERTMEM( _CrtCheckMemory( ) );

   return S_OK;
}

STDMETHODIMP cButton::MouseEnter(struct MouseState *)
{
   _ASSERTE( !m_bMouseIn );

   m_bMouseIn = VARIANT_TRUE;

   if( m_bPressed )
   {
      long nID;
      m_pSite->get_ID( &nID );
      Fire_Hit( nID );

      _ASSERTE( m_pSite.p != NULL );

      m_pSite->Invalidate();
   }

	return S_OK;
}

STDMETHODIMP cButton::MouseExit(struct MouseState *)
{
   _ASSERTE( m_bMouseIn );

   m_bMouseIn = VARIANT_FALSE;

   if( m_bPressed )
   {
      long nID;
      m_pSite->get_ID( &nID );
      Fire_Unhit( nID );

      _ASSERTE( m_pSite.p != NULL );

      m_pSite->Invalidate();
   }

	return S_OK;
}

STDMETHODIMP cButton::MouseDown(struct MouseState *)
{
   _ASSERTE( m_pSite != NULL );

   long nID;
   m_pSite->get_ID( &nID );
   Fire_Hit( nID );

   m_bPressed = VARIANT_TRUE;
   m_pSite->Invalidate();

	return S_OK;
}

STDMETHODIMP cButton::MouseUp(struct MouseState *)
{
   m_bPressed = VARIANT_FALSE;

   long nID;
   m_pSite->get_ID( &nID );

   if( m_bMouseIn )
   {
      _ASSERTE( m_pSite.p != NULL );

      m_pSite->Invalidate();

      // NOTE: The command may destroy the control synchronously
      // so we make a stack copy of the target in case our instance is destroyed
      // for the purpose of completing the command
      Fire_Accepted( nID );
      Fire_Unhit( nID );
   }
   else
      Fire_Canceled( nID );

	return S_OK;
}

STDMETHODIMP cButton::get_Matte(long *pVal)
{
   *pVal = m_nMatte;

	return S_OK;
}

STDMETHODIMP cButton::put_Matte(long newVal)
{
   m_nMatte = newVal;
   m_pSite->Invalidate();

	return S_OK;
}

STDMETHODIMP cButton::SchemaLoad(IView *, IUnknown *pSchema)
{
   USES_CONVERSION;

   CComPtr< IPluginSite > pPlugin;
   m_pSite->get_PluginSite( &pPlugin );

   MSXML::IXMLDOMElementPtr pElement = pSchema;

   // Get the suspected variables out
   _variant_t vModule = pElement->getAttribute( _T( "iconlibrary" ) ),
      vReleased = pElement->getAttribute( _T( "icon" ) ),
      vPressed = pElement->getAttribute( _T( "pressedicon" ) ),
      vMatte = pElement->getAttribute( _T( "matte" ) ),
	  vBackground = pElement->getAttribute( _T( "background" ) );

   if( vModule.vt == VT_BSTR )
      pPlugin->LoadResourceModule( vModule.bstrVal, &m_nModule );

   if( vReleased.vt != VT_NULL )
   {
      try
      {
         m_nReleased = static_cast< long >( vReleased ) + 0x06000000;
      }
      catch( ... )
      {
         // Type conversion error
         _ASSERTE( FALSE );
      }
   }

   if( vPressed.vt != VT_NULL )
   {
      try
      {
         m_nPressed = static_cast< long >( vPressed ) + 0x06000000;
      }
      catch( ... )
      {
         // Type conversion error
         _ASSERTE( FALSE );
      }
   }
   else
      m_nPressed = m_nReleased;

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

   if( vBackground.vt != VT_NULL )
   {
      try
      {
         m_nBackground = static_cast< long >( vBackground ) + 0x06000000;
      }
      catch( ... )
      {
         // Type conversion error
         _ASSERTE( FALSE );
      }
   }
   else
   {
	   m_nBackground = 0;
   }

   return S_OK;
}
