// RcRcApOpenToolbar.cpp : Implementation of CRcRcApOpenToolbar

#include "stdafx.h"
#include "RcApOpenToolbar.h"
#include "RpAnimPluginPackage.h"

#define PLUGIN_TOOLBAR_NAME  L"Plugin sample toolbar"
#define ANIMPLUGIN_TOOLBAR_ID L"{4307945C-EF36-4dd2-A6C6-BF3C33F840CB}"


static RtShelfButtonDataEx shelfButtonProcClipData[] =
{
    {_T("Create Clip"),   _T("Create procedural clip"),  _T("RsAnimPlugin.CreateProcClip('')"), _T(""), &__uuidof(CRpAnimPlugin), IDB_ANIM_PROCCLIP, NULL,  _T(""), 0, NULL},
};

static RtShelfButtonDataEx shelfButtonStopData[] =
{
	{_T("Stop"),   _T("Stop Playing"),  _T("RsTime.Stop()"), _T(""), &__uuidof(CRpAnimPlugin), IDB_ANIM_STOP, NULL, _T(""), 0, NULL},
 };

static RtShelfButtonDataEx shelfButtonPlayData[] =
{
    {_T("Play"),   _T("Play animation"),  _T("RsTime.Play('')"), _T(""), &__uuidof(CRpAnimPlugin), IDB_ANIM_PLAY, NULL, _T(""), 0, NULL},
 };

static RtShelfButtonDataEx shelfButtonRecData[] =
{
    {_T("Rec"),   _T("Set keyframe"),  _T("RsAnim.SetKeyFrame('', RsTime.CurrentTime())"), _T("RsAnimKeying.OpenView()"), &__uuidof(CRpAnimPlugin), IDB_ANIM_REC, NULL,  _T(""), 0, NULL},
 };

static RtShelfButtonDataEx shelfButtonStartData[] =
{
    {_T("Start frame"),   _T("Move to the beginning"),  _T("RsTime.StartFrame()"), _T(""), &__uuidof(CRpAnimPlugin), IDB_ANIM_START, NULL,  _T(""), 0, NULL},
 };

static RtShelfButtonDataEx shelfButtonEndData[] =
{
    {_T("End frame"),   _T("Move to the end"),  _T("RsTime.EndFrame()"), _T(""), &__uuidof(CRpAnimPlugin), IDB_ANIM_END, NULL,  _T(""), 0, NULL},
};

static RtShelfButtonDataEx shelfButtonNextData[] =
{
    {_T("Next frame"),   _T("Move to the next frame"),  _T("RsTime.NextFrame()"),_T(""), &__uuidof(CRpAnimPlugin), IDB_ANIM_NEXT, NULL,  _T(""), 0, NULL},
 };

static RtShelfButtonDataEx shelfButtonPrevData[] =
{
    {_T("Prev frame"),   _T("Move to the previous frame"),  _T("RsTime.PrevFrame()"), _T(""), &__uuidof(CRpAnimPlugin), IDB_ANIM_PREV, NULL,  _T(""), 0, NULL},
};


static RtShelfButtonDataEx shelfButtonNextKfData[] =
{
    {_T("Next keyframe"),   _T("Move to the next keyframe"),  _T("RsTime.NextKeyFrame()"),_T(""), &__uuidof(CRpAnimPlugin), IDB_ANIM_NEXTKF, NULL,  _T(""), 0, NULL},
 };

static RtShelfButtonDataEx shelfButtonPrevKfData[] =
{
    {_T("Prev keyframe"),   _T("Move to the previous keyframe"),  _T("RsTime.PrevKeyFrame()"), _T(""), &__uuidof(CRpAnimPlugin), IDB_ANIM_PREVKF, NULL,  _T(""), 0, NULL},
};



