// Panel.cpp : Implementation of cPanel
#include "stdafx.h"
#include "Inject.h"
#include "Panel.h"

/////////////////////////////////////////////////////////////////////////////
// cPanel

enum ePanelChildren
{
   eViewFirst = 1000
};

cPanel::cPanel()
: m_nIcon( 0 ),
m_nIconModule( 0 ),
m_nActiveView( -1 ),
m_bDragging( false )
{
}

void cPanel::hideView()
{
   m_pSite->Invalidate();

   if( m_nActiveView == -1 )
      // No active view currently
      return;

   CComPtr< ILayerSite > pActive;
   m_pSite->get_Child( m_nActiveView, ePositionByID, &pActive );

   static RECT rcHide = { 0, 0, 0, 0 };
   pActive->put_Position( &rcHide );

   if( m_pSink.p != NULL )
      m_pSink->PanelDeactivate( m_nActiveView );

   m_nActiveView = -1;
}

void cPanel::onCreate()
{
   CComPtr< IPluginSite > pPlugin;
   m_pSite->get_PluginSite( &pPlugin );

   pPlugin->LoadBitmapPortal( 0x0600126F, &m_pBackground );
   pPlugin->LoadBitmapPortal( 0x06001277, &m_pBorder );
   pPlugin->CreateFont( _bstr_t( _T( "Times New Roman" ) ), 15, eFontBold, &m_pTitle );

   CComPtr< IButton > pRollup;

   HRESULT hRes = ::CoCreateInstance( CLSID_Button, NULL, CLSCTX_INPROC_SERVER, IID_IButton,
      reinterpret_cast< void ** >( &pRollup ) );

   _ASSERTE( SUCCEEDED( hRes ) );

   CComPtr< ILayer > pBtnLayer;
   pRollup->QueryInterface( &pBtnLayer );

   LayerParams lp = { 1, { 180 - 16, 0, 180, 16 }, eRenderClipped };
   m_pSite->CreateChild( &lp, pBtnLayer );

   pRollup->put_Matte( RGB( 0, 0, 0 ) );
   pRollup->SetImages( 0, 0x0600113C, 0x0600113B );
   ICommandEventsImpl< BUTTON_CLOSE, cPanel >::advise( pRollup );

   m_pSite->put_Transparent( VARIANT_FALSE );
}

void cPanel::onDestroy()
{
   m_pBorder.Release();
   m_pBackground.Release();
   m_pTitle.Release();
}

STDMETHODIMP cPanel::Render( ICanvas *pCanvas )
{
   RECT rc;
   m_pSite->get_Position( &rc );

   SIZE szBorder;
   m_pBorder->get_Size( &szBorder );

   // Draw the background
   RECT rc_pat = { 0, 0, rc.right - rc.left, rc.bottom - rc.top };
   static POINT pt_pat = { 0, 0 };

   m_pBackground->PatBlt( pCanvas, &rc_pat, &pt_pat );

   // Draw the borders
   RECT rc_border_top = { 0, 0, rc.right - rc.left, szBorder.cy },
      rc_border_bottom = { 0, rc.bottom - rc.top - szBorder.cy, 
         rc.right - rc.left, rc.bottom - rc.top };

   pCanvas->Fill( &rc_border_top, RGB( 0, 0, 0 ) );
   m_pBorder->PatBlt( pCanvas, &rc_border_top, &pt_pat );
   pCanvas->Fill( &rc_border_bottom, RGB( 0, 0, 0 ) );
   m_pBorder->PatBlt( pCanvas, &rc_border_bottom, &pt_pat );

   // Draw the title text
   if( m_strTitle.length() > 0 )
   {
      POINT ptText = { 24, szBorder.cy + 5 };
      m_pTitle->DrawText( &ptText, m_strTitle, 0, pCanvas );
   }

   if( m_nIcon != 0 )
   {
      CComPtr< IPluginSite > pPlugin;
      m_pSite->get_PluginSite( &pPlugin );

      CComPtr< IIconCache > pIconCache;
      static SIZE szIcon = { 16, 16 };
      pPlugin->GetIconCache( &szIcon, &pIconCache );

      static POINT pt = { 4, szBorder.cy + 4 };
      pIconCache->DrawIcon( &pt, m_nIcon, m_nIconModule, pCanvas );
   }

   _ASSERTE( _CrtCheckMemory( ) );

   return S_OK;
}

