//+-------------------------------------------------------------------------
//
//  Microsoft Windows
//
//  Copyright (C) Microsoft Corporation, 1999 - 1999
//
//  File:       bennodes.h
//
//--------------------------------------------------------------------------

// BenefitsNodes.h
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_BENEFITSNODES_H__E0573E77_D325_11D1_846C_00104B211BE5__INCLUDED_)
#define AFX_BENEFITSNODES_H__E0573E77_D325_11D1_846C_00104B211BE5__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Benefits.h"

//
// Added to support the generated COM dispatch interface.
//
#import "SampCtrl\SampCtrl.ocx"
using namespace SampCtrl;

class CRetirementNode : public CBenefitsData< CRetirementNode >
{
public:
	SNAPINMENUID( IDR_UPDATE_MENU )
	BEGIN_SNAPINCOMMAND_MAP( CRetirementNode, FALSE )
		SNAPINCOMMAND_ENTRY(ID_TASK_ENROLL, OnEnroll)
		SNAPINCOMMAND_ENTRY(ID_TOP_UPDATE, OnUpdate)
	END_SNAPINCOMMAND_MAP()
	BEGIN_SNAPINTOOLBARID_MAP( CRetirementNode )
	END_SNAPINTOOLBARID_MAP()

	CRetirementNode( CEmployee* pCurEmployee );
	virtual ~CRetirementNode();

	//
	// Overridden to display web page as results.
	//
    STDMETHOD( GetResultViewType )( LPOLESTR *ppViewType, long *pViewOptions );

	//
	// Overridden to provide strings for various columns.
	//
	LPOLESTR GetResultPaneColInfo(int nCol);

	//
	// Command handler for "Enroll" functionality.
	//
	STDMETHOD( OnEnroll )(bool& bHandled, CSnapInObjectRootBase* pObj);

	//
	// Command handler for "Update" functionality.
	//
	STDMETHOD( OnUpdate )(bool& bHandled, CSnapInObjectRootBase* pObj);

	//
	// Overridden to cache the OCX pointer.
	//
    STDMETHOD(Notify)( MMC_NOTIFY_TYPE event,
        long arg,
        long param,
		IComponentData* pComponentData,
		IComponent* pComponent,
		DATA_OBJECT_TYPES type)
	{
		HRESULT hr = E_NOTIMPL;

		switch (event)
		{
		case MMCN_SHOW:
			//
			// Always respond to the show call so that the
			// console knows this has been processed and can
			// properly seat toolbars, etc.
			//
			hr = S_OK;
			break;

		case MMCN_INITOCX:
			//
			// The IUnknown of the OCX is passed in. Do
			// any other initialization of the OCX here.
			//
			m_spControl = (IUnknown*) param;
			hr = S_OK;
			break;

		default:
			//
			// Always default to calling the base class implementation.
			//
			hr = CBenefitsData<CRetirementNode>::Notify( event, 
					arg, 
					param, 
					pComponentData, 
					pComponent, 
					type );
		}

		return hr;
	}

protected:
	//
	// Definition generated by compiler. IDispatch implementation.
	//
	_SampleControlPtr m_spControl;
};

#define TASKPAD_LOCALQUERY 100

