/****************************************************************************************
		ModelerProp.cpp
		(c)1990-1999 MetaCreations.

		Properties Palette of the Modeler

		Author:	Jerome Bignon

		Date:	06/01/99

		Revision History

		when		who			what & why
		==========	==========	======================================================
		06/27/99	cph			added include for MCCountedPtrHelper.h
		06/11/99	Jerome		Added animation and saving
		06/01/99	Jerome		Creation
*****************************************************************************************/


#include "ModelerProp.h"
#include "Modeler.h"
#include "ModelerActions.h"
#include "ModelerDef.h"
#include "COM3DUtilities.h"
#include "COMSafeUtilities.h"
#include "COMUtilities.h"
#include "PublicUtilities.h"
#include "I3DShUtilities.h"
#include "IShUtilities.h"
#include "IMFPart.h"
#include "I3DShModule.h"
#include "IMFResponder.h"
#include "MFPartMessages.h"
#include "MCCountedPtrHelper.h"



ModelerProp::ModelerProp(IPropertiesModule* 	inPropertiesModule, 
						Modeler* 		modeler)
{
	fModeler = modeler;
	fPropertiesModule = inPropertiesModule;

	gShell3DUtilities->GetImmediateUpdateChannel(&fImmediateUpdateChannel);
	if (fImmediateUpdateChannel)
		fImmediateUpdateChannel->RegisterListener(this);
}

ModelerProp::~ModelerProp()
{
	fImmediateUpdateChannel->UnregisterListener(this);

}


MCCOMErr ModelerProp::QueryInterface(const MCIID& riid, void** ppvObj)
{
	if (MCIsEqualIID(riid, IID_IPropertiesClient)) 
	{
		TMCCountedGetHelper<IPropertiesClient> result(ppvObj);
		result = this;
		return MC_S_OK;
	}

	if (MCIsEqualIID(riid, IID_IChangeListener)) 
	{
		TMCCountedGetHelper<IChangeListener> result(ppvObj);
		result = this;
		return MC_S_OK;
	}

	return TBasicUnknown::QueryInterface(riid, ppvObj);
}


uint32 ModelerProp::AddRef()
{
	return TBasicUnknown::AddRef();
}


void ModelerProp::DataChanged(IChangeChannel* 	channel, 
									IDType 					changeKind, 
									IMCUnknown* 			changedData)
{
	TMCCountedPtr<I3DShModule> shModule;
	fPropertiesModule->QueryInterface(IID_I3DShModule, (void **)&shModule);

	if (!shModule->GetIsHydrated())
		return;

	if (channel == fImmediateUpdateChannel)
	{
		TMCCountedPtr<IMFPart> hostPart;
		fPropertiesModule->GetHostPart(&hostPart);

		if (hostPart)
			hostPart->ProcessUpdatesPart();
	}
}


IDType ModelerProp::GetControllingModuleID()
{
	return kModelerID;

}


ResourceID MCCOMAPI	ModelerProp::GetPropResID()
{
	return 200; 
}

void MCCOMAPI ModelerProp::GetSelectionChannel(IChangeChannel** outChannel)
{
	fModeler->GetSelectionChannel(outChannel);
}



void MCCOMAPI ModelerProp::LoadPageData(IMFPart* 			inTopPart)
{
	TMCCountedPtr<ITreePrim>		treePrim;
	TMCCountedPtr<IMFPart>			textPart;
	TMCCountedPtr<TreeData>			treeData;						

	treePrim = fModeler->GetTreePrimNoAddRef();
	treePrim->GetData(&treeData);

	inTopPart->FindChildPartByID(&textPart, 'Bran');
	MCAssert(textPart);
	textPart->SetValue(&(treeData->fNbBranches), kInt16ValueType, true, true);

	inTopPart->FindChildPartByID(&textPart, 'Angl');
	MCAssert(textPart);
	textPart->SetValue(&(treeData->fAngle), kReal32ValueType, true, true);

	inTopPart->FindChildPartByID(&textPart, 'Step');
	MCAssert(textPart);
	textPart->SetValue(&(treeData->fRecursiv), kInt16ValueType, true, true);

	fPropertiesModule->SetCurrentSelectionType(GetPropResID());	// It is weird to have to do this
}

boolean MCCOMAPI ModelerProp::HandlePageHit(
											IMFPart*			inTopPart,
											int32				inMessage,
											IMFResponder*		inSource,
											void*				inData)
{
	boolean					result = false;
	TMCCountedPtr<TreeData>	treeData;						

	fModeler->GetTreePrimNoAddRef()->GetData(&treeData);

	if (inMessage == EMFPartMessage::kMsg_OutOfScopePartValueChanged)
	{
		TMCCountedPtr<IMFPart>		topPart;
		IDType						sourceID;
		TMCCountedPtr<IMFPart>		sourcePart;

		inSource->QueryInterface(IID_IMFPart, (void**) &sourcePart);
		ThrowIfNil(sourcePart);
		sourceID = sourcePart->GetIMFPartID();

		if (inTopPart)
		{
			topPart = inTopPart;
		}
		else
		{
			TMCCountedPtr<IMFPart>	part;
			inSource->QueryInterface(IID_IMFPart, (void**) &part);
			ThrowIfNil(part);
			part->GetPartParentWindow(&topPart);
		}
	
		TMCCountedPtr<IMFPart>		textPart;
		if ((sourceID == 'Bran')||(sourceID == 'Angl')||(sourceID == 'Step'))
		{
			topPart->FindChildPartByID(&textPart, 'Bran');
			MCAssert(textPart);
			textPart->GetValue(&(treeData->fNbBranches), kInt16ValueType);

			topPart->FindChildPartByID(&textPart, 'Angl');
			MCAssert(textPart);
			textPart->GetValue(&(treeData->fAngle), kReal32ValueType);

			topPart->FindChildPartByID(&textPart, 'Step');
			MCAssert(textPart);
			textPart->GetValue(&(treeData->fRecursiv), kInt16ValueType);
		}

		//-- Now that we have the values, let's create the action
		TMCCountedPtr<IShAction> action;
		TMCCountedPtr<IMFResponder> context;
		TMCCountedPtr<IMFDocument> Doc;
		Doc = fModeler->GetDocNoAddRef();
		Doc->QueryInterface(IID_IMFResponder, (void**) &context);

		ModelerAction::Create( &action, treeData, fModeler );
		gActionManager->PostAction(action, 0, context);
		result = true;
	}
	return result;
}


void ModelerProp::GetExtraPart(IMFPart** outExtraPart)
{
	TMCCountedGetHelper<IMFPart> result(outExtraPart);
	result = static_cast<IMFPart*>(NULL);
}