// RsVPNodeFactory.cpp : Implementation of CRsVPNodeFactory

#include "stdafx.h"
#include "RsVPNodeFactory.h"
#include "RpViewPackage.h"

// nodes
#include "RnTemplateView.h"


STDMETHODIMP CRsVPNodeFactory::CreateInstance(const IID *riid, IRsNode** ppNode) 
{
	//define how to create each node
	BEGIN_NODE_MAP()
		NODE_ENTRY(riid, ppNode, IRnTemplateView, CRnTemplateView)
	END_NODE_MAP() 

	return E_INVALIDARG;
}


STDMETHODIMP CRsVPNodeFactory::CreateAggInstance(IUnknown* pUnkOuter, 
                                                  const IID * riid, IUnknown** ppvObject)
{
	return E_NOTIMPL;
}


STDMETHODIMP CRsVPNodeFactory::EnumNodeDesc(IRsEnumNodeDesc** ppEnumNodeDesc) 
{
	//define descriptors for each node
    BEGIN_NODE_DESC_MAP()
		NODE_DESC_ENTRY(IRnTemplateView,	CRpViewPackage, /* fill object descriptor*/ 0, 0, 0)
	END_NODE_DESC_MAP()

	typedef CComEnum<IRsEnumNodeDesc, &__uuidof(IRsEnumNodeDesc), IRsNodeDesc*, _CopyInterface<IRsNodeDesc> > CRsEnumNodeDesc;

	// system factory
	CComPtr<IRpKernel> spKernel;
	CRpViewPackage::GetKernelPackage(&spKernel);
	CComPtr<IRsSysFactory> spFactory;
	HRESULT hr = spKernel->GetSysFactory(&spFactory);
	if (FAILED(hr))	
        return hr;

	CComObject<CRsEnumNodeDesc>* pEnum;
	hr = CComObject<CRsEnumNodeDesc>::CreateInstance(&pEnum);
	if (FAILED(hr)) 
		return hr;

	// number of the items in the descriptor array
	RtUlong lastIndex = sizeof(_nodeDesc) / sizeof(_nodeDesc[0]);

	// initialize array
	CInterfaceArray<IRsNodeDesc>	arrayDesc;

	// fill array
	for (RtUlong i = 0; i< lastIndex; i++)
	{
		// create descriptor instance
		CComPtr<IRsNodeDesc>	spNodeDesc;
		spFactory->CreateNodeDesc(&spNodeDesc);

		// initialize descriptor
		spNodeDesc->Initialize(&_nodeDesc[i]);

		// add it to array
		arrayDesc.Add(spNodeDesc);
	}

	// initialize enumerator so that caller takes ownership of the array
	hr = pEnum->Init((IRsNodeDesc**)&arrayDesc[0].p, 
		(IRsNodeDesc**)&arrayDesc[lastIndex-1].p, NULL ,AtlFlagCopy  );

	if (SUCCEEDED(hr)) 
		hr = pEnum->QueryInterface(ppEnumNodeDesc);
	return hr;
}

STDMETHODIMP CRsVPNodeFactory::EnumConDesc(IRsEnumConDesc** ppEnumConDesc)
{
	return E_NOTIMPL;
}