class CHealthNode : public CBenefitsData< CHealthNode >,
	public CTaskpadItem
{
public:
	SNAPINMENUID( IDR_ENROLL_MENU )
	BEGIN_SNAPINCOMMAND_MAP( CHealthNode, FALSE )
		SNAPINCOMMAND_ENTRY(ID_TASK_ENROLL, OnEnroll)
		SNAPINCOMMAND_ENTRY(ID_TOP_IMPORT, OnImport)
		SNAPINCOMMAND_ENTRY(ID_TOP_EXPORT, OnExport)
		SNAPINCOMMAND_ENTRY(ID_VIEW_TASKPAD, OnTaskpad)
	END_SNAPINCOMMAND_MAP()
	BEGIN_SNAPINTOOLBARID_MAP( CHealthNode )
		SNAPINTOOLBARID_ENTRY( IDR_ENROLLTOOLBAR )
	END_SNAPINTOOLBARID_MAP()

	CHealthNode( CEmployee* pCurEmployee );
	virtual ~CHealthNode();

	//
	// Overridden to display web page as results.
	//
    STDMETHOD( GetResultViewType )( LPOLESTR *ppViewType, long *pViewOptions );

	//
	// Overridden to provide strings for various columns.
	//
	LPOLESTR GetResultPaneColInfo(int nCol);

	//
	// Command handler for "Enroll" functionality.
	//
	STDMETHOD( OnEnroll )(bool& bHandled, CSnapInObjectRootBase* pObj);

	//
	// Restores any state, especially in the case of using a
	// taskpad, when the back and forward buttons are used by
	// the user for navigation.
	//
	STDMETHOD( OnRestoreView )( MMC_RESTORE_VIEW* pRestoreView, BOOL* pfHandled );

	//
	// Command handler for "OnTaskpad" functionality.
	//
	STDMETHOD( OnTaskpad )(bool& bHandled, CSnapInObjectRootBase* pObj)
	{
		UNUSED_ALWAYS( bHandled );
		CComPtr<IConsole> spConsole;

		//
		// Switch the current view mode to a taskpad view.
		//
		m_fTaskpad = !m_fTaskpad;

		//
		// Reselect the node to cause GetResultViewType() to get
		// called once again.
		//
		if ( pObj->m_nType == 1 )
			spConsole = ((CBenefits*)pObj)->m_spConsole;
		else
			spConsole = ((CBenefitsComponent*)pObj)->m_spConsole;

		spConsole->SelectScopeItem( m_scopeDataItem.ID );

		return( S_OK );
	}

	//
	// Overridden to set the checkmark state of the taskpad menuitem.
	//
	void UpdateMenuState(UINT id, LPTSTR pBuf, UINT *flags)
	{
		UNUSED_ALWAYS( pBuf );

		//
		// Check the menuitem if we are currently in "taskpad"
		// mode.
		//
		if ( id == ID_VIEW_TASKPAD )
			*flags |= m_fTaskpad ? MFS_CHECKED : MFS_UNCHECKED;
	}

	//
	// Overridden to enable the delete verb.
	//
    STDMETHOD(Notify)( MMC_NOTIFY_TYPE event,
        long arg,
        long param,
		IComponentData* pComponentData,
		IComponent* pComponent,
		DATA_OBJECT_TYPES type)
	{
		HRESULT hr = E_NOTIMPL;

		switch (event)
		{
		case MMCN_SELECT:
			hr = S_OK;
			break;

		case MMCN_RESTORE_VIEW:
			//
			// Called when the history list is used to navigate by
			// the user. Since we have a taskpad display, it's up
			// to us to restore that view, as appropriate.
			//
			hr = OnRestoreView( (MMC_RESTORE_VIEW*) arg, (BOOL*) param );
			break;

		case MMCN_SHOW:
			//
			// Always respond to the show call so that the
			// console knows this has been processed and can
			// properly seat toolbars, etc.
			//
			hr = S_OK;
			break;

		default:
			//
			// Always default to calling the base class implementation.
			//
			hr = CBenefitsData< CHealthNode >::Notify( event, 
					arg, 
					param, 
					pComponentData, 
					pComponent, 
					type );
		}

		return hr;
	}

	//
	// Called when one of the tasks is clicked.
	//
	STDMETHOD( TaskNotify )( IConsole* pConsole, VARIANT* arg, VARIANT* param );

	//
	// Returns an enumerator for all of these tasks.
	//
	STDMETHOD( EnumTasks )( LPOLESTR szTaskGroup, IEnumTASK** ppEnumTASK );

protected:
	//
	// Indicates whether we should be displayed in a taskpad view.
	//
	bool m_fTaskpad;
};

class CBuildingNode;
class CKeyNode : public CChildrenBenefitsData< CKeyNode >
{
public:
	SNAPINMENUID( IDR_ACCESS_MENU )
	BEGIN_SNAPINCOMMAND_MAP( CKeyNode, FALSE )
		SNAPINCOMMAND_ENTRY(ID_NEW_BUILDINGACCESS, OnGrantAccess)
	END_SNAPINCOMMAND_MAP()
	BEGIN_SNAPINTOOLBARID_MAP( CKeyNode )
		SNAPINTOOLBARID_ENTRY( IDR_ACCESSTOOLBAR )
	END_SNAPINTOOLBARID_MAP()

