// RsTemplateWindow.cpp : Implementation of CRsTemplateWindow

#include "stdafx.h"
#include "RsTemplateWindow.h"
#include "RpViewPackage.h"


// CRsTemplateWindow

LRESULT CRsTemplateWindow::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	CRect rcClient;
	GetClientRect(&rcClient);

	// edit control for object name
	CRect editRect(rcClient);
	editRect.bottom = EDIT_CTRL_HEIGHT;
	m_editCtrl.Create(this, NODE_NAME_CTRL, m_hWnd, &editRect, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 101);
	m_editCtrl.SetReadOnly(TRUE); 


	// main list  for connector descriptors
	CRect listRect(rcClient);
	listRect.top = EDIT_CTRL_HEIGHT + 1;
	m_listCtrl.Create(this, CON_DESCRIPTORS_CTRL, m_hWnd, &listRect, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 101);
	m_listCtrl.SetExtendedListViewStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);

	m_listCtrl.AddColumn(_T("Name"), 0);
	m_listCtrl.AddColumn(_T("Id"), 1);
	m_listCtrl.AddColumn(_T("Description"), 2);
	m_listCtrl.AddColumn(_T("Data Type"), 3);
	m_listCtrl.AddColumn(_T("Flags"), 4);

	// Set reasonable widths for columns.
	m_listCtrl.SetColumnWidth(0, 100);
	m_listCtrl.SetColumnWidth(1, 200);
	m_listCtrl.SetColumnWidth(2, 150);
	m_listCtrl.SetColumnWidth(3, 120);
	m_listCtrl.SetColumnWidth(4, 200);


	return 0;
}

LRESULT CRsTemplateWindow::OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
	CRect clientRect;
	GetClientRect(&clientRect);

	CRect editRect(clientRect);
	editRect.bottom = EDIT_CTRL_HEIGHT;
	m_editCtrl.SetWindowPos(NULL, editRect, SWP_NOZORDER | SWP_NOACTIVATE );

	CRect listRect(clientRect);
	listRect.top = EDIT_CTRL_HEIGHT + 1;
	m_listCtrl.SetWindowPos(NULL, listRect, SWP_NOZORDER | SWP_NOACTIVATE );

	return 0;
}

LRESULT CRsTemplateWindow::OnDestroy(UINT, WPARAM, LPARAM, BOOL&)
{
	// destory view
	DestroyView();
	return 0;
}


STDMETHODIMP CRsTemplateWindow::CreateView(HWND hWndParent, RECT* pRect, DWORD dwStyle, DWORD dwExStyle)
{
	CWindowImpl<CRsTemplateWindow>::Create(hWndParent,pRect ,NULL, dwStyle,dwExStyle);
	return S_OK;
}

STDMETHODIMP CRsTemplateWindow::DestroyView(void)
{
	CComQIPtr<IRsViewNode>	spViewNode = m_spViewNode;
	spViewNode->OnWndDestroy();
	m_spViewNode.Release();

	return S_OK;
}

STDMETHODIMP CRsTemplateWindow::GetHandle(HWND* phWnd)
{
	*phWnd = m_hWnd;
	return S_OK;
}

STDMETHODIMP CRsTemplateWindow::Update(IRsViewRenderData* pRenderData)
{
	m_spRenderData = pRenderData;

	LockWindowUpdate();
	UpdateControls(m_spRenderData);
	LockWindowUpdate(FALSE);

	InvalidateRect(NULL,0);
	return S_OK;
}


STDMETHODIMP CRsTemplateWindow::InitializeControl(IRsNode* pViewNode)
{
	// initialize internal structures
	m_spViewNode = pViewNode;
	return S_OK;
}

HRESULT CRsTemplateWindow::UpdateControls(IRsTemplateRenderData* pRenderData)
{
	// fill data
	if(pRenderData)
	{
		// node name
		CComBSTR bszNodeName;
		pRenderData->GetNodeName(&bszNodeName);
		CString szNodeName(bszNodeName);
		m_editCtrl.SetWindowText(szNodeName);


		// con descriptors
		RtUlong cNumConDesc;
		pRenderData->ConDescriptorCount(&cNumConDesc);
		m_listCtrl.DeleteAllItems();

		for(RtUlong i = 0; i < cNumConDesc; i++)
		{
			CComPtr<IRsConDescriptor>	spConDesc;
			if(S_OK == pRenderData->GetConDescriptorAt(i, &spConDesc))
			{
				AddDescriptorItem(i, spConDesc);
			}
		}
	}
	else
	{
		// empty
		m_listCtrl.DeleteAllItems();
		CString szNodeName(_T("<none>"));
		m_editCtrl.SetWindowText(szNodeName);
	}
	return S_OK;
}

	

