//===========================================================================//
// File:	D3DRMVideoRenderables.cpp                                        //
// Project: MUNGA           Brick: Win95 Video Renderer 	                 //
// Contents: Windows95 Layer Video Renderer									 //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 03/13/97  JTR  Initial coding.                                            //
//---------------------------------------------------------------------------//
// Copyright (C) 1997, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#include "AdeptHeaders.hpp"

#include "VideoHeaders.hpp"

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
LODComponent::ClassData*
	LODComponent::CreateFactoryRequest(FactoryRequestParameters *parameters)
{
	Check_Object(parameters);

	//
	//-------------------------------------------------------------------------
	// Allocate enough room for what we need to write out, then call our parent
	//-------------------------------------------------------------------------
	//
	MemoryStream *component_stream = parameters->m_stream;
	Check_Object(component_stream);
	component_stream->AllocateBytes(sizeof(LODComponent));
	bool result = BaseClass::CreateFactoryRequest(parameters) != NULL;

	//
	//----------------------------------------
	// Set up a name list for all the children
	//----------------------------------------
	//
	Page *page = parameters->m_page;
	Check_Object(page);
	DynamicArrayOf<ComponentDescriptor> *component_names = parameters->m_components;
	Check_Object(component_names);
	ChainOf<Note*> *children_chain = page->MakeNoteChain("Child");
	Check_Object(children_chain);
	Page::NoteIterator children(children_chain);
	ChainOf<Note*> *ranges_chain = page->MakeNoteChain("Range");
	Check_Object(ranges_chain);
	Page::NoteIterator ranges(ranges_chain);

	//
	//-----------------------------------
	// Write out the number of lod ranges
	//-----------------------------------
	//
	int range_count = Min(children.GetSize(), ranges.GetSize());
	*component_stream << range_count;

	//
	//-----------------------------------------------------------
	// Loop through the children, making sure we can hook them up
	//-----------------------------------------------------------
	//
	Note *child = children.ReadAndNext();
	Note *range = ranges.ReadAndNext();
	int child_id = -1;
	while (child && range)
	{
		//
		//------------------------------------
		// Find the child and write out its ID
		//------------------------------------
		//
		Check_Object(child);
		const char* child_name;
		child->GetEntry(&child_name);
		Check_Pointer(child_name);
		child_id = ComponentDescriptor::FindName(component_names, parameters->m_index, child_name);
		if (child_id == -1)
		{
			STOP((
				"%s: {[%s]Child=%s}: Unknown component name!",
				page->GetNotationFile()->GetFileName(),
				page->GetName(),
				child_name
			));
			result = false;
		}
		else
		{
			Component::ClassData* class_data = (*component_names)[child_id].m_classData;
			Check_Object(class_data);
			if (!class_data->IsDerivedFrom(VideoComponent::DefaultData))
			{
				STOP((
					"%s: {[%s]Child=%s}: Child is not a VideoComponent component!",
					page->GetNotationFile()->GetFileName(),
					page->GetName(),
					child_name
				));
				result = false;
			}
		}
		*component_stream << child_id;

		//
		//---------------------
		// Write out the ranges
		//---------------------
		//
		Check_Object(range);
		const char* range_values = NULL;
		range->GetEntry(&range_values);
		Check_Pointer(range_values);
		Scalar n,f;
		sscanf(range_values, "%f %f", &n, &f);
		n *= n;
		f *= f;
		*component_stream << n << f;
		child = children.ReadAndNext();
		range = ranges.ReadAndNext();
	}

	//
	//---------------------------------------------------------------
	// Make sure to always write the null ID to stop the child stream
	//---------------------------------------------------------------
	//
	Check_Object(ranges_chain);
	delete ranges_chain;
	Check_Object(children_chain);
	delete children_chain;
	Check_Object(DefaultData);
	return (result) ? DefaultData : NULL;
}