	CKeyNode( CEmployee* pCurEmployee );
	virtual ~CKeyNode();

	//
	// Overridden to call the base class implementation.
	//
    STDMETHOD(Notify)( MMC_NOTIFY_TYPE event,
        long arg,
        long param,
		IComponentData* pComponentData,
		IComponent* pComponent,
		DATA_OBJECT_TYPES type)
	{
		ATLTRACE2( atlTraceSnapin, 0, _T( "CNotifyImpl::Notify\n" ) );

		// Add code to handle the different notifications.
		// Handle MMCN_SHOW and MMCN_EXPAND to enumerate children items.
		// In response to MMCN_SHOW you have to enumerate both the scope
		// and result pane items.
		// For MMCN_EXPAND you only need to enumerate the scope items
		// Use IConsoleNameSpace::InsertItem to insert scope pane items
		// Use IResultData::InsertItem to insert result pane item.
		HRESULT hr = E_NOTIMPL;

		_ASSERTE( pComponentData != NULL || pComponent != NULL );

		CComPtr<IConsole> spConsole;
		CComQIPtr<IHeaderCtrl, &IID_IHeaderCtrl> spHeader;
		if (pComponentData != NULL)
			spConsole = ((CBenefits*)pComponentData)->m_spConsole;
		else
		{
			spConsole = ((CBenefitsComponent*)pComponent)->m_spConsole;
			spHeader = spConsole;
		}

		switch (event)
		{
		case MMCN_SELECT:
			//
			// Call our select handler.
			//
			hr = OnSelect( spConsole );
			break;

		case MMCN_SHOW:
			//
			// Only setup colums if we're displaying the result pane.
			//
			if ( arg == TRUE )
				hr = OnShowColumn( spHeader );
			hr = OnShow( event, arg, param, spConsole, type );
			break;

		case MMCN_EXPAND:
			//
			// We do not expand as normal, since the building nodes are
			// only displayed in the result pane.
			//
			break;

		case MMCN_ADD_IMAGES:
			hr = OnAddImages( event, arg, param, spConsole, type );
			break;

		case MMCN_QUERY_PASTE:
			//
			// Called to determine if the current object can be pasted
			// or not into this context.
			//
			hr = OnQueryPaste( (LPDATAOBJECT) arg );
			break;

		case MMCN_PASTE:
			//
			// Called by MMC when the item should be pasted.
			//
			hr = OnPaste( spConsole, (LPDATAOBJECT) arg, (LPDATAOBJECT*) param );
			break;
		}

		return hr;
	}

	//
	// Ensures that the appropriate verbs are displayed.
	//
	STDMETHOD( OnSelect )( IConsole* pConsole )
	{
		HRESULT hr;
		CComPtr<IConsoleVerb> spConsoleVerb;

		//
		// Enable the delete verb.
		//
		hr = pConsole->QueryConsoleVerb( &spConsoleVerb );
		_ASSERTE( SUCCEEDED( hr ) );

		//
		// Enable the copy and paste verbs.
		//
		hr = spConsoleVerb->SetVerbState( MMC_VERB_PASTE, ENABLED, TRUE );
		_ASSERTE( SUCCEEDED( hr ) );

		return( hr );
	}

	//
	// Called by the console to determine if we can paste the
	// specified node.
	//
	STDMETHOD( OnQueryPaste )( LPDATAOBJECT pItem );
	
	//
	// Called by MMC when the item should be pasted.
	//
	STDMETHOD( OnPaste )( IConsole* pConsole, LPDATAOBJECT pItem, LPDATAOBJECT* pItemCut );

	//
	// Overridden to provide strings for various columns.
	//
	LPOLESTR GetResultPaneColInfo(int nCol);

	//
	// Overridden to add new columns to the results
	// display.
	//
	STDMETHOD( OnShowColumn )( IHeaderCtrl* pHeader );