HRESULT CRsTemplateWindow::AddDescriptorItem(int nItem, IRsConDescriptor* pConDesc)
{
	// name 
	CComBSTR bszClassName;
	pConDesc->GetName(&bszClassName);
	CString szName(bszClassName);
	m_listCtrl.AddItem(nItem, 0, szName);

	// id
	CONID	conId;
	pConDesc->GetConGUID(&conId);
	LPOLESTR str;
	::StringFromIID(conId ,&str);
	CString szConId(str);
	m_listCtrl.AddItem(nItem, 1, szConId);
	CoTaskMemFree(str);

	// description
	CComBSTR bszDescription;
	pConDesc->GetDescription(&bszDescription);
	CString	szDesc(bszDescription);
	m_listCtrl.AddItem(nItem, 2, szDesc);


	// data type
	CString szType;
	VARTYPE vartype;
	pConDesc->GetDataType(&vartype);

	switch(vartype)
	{
	case VT_UI1:
	case VT_UI2:
	case VT_UI4:
	case VT_UI8:
	case VT_UINT:
	case VT_I1:
	case VT_I2:
	case VT_I4:
	case VT_I8:
	case VT_INT:
		szType = "integer value";
		break;
	case VT_R4:
	case VT_R8:
		szType = "real value";
		break;
	case VT_BSTR:
		szType = "string value";
		break;
	case VT_BOOL:
		szType = "boolean";
		break;
	default:
		{
			CONID dataTypeID;
			pConDesc->GetDataTypeId(&dataTypeID);

			// Get system facory
			CComPtr<IRsSysFactory> spFactory;
			CRpViewPackage::GetSysFactory(&spFactory);

			CComPtr<IRsDataObject>    spDataObj;
			spFactory->CreateDataObj(&dataTypeID, &spDataObj);
			CComQIPtr<IRsObject>  spObj = spDataObj;
			if(spObj)
			{
				CComBSTR  bszClassName; 
				spObj->get_ClassName(&bszClassName);
				szType = bszClassName;
			}
			else
			{
				szType = "dummy";
			}

		}
		szType.Append(L" object");
		break;
	}
	m_listCtrl.AddItem(nItem, 3, szType);

	// flags

	CString szFlags;
	RtFlags ConFlags;
	pConDesc->get_DefaultFlags(&ConFlags);
	if(ConFlags & CONFLG_IN)
		szFlags.AppendFormat(_T("Input, "));
	if(ConFlags & CONFLG_OUT)
		szFlags.AppendFormat(L"Output, ");
	if(ConFlags & CONFLG_EXPORTED)
		szFlags.AppendFormat(L"Exported, ");
	if(ConFlags & CONFLG_HIDDEN)
		szFlags.AppendFormat(L"Hidden, ");
	if(ConFlags & CONFLG_CACHING)
		szFlags.AppendFormat(L"Caching, ");
	if(ConFlags & CONFLG_CONTROLFLOW)
		szFlags.AppendFormat(L"Control Flow, ");
	if(ConFlags & CONFLG_DISABLECACHING)
		szFlags.AppendFormat(L"Disable caching, ");
	if(ConFlags & CONFLG_REGISTERED)
		szFlags.AppendFormat(L"Global, ");
	if(ConFlags & CONFLG_CUSTOM)
		szFlags.AppendFormat(L"Custom, ");
	if(ConFlags & CONFLG_NONOTIFY)
		szFlags.AppendFormat(L"NoNotify, ");
	if(ConFlags & CONFLG_TOPOLOGY)
		szFlags.AppendFormat(L"Topology, ");
	if(ConFlags & CONFLG_LOCAL)
		szFlags.AppendFormat(L"Local, ");

	m_listCtrl.AddItem(nItem, 4, szFlags);

	return S_OK;
}