STDMETHODIMP cPanel::Reformat()
{
   // Reset the size
   CComPtr< IPluginSite > pPlugin;
   m_pSite->get_PluginSite( &pPlugin );

   SIZE szScreen;
   pPlugin->GetScreenSize( &szScreen );

   RECT rc = { m_nLeft, m_nTop, m_nWidth+m_nLeft, m_nHeight+m_nTop };

   m_pSite->put_Position( &rc );

   RECT rcCloseBtn = { m_nWidth - 16, 0, m_nWidth, 16 };   
   CComPtr< ILayerSite > pCloseBtnLS;
   m_pSite->get_Child(1, ePositionByID, &pCloseBtnLS);

   pCloseBtnLS->put_Position(&rcCloseBtn);

   if( m_nActiveView != -1 )
   {
      // Position the active view
      SIZE szBorder;
      m_pBorder->get_Size( &szBorder );

      CComPtr< ILayerSite > pActive;
      m_pSite->get_Child( m_nActiveView, ePositionByID, &pActive );

      RECT rcChild = { 0, 24 + szBorder.cy, m_nWidth, m_nHeight - szBorder.cy };
      pActive->put_Position( &rcChild );
   }

   return S_OK;
}

STDMETHODIMP cPanel::AddView(long nViewID, ILayer *pLayer)
{
   _ASSERTE( pLayer != NULL );

   LayerParams p = { nViewID, { 0, 0, 0, 0 }, eRenderClipped };

   // Set up the layer - note that it is not visible
   return m_pSite->CreateChild( &p, pLayer );
}

STDMETHODIMP cPanel::ActivateView(long nViewID, ViewParams *pParams)
{
   // Hide the current view by resizing to 0,0
   hideView();

   m_strTitle = pParams->label;
   m_nIcon = pParams->icon;
   m_nIconModule = pParams->iconLibrary;
   m_nWidth = pParams->width;
   m_nTop = pParams->top;
   m_nHeight = pParams->height;
   m_nLeft = pParams->left;

#ifdef _DEBUG
   // Make sure the child exists
   CComPtr< ILayerSite > pChildSite;
   _ASSERTE( SUCCEEDED( m_pSite->get_Child( nViewID, ePositionByID, &pChildSite ) ) );
#endif

   // Locate the child
   m_nActiveView = nViewID;

   // Trick it into reformatting next frame
   static RECT rcBig = { 0, 0, 1, 1 };
   m_pSite->put_Position( &rcBig );

	return S_OK;
}

STDMETHODIMP cPanel::RemoveView(long nViewID)
{
   if( nViewID == m_nActiveView )
      // If this is the current view, run and hide
      Deactivate();

   CComPtr< ILayerSite > pChildSite;
   HRESULT hRes = m_pSite->get_Child( nViewID, ePositionByID, &pChildSite );
   _ASSERTE( SUCCEEDED( hRes ) );

   pChildSite->Destroy();

	return S_OK;
}

void cPanel::onCloseAccepted(long nID)
{
   // We should only be getting commands from the button
   _ASSERTE( nID == 1 );

   Deactivate();
}

STDMETHODIMP cPanel::get_ActiveView(long *pVal)
{
   _ASSERTE( pVal != NULL );

   *pVal = m_nActiveView;

   return S_OK;
}

STDMETHODIMP cPanel::LoadView(long nViewID, IView *pView, IUnknown *pSchema)
{
   _ASSERTE( pView != NULL );
   _ASSERTE( pSchema != NULL );

   long nAssigned;

   // Set up the layer - note that it is not visible
   return pView->LoadControl( m_pSite, nViewID, pSchema, &nAssigned );
}

STDMETHODIMP cPanel::Deactivate()
{
   if( m_nActiveView == -1 )
      // No active view currently
      return S_OK;

   // Hide the current view by resizing to 0,0
   hideView();

   // Hide the entire panel
   static RECT rcHide = { 0, 0, 0, 0 };
   m_pSite->put_Position( &rcHide );

   m_nActiveView = -1;

	return S_OK;
}

STDMETHODIMP cPanel::putref_Sink(IPanelSink *newVal)
{
   m_pSink = newVal;

	return S_OK;
}

STDMETHODIMP cPanel::MouseEnter(MouseState *)
{
   return S_OK;
}

STDMETHODIMP cPanel::MouseExit(MouseState *)
{
   return S_OK;
}

STDMETHODIMP cPanel::MouseDown(MouseState *pMS)
{		
	if((pMS->screen.x>=m_nLeft) && (pMS->screen.x<=m_nLeft+m_nWidth-16) && (pMS->screen.y-28>=m_nTop) && (pMS->screen.y-28<=m_nTop+28))
	{
		m_DeltaX = pMS->screen.x-m_nLeft;
		m_DeltaY = pMS->screen.y-m_nTop-28;
		m_bDragging = true;
	}

	return S_OK;
}

STDMETHODIMP cPanel::MouseUp(MouseState *)
{
	m_bDragging = false;
	return S_OK;
}

STDMETHODIMP cPanel::MouseMove(MouseState *pMS)
{
	if(m_bDragging)
	{
		m_nLeft = pMS->screen.x-m_DeltaX;
		m_nTop = pMS->screen.y-m_DeltaY-28;

		static RECT rcBig = { 0, 0, 1, 1 };
		m_pSite->put_Position( &rcBig );
	}
	return S_OK;
}

STDMETHODIMP cPanel::MouseEvent(long nMsg, long wParam, long lParam)
{
   return S_OK;
}