static RtShelfDataEx tpControlsToolbar[] =
{
	{eToolBar, _T("Clip"), sizeof(shelfButtonProcClipData) / sizeof(shelfButtonProcClipData[0]), 	shelfButtonProcClipData},
	{eToolBar, _T("Rec"), sizeof(shelfButtonRecData) / sizeof(shelfButtonRecData[0]), 	shelfButtonRecData},
	{eToolBar, _T("Start"), sizeof(shelfButtonStartData) / sizeof(shelfButtonStartData[0]), 	shelfButtonStartData},
	{eToolBar, _T("Prev kf"), sizeof(shelfButtonPrevKfData) / sizeof(shelfButtonPrevKfData[0]), 	shelfButtonPrevKfData},
	{eToolBar, _T("Prev"), sizeof(shelfButtonPrevData) / sizeof(shelfButtonPrevData[0]), 	shelfButtonPrevData},
    {eToolBar, _T("Stop"), sizeof(shelfButtonStopData) / sizeof(shelfButtonStopData[0]), 	shelfButtonStopData},
	{eToolBar, _T("Play"), sizeof(shelfButtonPlayData) / sizeof(shelfButtonPlayData[0]), 	shelfButtonPlayData},
	{eToolBar, _T("Next"), sizeof(shelfButtonNextData) / sizeof(shelfButtonNextData[0]), 	shelfButtonNextData},
	{eToolBar, _T("Next kf"), sizeof(shelfButtonNextKfData) / sizeof(shelfButtonNextKfData[0]), 	shelfButtonNextKfData},
	{eToolBar, _T("End"), sizeof(shelfButtonEndData) / sizeof(shelfButtonEndData[0]), 	shelfButtonEndData}
};


// CRcApOpenToolbar

STDMETHODIMP CRcApOpenToolbar::OnGetValue(CONID conID, IRsDataCache* pDataCache, VARIANT* pVtData, RtBool* pHandled)
{
	return S_OK;
}

STDMETHODIMP CRcApOpenToolbar::OnSetValue(CONID con_id, IRsDataCache* pDataCache, VARIANT* pvtData, RtBool* pHandled)
{
	return S_OK;
}
STDMETHODIMP CRcApOpenToolbar::OnDefaultValue(CONID con_id, VARIANT* pVtData, RtBool* pHandled)
{
	return S_OK;
}

STDMETHODIMP CRcApOpenToolbar::OnInvalidate(CONID con_id, RtBool* pHandled)
{
	return S_OK;
}

STDMETHODIMP CRcApOpenToolbar::OnInitialize(void)
{
	return S_OK;
}

STDMETHODIMP CRcApOpenToolbar::OnLoadDefault(void)
{
	return S_OK;
}

STDMETHODIMP CRcApOpenToolbar::OnDestroy(void)
{
	return S_OK;
}

HRESULT CRcApOpenToolbar::FinalConstruct()
{
	// kernel package
	CComPtr<IRpKernel> spKernelPck;
	HRESULT hRes = CRpAnimPlugin::GetKernelPackage(&spKernelPck);
	
	// create base node
	if (SUCCEEDED(hRes))
		hRes = spKernelPck->CreateBaseNode(GetControllingUnknown(), &m_spUnkAgg);

	return hRes;
}

