#if !defined(D_tdoMaterialClass)
#error "define the class before including this file"
#endif

//================================================================================
//================================================================================
void vKillMaterialList(D_tdoMaterialClass *_p_oDummyArgToEnableOverLoading, CComboBox *_p_oReferencingCombo)
{																																																														
	_p_oDummyArgToEnableOverLoading = _p_oDummyArgToEnableOverLoading;

	CPA_List<CPA_BaseObject> oEditorObjectList;
	gs_p_oMaterialInterface->GetMainWorld()->fn_lFindObjects(																																	
		&oEditorObjectList,
		"", D_tdoMaterialClass::m_csGetMaterialType(),																																					
		NO_CRITERIA /* owner */																																																	
	);																																																												
	/* and destroy them all */																																																
	while ( !oEditorObjectList.IsEmpty() )																																										
	{																																																													
		D_tdoMaterialClass *p_oMaterial = (D_tdoMaterialClass *) oEditorObjectList.RemoveHead();																
		/* and delete the object, it will handle cohemngr links removal itself */
		delete p_oMaterial;																																																			
	}																																																													
	//reset the referencing combobox
	if ( _p_oReferencingCombo )
	{
		_p_oReferencingCombo->ResetContent();
		_p_oReferencingCombo->AddString(C_szNoMaterialComboEntry);
		_p_oReferencingCombo->SetItemDataPtr(0, NULL);
	}
}																																																														