	//
	// Command handler for "Grant Acess" functionality.
	//
	STDMETHOD( OnGrantAccess )( bool& bHandled, CSnapInObjectRootBase* pObj );

	//
	// Called by one of our children nodes to inform us that
	// they should be deleted. This occurs when the user selects
	// a delete action on the building. This function should not
	// only delete the building, but also handle the refresh of
	// the result display.
	//
	STDMETHOD( OnDeleteBuilding )( IConsole* pConsole, CBuildingNode* pChildNode );
};

class CBuildingNode : public CBenefitsData< CBuildingNode >
{
public:
	BEGIN_SNAPINCOMMAND_MAP(CBuildingNode, FALSE)
	END_SNAPINCOMMAND_MAP()

	BEGIN_SNAPINTOOLBARID_MAP(CBuildingNode)
	END_SNAPINTOOLBARID_MAP()

	CBuildingNode( CKeyNode* pParentNode, BSTR bstrName, BSTR bstrLocation );
	CBuildingNode( const CBuildingNode& inNode );

	//
	// Overridden to provide strings for various columns.
	//
	LPOLESTR GetResultPaneColInfo(int nCol);

	//
	// Hold the location of this building.
	//
	BSTR m_bstrLocation;

	//
	// Pointer to our parent node to handle deletion
	// issues.
	//
	CKeyNode* m_pParentNode;

	//
	// Overridden to enable the delete verb.
	//
    STDMETHOD(Notify)( MMC_NOTIFY_TYPE event,
        long arg,
        long param,
		IComponentData* pComponentData,
		IComponent* pComponent,
		DATA_OBJECT_TYPES type)
	{
		HRESULT hr = E_NOTIMPL;
		CComPtr<IConsole> spConsole;
		CComQIPtr<IHeaderCtrl, &IID_IHeaderCtrl> spHeader;

		if (pComponentData != NULL)
			spConsole = ((CBenefits*)pComponentData)->m_spConsole;
		else
		{
			spConsole = ((CBenefitsComponent*)pComponent)->m_spConsole;
			spHeader = spConsole;
		}

		switch (event)
		{
		case MMCN_DELETE:
			//
			// Call our delete handler.
			//
			hr = OnDelete( spConsole );
			break;

		case MMCN_SELECT:
			//
			// Call our select handler.
			//
			hr = OnSelect( spConsole );
			break;

		case MMCN_SHOW:
			//
			// Always respond to the show call so that the
			// console knows this has been processed and can
			// properly seat toolbars, etc.
			//
			hr = S_OK;
			break;

		default:
			//
			// Always default to calling the base class implementation.
			//
			hr = CBenefitsData< CBuildingNode >::Notify( event, 
					arg, 
					param, 
					pComponentData, 
					pComponent, 
					type );
		}

		return hr;
	}

	//
	// Delete handler.
	//
	STDMETHOD( OnDelete )( IConsole* pConsole )
	{
		_ASSERT( m_pParentNode != NULL );
		HRESULT hr;

		//
		// Calls the parent node to tell it to delete
		// ourselves.
		//
		hr = m_pParentNode->OnDeleteBuilding( pConsole, this );

		return( hr );
	}

	//
	// Ensures that the appropriate verbs are displayed.
	//
	STDMETHOD( OnSelect )( IConsole* pConsole )
	{
		HRESULT hr;
		CComPtr<IConsoleVerb> spConsoleVerb;

		//
		// Enable the delete verb.
		//
		hr = pConsole->QueryConsoleVerb( &spConsoleVerb );
		_ASSERTE( SUCCEEDED( hr ) );
		hr = spConsoleVerb->SetVerbState( MMC_VERB_DELETE, ENABLED, TRUE );
		_ASSERTE( SUCCEEDED( hr ) );

		//
		// Enable the copy and paste verbs.
		//
		hr = spConsoleVerb->SetVerbState( MMC_VERB_COPY, ENABLED, TRUE );
		_ASSERTE( SUCCEEDED( hr ) );

		return( hr );
	}
};

#endif // !defined(AFX_BENEFTISNODES_H__E0573E77_D325_11D1_846C_00104B211BE5__INCLUDED_)