STDMETHODIMP CRcApOpenToolbar::Execute(void)
{
	HRESULT hr;

    // get Window manager package
    CComPtr<IRpKernel> spKernelPackage;
    hr = CRpAnimPlugin::GetKernelPackage(&spKernelPackage);
    if (FAILED(hr))
        return hr;

    CComPtr<IRsUnknownPackage> spPackage;
    hr = spKernelPackage->FindPackage(DEF_GUIDNAME(CRpWinMng), &spPackage);
    if (FAILED(hr))
        return hr;
    CComQIPtr<IRpWinMngPck>	spWinPackage = spPackage;

    // get windows manager node
    CComPtr<IRsNode> spWinMgrNode;
    hr = spWinPackage->GetWindowsManagerNode(&spWinMgrNode);
    if (FAILED(hr))
        return hr;
    CComQIPtr<IRnWindowsManager> spWinMng = spWinMgrNode;
    
	
	// check if animplugin toolbar is already created
	CComPtr<IRsNode> spExistingToolbarNode;
    spWinMng->FindToolbarByID(ANIMPLUGIN_TOOLBAR_ID, &spExistingToolbarNode);
    
	CComPtr<IRsNode> spExistingToolbarFrameNode;
	if (spExistingToolbarNode)
		spExistingToolbarNode->GetOwner( &spExistingToolbarFrameNode);

	
	if (spExistingToolbarFrameNode != NULL)
	{
		// if toolbar exists, update client 
		CComQIPtr<IRnFrameWindow> spFrameWindow = spExistingToolbarFrameNode;

		if ( spFrameWindow)
			spFrameWindow->RefreshClient();
	}
	else
	{
		// if it does not exist, create new animplugin toolbar

		CComPtr<IRfToolbarSet> spToolbarSet;
		hr = spWinPackage->CreateToolbarFnSet(&spToolbarSet);
		if (FAILED(hr))
			return hr;

		// create toolbar frame
		CComPtr<IRsNode> spToolbarFrameNode;
		if (FAILED(hr = spToolbarSet->CreateToolBarFrame(CComBSTR(PLUGIN_TOOLBAR_NAME), &spToolbarFrameNode)))
			return hr;

		CComQIPtr<IRnFrameWindow> spToolbarFrame = spToolbarFrameNode;
		CComQIPtr<IRnEncapsulator>	spToolbarFrameEncaps = spToolbarFrameNode;

		// create toolbar
		CComPtr<IRsNode> spToolbarNode;
		if (FAILED(hr = spToolbarSet->CreateToolBarEx(CComBSTR(PLUGIN_TOOLBAR_NAME), spToolbarFrameEncaps, tpControlsToolbar, sizeof( tpControlsToolbar) / sizeof( tpControlsToolbar[ 0]), &spToolbarNode)))
			return hr;

		CComQIPtr<IRnToolbar> spToolbar = spToolbarNode;
		if (!spToolbar)
			return E_FAIL;

		// assign toolbar unique id
		spToolbar->put_ToolbarID( CComBSTR( ANIMPLUGIN_TOOLBAR_ID));

		// create window for toolbar
		spToolbarFrame->OpenWindow();

		// position toolbar
		CComQIPtr<IRsNode> spActiveFrameNode;
		spWinMng->GetActiveWindow( &spActiveFrameNode);

		CComQIPtr<IRnFrameWindow> spActiveFrame = spActiveFrameNode;
		if( FAILED( hr = SnapToolbarToActiveWindow(spToolbarFrame, spActiveFrame)))
			return hr;
	}

	return S_OK;
}

STDMETHODIMP CRcApOpenToolbar::Undo(void)
{
	return S_OK;
}

STDMETHODIMP CRcApOpenToolbar::Redo(void)
{
	return S_OK;
}

STDMETHODIMP CRcApOpenToolbar::HasUndo(RtBool* isUndoable)
{
	//Command is not undoable.
	*isUndoable = false;
	return S_OK;
}

HRESULT CRcApOpenToolbar::SnapToolbarToActiveWindow(IRnFrameWindow* pToolbarFrame, IRnFrameWindow* pActiveFrame)
{
	HRESULT hRes;

	if (!pToolbarFrame || !pActiveFrame)
		return E_INVALIDARG;

	CRect rectActiveFrame;
	if ( FAILED( hRes = pActiveFrame->get_Rectangle( &rectActiveFrame)))
		return hRes;

	if ( FAILED( hRes = pToolbarFrame->SafeMoveWindow( rectActiveFrame.left, rectActiveFrame.bottom, INT_MIN, INT_MIN)))
		return hRes;

	CComQIPtr<IRsBaseNode> spActiveFrameBaseNode = pActiveFrame;
	if(!spActiveFrameBaseNode)
		return E_FAIL;
	
	CComBSTR bsActiveFrameName;
	if ( FAILED( hRes = spActiveFrameBaseNode->GetFullName( NULL, &bsActiveFrameName)))
		return hRes;

	return pToolbarFrame->SetSnappedToWindow( bsActiveFrameName, WINDOW_CORNER_LEFT_BOTTOM, WINDOW_CORNER_CLIENT_LEFT_BOTTOM, 0, 0, true);
}