//================================================================================
//================================================================================
#if defined(D_tdxEngineMaterialHandle)
void vRefreshMaterialList(
	long _lStartInLinkTable,
	D_tdoMaterialClass *_p_oDummyArgToEnableOverLoading, 
	BOOL _bSectionsAnalysedWithFullNames,
	CComboBox *_p_oReferencingCombo
)
{
	_p_oDummyArgToEnableOverLoading = _p_oDummyArgToEnableOverLoading;

	/* scan all loaded engine materials and associate editor materials to them...	*/
	SCR_tdst_Link_Value *p_stMaterialEntry;
	SCR_tdst_Link_Table *p_stMaterialLinkTable = D_tdoMaterialClass::m_p_stGetAssociatedLinkTable();
	CString csStatusMessage;
	csStatusMessage.Format("linking %d editor and engine materials", p_stMaterialLinkTable->stLinkArray.uiNumValues);
	/* start the scan	*/
	unsigned int uiMaterialPos = _lStartInLinkTable;
	SCR_M_DyAr_GetNextElement(
		SCR_tdst_Link_Value,
		uiMaterialPos,
		p_stMaterialEntry,
		p_stMaterialLinkTable->stLinkArray
	);
	/* while there are entries in the list */
	while ( p_stMaterialEntry )
	{
		fn_vGiveProgressInfo(
			csStatusMessage,
			(uiMaterialPos * 100) / p_stMaterialLinkTable->stLinkArray.uiNumValues
		);
		D_tdxEngineMaterialHandle hEngineMaterial = (D_tdxEngineMaterialHandle) SCR_M_ul_Link_GetValue(p_stMaterialEntry);
		//see if an editor material exists for this engine material (which means it was referenced somewhere)
		D_tdoMaterialClass *p_oInsertedMaterial = (D_tdoMaterialClass *) gs_p_oMaterialInterface->m_p_oGetEditorObjectForEngine(hEngineMaterial);
		if
		(
			SCR_M_e_Link_GetState(p_stMaterialEntry) == SCR_ELS_Link_Initialized
			&& !p_oInsertedMaterial //the engine material was not referenced
		)
		{ /* we did not find an editor material for the engine material */
			/* if we did not find a material with the engine, try to find one with the name, in case the script was	*/
			/* parsed and editor materials were created for unloaded sections -> they have no valid engine material */
			/* search OwnerFile */
			CPA_FileObject *p_oOwnerFile;
			CString csKey(SCR_M_p_sz_Link_GetKey(p_stMaterialEntry));
			CString csName(gs_p_oMaterialInterface->m_csGetFilePartOfSectionName(csKey));
			//create editor materials only if the file in which the engine material exists is of the good extension
			if ( !D_tdoMaterialClass::m_csGetScriptExtension().CompareNoCase(strrchr(LPCTSTR(csName), '.')) )
			{
				/* extract the id from the key */
				csKey = gs_p_oMaterialInterface->m_csGetIdPartOfSectionName(csKey);
				//this wont work if csName is a full name, so get the file from the full name instead.
				//that way we are sure to get a preexisting fileobject when there is one
				p_oOwnerFile = p_oGetFileObjectForReferencedPath(csName, C_szFileReferencedNameKey);
				if ( !p_oOwnerFile )
					p_oOwnerFile = p_oGetFileObjectForReferencedPath(csName, "");

				if ( p_oOwnerFile )
					p_oInsertedMaterial = (D_tdoMaterialClass *) gs_p_oMaterialInterface->GetBaseObject(
						csKey,
						D_tdoMaterialClass::m_csGetMaterialType(),
						p_oOwnerFile
					);

				if ( p_oInsertedMaterial )
				{
					/* give the engine material to the editor material */
					p_oInsertedMaterial->m_vAssociateEngineMaterial(hEngineMaterial, TRUE);
				}
				else
				{
					ASSERT(D_tdoMaterialClass::m_bIsEngineMaterialValid(hEngineMaterial));
					/* Create a new editor material to handle this engine material */
					//CString csPath(D_tdoMaterialClass::m_csGetBaseDataPath());
					if ( csName.Find('/') != -1 )
						AfxMessageBox(
							"Find where\n" + csKey + "\nis referenced and change all '/' characters to '\\'s", 
							MB_OK | MB_ICONSTOP
						);

					if ( p_oOwnerFile )
						p_oInsertedMaterial = new D_tdoMaterialClass(
							p_oOwnerFile,
							csKey,
							TRUE,
							hEngineMaterial
						);
				}
			}
		}
		if ( _p_oReferencingCombo && p_oInsertedMaterial )
		{
			CString csName = p_oInsertedMaterial->GetName();
			short wIndex = _p_oReferencingCombo->FindStringExact(-1, csName);
			if ( wIndex == CB_ERR ) //if the material is not already in the combo
			{ //add it
				wIndex = _p_oReferencingCombo->AddString(csName);
				_p_oReferencingCombo->SetItemDataPtr(wIndex, p_oInsertedMaterial);
			}
		}

		uiMaterialPos ++;
		SCR_M_DyAr_GetNextElement(
			SCR_tdst_Link_Value,
			uiMaterialPos,
			p_stMaterialEntry,
			p_stMaterialLinkTable->stLinkArray
		);
	}

	/* if all editor materials were destroyed, we have to parse the file again */
	/* to build editor materials for the remaining sections for all gmt files! */
	if ( gs_p_oMaterialInterface->m_eGetRefreshListMode() == E_rlm_DestroyAndRebuild )
	{
		CPA_BaseObjectList *p_oFileList = gs_p_oMaterialInterface->GetMainWorld()->fn_p_oGetOriginalObjectList(C_szFileTypeName);
		Position xPos = p_oFileList->GetHeadPosition();
		while ( xPos )
		{
			CPA_FileObject *p_oFileObject = (CPA_FileObject *) p_oFileList->GetNext(xPos);
			CString csName;
			//if the sections were analyzed with the full name, the file in which the scripts found them
			//is known with its long name as well, else it is known with its referenced name
			if ( _bSectionsAnalysedWithFullNames )
				csName = p_oFileObject->GetCompleteName();
			else
				csName = p_oFileObject->GetReferencedName(gs_p_oMaterialInterface, C_szFileReferencedNameKey);
			const char *pszName = LPCTSTR(csName);
			const char *pszNameExtension = strrchr((char*)pszName, '.');
			if 
			( 
				((pszNameExtension == NULL) ? FALSE : TRUE)
				&& (!(D_tdoMaterialClass::m_csGetScriptExtension().CompareNoCase(pszNameExtension)))
				&& (SCR_fn_c_RdL0_IsSectionExists((char *) pszName)) //the file must exist...
			)
			{
				/* now lets load the other sections in the script files that are not used by the engine */
				SCR_fn_v_RdL0_OpenFile((char*)pszName); //force file parsing, just in case
				SCR_tdst_File_Open *p_stFile = SCR_fnp_st_RdL0_GetOpenFile((char*)pszName);
				csStatusMessage.Format("creating %d unreferenced materials of %s", p_stFile->stSectionsDes.uiNumValues, pszName);
				//start the scan
				uiMaterialPos = 0;
				SCR_tdst_Anl_SectionDes *p_stSectionDesc;
				SCR_M_DyAr_GetNextElement(
					SCR_tdst_Anl_SectionDes,
					uiMaterialPos,
					p_stSectionDesc,
					p_stFile->stSectionsDes
				);
				while ( p_stSectionDesc )
				{
					fn_vGiveProgressInfo(csStatusMessage, (uiMaterialPos * 100) / p_stFile->stSectionsDes.uiNumValues);
					D_tdoMaterialClass *p_oInsertedMaterial = NULL;
					if ( !p_stSectionDesc->p_stOpenSection ) /* handle only sections that are not yet analyzed */
					{
						//find if an object with the same identification already exists (because we never know...)
						p_oInsertedMaterial = (D_tdoMaterialClass *) gs_p_oMaterialInterface->GetBaseObject(
							CString(p_stSectionDesc->stBuffers.p_szBufferNameExt), //to make sure the correct overload is specified
							D_tdoMaterialClass::m_csGetMaterialType(),
							p_oFileObject
						);
						//if we found one, the material that created it was not aware that the section existed,
						//so correct it now
						if ( p_oInsertedMaterial )
							p_oInsertedMaterial->SetExistingSection(TRUE);
						else //if we did not find such an editor object, create it
						{
							D_tdxEngineMaterialHandle hInvalidMaterial;
							D_tdoMaterialClass::m_vInvalidateEngineMaterial(hInvalidMaterial);
							p_oInsertedMaterial = new D_tdoMaterialClass(
								p_oFileObject,
								p_stSectionDesc->stBuffers.p_szBufferNameExt,
								TRUE,
								hInvalidMaterial
							);
							if ( _p_oReferencingCombo )
							{
								CString csName = p_oInsertedMaterial->GetName();
								short wIndex = _p_oReferencingCombo->FindStringExact(-1, csName);
								if ( wIndex == CB_ERR ) //if the material is not already in the combo
								{ //add it
									wIndex = _p_oReferencingCombo->AddString(csName);
									_p_oReferencingCombo->SetItemDataPtr(wIndex, p_oInsertedMaterial);
								}
							}
						}
					}
					uiMaterialPos ++;
					SCR_M_DyAr_GetNextElement(
						SCR_tdst_Anl_SectionDes,
						uiMaterialPos,
						p_stSectionDesc,
						p_stFile->stSectionsDes
					);
				} /* section loop */
				fn_vGiveProgressInfo(csStatusMessage, 100);
			} /* gmt file test */
		} /* gmt file loop */
	} /* destroy and rebuild test */
	fn_vGiveProgressInfo("", -1);
}
#endif

#undef D_tdoMaterialClass
#undef D_tdxEngineMaterialHandle
