
fn isolated_CHRPARAMS_Attribs \
											isolated_Node: =
(	
	if isolated_Node.count == 2 then
	(
		for i=1 to isolated_Node.count do
		(
			attribName 		= isolated_Node[i][1]
			attribVal		 	= isolated_Node[i][2]
			
			--i==1 because "name" should always come before "path"
			if (stricmp attribName "name") == 0 AND \
				i == 1 then
			(
				case of
				(
					--If we discover more tokens, then we will add them, but these are all I have found so far.
					--In newer versions of CryEngine, I think the .caf files will be deprecated, but they are still used as ***on-demand assets***
					
					( stricmp attribVal "$TracksDatabase" == 0)	:
					(
						TracksDatabase 			= isolated_Node[i+1][2]
						TracksDatabase_path 	= pathConfig.resolvePathSymbols (pathConfig.AppendPath ::g_dirPath TracksDatabase) --build full path
						format "TracksDatabase_path ($TracksDatabase): %\n" TracksDatabase_path						
					)
					( stricmp attribVal "#filepath" == 0):
					(
						filepath 			= isolated_Node[i+1][2]
						filepath_path 	= pathConfig.resolvePathSymbols (pathConfig.AppendPath ::g_dirPath filepath) --build full path
						format "filepath_path (#filepath): %\n" filepath_path
					)
					( stricmp attribVal "$AnimEventDatabase" == 0):
					(
						AnimEventDatabase 			= isolated_Node[i+1][2]
						AnimEventDatabase_path 	= pathConfig.resolvePathSymbols (pathConfig.AppendPath ::g_dirPath AnimEventDatabase) --build full path
						format "AnimEventDatabase_path ($AnimEventDatabase): %\n" AnimEventDatabase_path
					)
					( stricmp attribVal "\x2A" == 0): -- \x2A == *
					(
						CAF_pattern 			= isolated_Node[i+1][2]						
						format "CAF_pattern: %\n" CAF_pattern
					)
					default:
					(
						CAF_File 			= isolated_Node[i+1][2]
						CAF_File_path 	= pathConfig.resolvePathSymbols (pathConfig.AppendPath ::g_dirPath CAF_File) --build full path
						format "CAF_File_path: %\n" CAF_File_path
					)					
				)
			)
		)
	)
	
)

fn populate_Animation_Tracks =
(
	local arr 			= #()
	local chrParams 	= ::g_inst_CHRPARAMS_Attribs	
	local unique_nodeIDs = #()
				
	for i=1 to chrParams.count do
	(
		local nodeID = 0		
		nodeID = chrParams[i].nodeID		
		AppendifUnique unique_nodeIDs nodeID
	)
	
	for i=1 to unique_nodeIDs.count do
	(			
		local UnodeID = unique_nodeIDs[i]		
		local isolated_Node = #()
		local nTagString = ""
		
		if ::rollout_Report.chk_Anim_Report.state then ( print "//////////////////////////////////////////////\n" ) --report
		for idx=1 to chrParams.count do
		(
			if chrParams[idx].nodeID == UnodeID then
			(
				local attribName 		= chrParams[idx].attribName[1]
				local attribVal			= chrParams[idx].attribVal[1]
				
				nTagString 				= chrParams[idx].nTagString
				
				Append isolated_Node #(attribName, attribVal)
				
				if ::rollout_Report.chk_Anim_Report.state then --report
				(				
					print chrParams[idx].nodeID
					print chrParams[idx].nTagString
					print chrParams[idx].attribName[1]
					print chrParams[idx].attribVal[1]
				)				
			)
		)
		if ::rollout_Report.chk_Anim_Report.state then ( print "\n" ) --report
		
		if (stricmp nTagString "Animation") == 0 then
		(
			print "//////////////////////////////////////////////\n"		
			isolated_CHRPARAMS_Attribs \
													isolated_Node:isolated_Node
			print "\n"
		)
	)	
)

fn load_CHRPARAMS_into_List =
(
	------------------------------------------------------------------------------
	try
	(
		RemoveRollout  	::rollout_AnimationTracks 		::CRYOP			
	)
	catch
	()
	rollout rollout_AnimationTracks "Animation Tracks" width:290 height:20 category:5
	(
		dropdownList 'ddl_Animation_Tracks' "Animation Tracks" pos:[8,20] width:265 height:30 items:#() align:#left
			
		on rollout_AnimationTracks open do
		(
			populate_Animation_Tracks ()
				
-- 			ddl_Animation_Tracks.items = populate_Animation_Tracks()
		)
	)				
	AddRollout  	::rollout_AnimationTracks 		::CRYOP rolledUp:true		
	------------------------------------------------------------------------------
)

fn CAF_read \
					caller: \
					g_cryFile: =
(
	load_global_CAF_arrays()	
	-----------------------------------------------------------------------------------
	inst_GAHCAF_PROCESSOR = GAHCAF_PROCESSOR()
	inst_GAHCAF_PROCESSOR.load_CAF \
													caller:caller \
													CAF_file:g_cryFile
	-----------------------------------------------------------------------------------
	store_global_CAF_arrays \
										fileType:(getFilenameType g_cryFile)
	set_CAF_states \
							type:(getFilenameType g_cryFile)
)

fn cryFile_loader \
						Binding_BOOL: \						
						&g_cryFile: \
						caller: \
						&mtlFile: \
						&assetName_From_CDF: \
						&inst_Sub_Meshes: \
						&inst_CDF_Model: \
						&inst_CDF_Attachment: \
						&inst_CDF_Modifiers: =
(
	if caller == "CAF" OR \
		caller == ".caf" then
	(		
		CAF_read \
						caller:caller \
						g_cryFile:g_cryFile
		
	)
	else if caller == "IMG" OR \
				caller == ".img" then
	(
		CAF_read \
						caller:caller \
						g_cryFile:g_cryFile
	)
	else
	(
		Reset_Arrays()
		
		--The other filepaths - we later check if they do indeed exist
		local g_cryFile_m 					= (g_cryFile as string) + "m"
		local g_cryFile_chrparams 		= (g_cryFile as string) + "params"		
		if NOT doesfileexist g_cryFile_m then
		(
			setINISetting 	::g_iniFile 	"fileType" 	"fileType2" 	"" --we will use this for loading the material xmlB
		)
		else
		(
			setINISetting 	::g_iniFile 	"fileType" 	"fileType2" 	(getFilenameType g_cryFile_m) --we will use this for loading the material xmlB
		)

		--//////////////////////////////////////////////////////////////////////////////////
		setINISetting 	::g_iniFile 	"paths" 		("g_cryFile"+(getFilenameType g_cryFile)) 			g_cryFile
		setINISetting 	::g_iniFile 	"paths" 		("last_loaded") 												g_cryFile --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"paths" 		("first_loaded") 												g_cryFile --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"fileType" 	("fileType1") 													(getFilenameType g_cryFile) --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"fileType" 	("fileType2_loaded") 										"false" --we set this to true later if it has been read
		
		--We reset some of the properties of the struct ( but we leave the CA_SKIN_counter untouched, because we want to keep track of the index of the loadable skins in each CDF 
		inst_Sub_Meshes.nStream										= #()
		inst_Sub_Meshes.nCount										= #()	
		inst_Sub_Meshes.subMeshes 									= #()
		inst_Sub_Meshes.SKINBONES_FROM_0xCCCC0017 		= #()
		
		if caller != "CDF" then
		(
			--Why do we increment the CA_SKIN_counter here? We found no CA_SKIN?
			--Well, because the old CryEngine used .chr for character etc (not CDF) thus some files are still legacy and incrementing
			--here we force treating this as a legacy character file	
			--we set it to 1 because obviously we are loading from a single file!
			-------------------------------------------------------------------------------------------
			inst_Sub_Meshes.CA_SKIN_counter = 1
			-------------------------------------------------------------------------------------------
		)
		
		--Report
		format "loading: %\n" g_cryFile

		load_global_arrays()
		--//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//
		g_bs = fopen g_cryFile "rb" --open binary stream
		--///////////////////////////////////////////////////////////////////////////////////
		load_cryFile \	
							currFileType: 						(getFilenameType g_cryFile) \
							bstream:							&g_bs \
							mtlFile:								&mtlFile \ -----
							g_cryFile_m:						&g_cryFile_m \ -----
							inst_Sub_Meshes:				&inst_Sub_Meshes \
							inst_CDF_Model:					&inst_CDF_Model \
							inst_CDF_Attachment:			&inst_CDF_Attachment \
							inst_CDF_Modifiers:				&inst_CDF_Modifiers
		--///////////////////////////////////////////////////////////////////////////////////
		fclose g_bs	--Close & Flush Binary Stream
		--//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//
		
		
		--Try to execute this in the Builders
		--/*
		--Now we attempt to load the mesh version of the file above - in Ryse(at least), the file suffixes have an *m* added to the suffix		
		if doesfileexist g_cryFile_m then
		(
			--//////////////////////////////////////////////////////////////////////////////////
			setINISetting 	::g_iniFile 	"paths" ("g_cryFile"+(getFilenameType g_cryFile_m)) 	g_cryFile_m
			setINISetting 	::g_iniFile 	"paths" ("last_loaded") 												g_cryFile_m --we will use this for loading the material xmlB
			setINISetting 	::g_iniFile 	"fileType" ("fileType2") 												(getFilenameType g_cryFile_m) --we will use this for loading the material xmlB			
			
			
			--We reset some of the properties of the struct ( but we leave the CA_SKIN_counter untouched, because we want to keep track of the index of the loadable skins in each CDF 
			inst_Sub_Meshes.nStream										= #()
			inst_Sub_Meshes.nCount										= #()	
			inst_Sub_Meshes.subMeshes 									= #()
			inst_Sub_Meshes.SKINBONES_FROM_0xCCCC0017 		= #()

			if caller != "CDF" then
			(
				--Why do we increment the CA_SKIN_counter here? We found no CA_SKIN?
				--Well, because the old CryEngine used .chr for character etc (not CDF) thus some files are still legacy and incrementing
				--here we force treating this as a legacy character file	
				--we set it to 1 because obviously we are loading from a single file!
				-------------------------------------------------------------------------------------------
				inst_Sub_Meshes.CA_SKIN_counter = 1
				-------------------------------------------------------------------------------------------
			)	
			
			--Report
			format "loading: %\n" g_cryFile
			
			load_global_arrays()			
			--//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//
			g_bs = fopen g_cryFile_m "rb" --open binary stream
			--///////////////////////////////////////////////////////////////////////////////////
			load_cryFile \
								currFileType: 					(getFilenameType g_cryFile_m) \
								bstream:						&g_bs \
								mtlFile:							&mtlFile \								
								inst_Sub_Meshes:			&inst_Sub_Meshes \
								inst_CDF_Model:				&inst_CDF_Model \
								inst_CDF_Attachment:		&inst_CDF_Attachment \
								inst_CDF_Modifiers:			&inst_CDF_Modifiers
			--///////////////////////////////////////////////////////////////////////////////////							
			fclose g_bs	--Close & Flush Binary Stream
			--//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//-//

			--Just for info, can be taken out
			setINISetting ::g_iniFile "fileType" ("fileType2_loaded") "true" --we set this to true so that we can go back and read bones in the first file			
		)	
		
		
		if ::rollout_Report.chk_Store_Report.state then --default is off
		(
			--Just for info
			try
			(			
				----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
				store_report ()	
				if ::g_Mesh_Report then ( report() )
				----------	----------	----------	----------	----------	----------	----------	----------	----------	----------			
			)
			catch()	
		)		
		
		
		
		------------------ Try to read *.charparams if it exists (we read it here, but will use it later when and if we process the .caf ------------------		
		if doesfileexist g_cryFile_chrparams then
		(
			::g_inst_CHRPARAMS_Attribs 			= #() --reset global array
			
			format "g_cryFile_chrparams: %\n" g_cryFile_chrparams
			
			inst_xmlB_PROCESSOR = xmlB_PROCESSOR()
			inst_xmlB_PROCESSOR.cry_CDF_xmlB_ASSETS_loader_ReaderV \
																								CDF_File:				&g_cryFile_chrparams \
																								inst_s_OPTIONS:		&inst_s_OPTIONS \
																								type:						(getFilenameType g_cryFile_chrparams)
		)
		
		if ::rollout_Report.chk_Store_Report.state then --default is off
		(
			--Just for info
			-------------------------------------------------------------------------------------------------------------------------------------------------------------
			try
			(	
				----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
				store_report ()	
				if ::g_Mesh_Report then ( report() )
				----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
			)
			catch()
		)
	)	
)

fn cryFile_Crysis_loader \	
								g_cryFile: \
								caller: \
								mtlFile: \
								assetName_From_CDF: =
(
	if caller == "CAF" OR \
		caller == ".caf" then
	(		
		CAF_read \
						caller:caller \
						g_cryFile:g_cryFile
		
	)
	else if caller == "IMG" OR \
				caller == ".img" then
	(
		CAF_read \
						caller:caller \
						g_cryFile:g_cryFile
	)
	else
	(
		Reset_Arrays()
		
		--//////////////////////////////////////////////////////////////////////////////////
		setINISetting 	::g_iniFile 	"paths" 		("g_cryFile"+(getFilenameType g_cryFile)) 		g_cryFile
		setINISetting 	::g_iniFile 	"paths" 		("last_loaded") 											g_cryFile --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"paths" 		("first_loaded") 											g_cryFile --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"fileType" 	("fileType1") 												(getFilenameType g_cryFile) --we will use this for loading the material xmlB
		setINISetting 	::g_iniFile 	"fileType" 	("fileType2_loaded") 									"false" --we set this to true later if it has been read
		--*/	
			
		load_global_arrays()
		-----------------------------------Load--------------------------------------
		g_bs = fopen g_cryFile "rb" --open binary stream

		--//////////////////////////
		load_cryFile bstream:g_bs						
		--//////////////////////////					
		
		--------------------------------End of Load---------------------------------
		fclose g_bs	--Close & Flush Binary Stream
			
		store_global_arrays fileType:(getFilenameType g_cryFile)			
		
		
		/*
		------------------ Try to read *.charparams if it exists (we read it here, but will use it later when and if we process the .caf ------------------
		local g_cryFile_chrparams 				= g_cryFile + "params"
		if doesfileexist g_cryFile_chrparams then
		(
			::g_inst_CHRPARAMS_Attribs 			= #() --reset global array
			
			format "g_cryFile_chrparams: %\n" g_cryFile_chrparams
			
			inst_xmlB_PROCESSOR = xmlB_PROCESSOR()
			inst_xmlB_PROCESSOR.cry_CDF_xmlB_ASSETS_loader_ReaderV \
																								CDF_File:				&g_cryFile_chrparams \
																								inst_s_OPTIONS:		&inst_s_OPTIONS \
																								type:						(getFilenameType g_cryFile_chrparams)
		
		)
		-------------------------------------------------------------------------------------------------------------------------------------------------------------
		
				
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
		store_report ()	
		if ::g_Mesh_Report then
		(
			report()
		)
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
		--/////////////////////////////////////////////////////////////////////////////////	
		
		--Now we attempt to load the mesh version of the file above - in Ryse(at least), the file suffixes have an *m* added to the suffix
		g_cryFile_m = (g_cryFile + "m")	

		if doesfileexist g_cryFile_m then
		(
			--//////////////////////////////////////////////////////////////////////////////////
			setINISetting 	::g_iniFile 	"paths" ("g_cryFile"+(getFilenameType g_cryFile_m)) 	g_cryFile_m
			setINISetting 	::g_iniFile 	"paths" ("last_loaded") 												g_cryFile_m --we will use this for loading the material xmlB
			setINISetting 	::g_iniFile 	"fileType" ("fileType2") 												(getFilenameType g_cryFile_m) --we will use this for loading the material xmlB
						
			load_global_arrays()
			-----------------------------------Load--------------------------------------
			g_bs = fopen g_cryFile_m "rb" --open binary stream			

			--//////////////////////////
			load_cryFile bstream:&g_bs
			--//////////////////////////		
							
			fclose g_bs	--Close & Flush Binary Stream
			--------------------------------End of Load---------------------------------				
			
			store_global_arrays 		fileType:	(getFilenameType g_cryFile_m)
			set_modelStates 			type:			(getFilenameType g_cryFile_m)
			
			--//////////////////////////////////// Build Bones ////////////////////////////////////	
			if NOT ::g_Dont_Load_Skeleton then
			(
				local has_bones = getINISetting ::g_iniFile "boneinfo" "has_bones" --this will tell us if there are bones present
				
				--Only if there are bones present, we try to build the bones
				if (stricmp has_bones "true") == 0 then
				(
					inst_create_bones = create_bones() --create struct
					if ::g_Create_Bones_Report then ( inst_create_bones.Create_Bones_Report = true )			

					inst_create_bones.CONSTRUCT_BONES \
																				LOADED:	&::_LOADED \
																				LOADEDm:	&::_LOADEDm				
				)
				
				--Once we are done with the bones methods, we set the *has_bones* back to false
				setINISetting 	::g_iniFile 	"boneinfo" "has_bones" 	"false"	
			)
			--/////////////////////////////////////////////////////////////////////////////////
			
			if mtlFile == unsupplied then
			(				
				--Note, for .cgf(m) we do not supply a g_cryFile, because the .mtl name will be loaded from within the .cgfm file, from the chunk 0xCCCC0014
				--on the other hand, if we were loading from a Character Definition File (.cdf) then we would supply the file we read from within the .cdf
				cryxmlB_loader \
										g_MaterialRef_Bool:		&g_MaterialRef_Bool \
				
			)
			else
			(
				if mtlFile != undefined then
				(				
					if doesfileexist mtlFile then
					(
						cryxmlB_loader \
												g_MaterialRef_Bool:		&g_MaterialRef_Bool \
												mtlFile:mtlFile
					)
				)
			)
		)		
		--*/
		
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------		
		store_report ()
		if ::g_Mesh_Report then
		(
			report()
		)
		----------	----------	----------	----------	----------	----------	----------	----------	----------	----------
	)	
)

struct CDF_Model
(
	n_File 			= "",
	n_Material 		= ""
)

struct CDF_Attachment
(
	n_File		 			= "",
	n_Material 			= "",
	n_Type 				= "",
	n_AName 			= "",							
	n_Binding 			= "",
	n_LodDistances 	= "",
	n_Flags			 	= "",
	
	---HFR---
	n_BoneName			= "",
	n_Rotation				= "",
	n_Position				= ""
)

struct CDF_Modifiers
(
	n_node				= "",
	n_value				= "",
	
	fn _set \
			&nTagString: \
			&attribName: \
			&attribVal: =
	(
		if (stricmp attribName "value" == 0) then
		(
			n_node			= nTagString
			n_value			= attribVal
		)
	)
)

fn mtlName_deepCheck \
									&_Material_: =
(
	if _Material_ != unsupplied then
	(
		if _Material_ != undefined then
		(
			if NOT doesfileexist _Material_ then
			(
				check_4_mtl_suffix \
											filePath:&_Material_
				
				local newMtlBuild 		= ""
				local finalMtlPath 		= ""
								
				local mtlDir 				= getFilenamePath _Material_					
				local stringFiltered 		= filterString (filenameFromPath _Material_) "_"
								
				for i=1 to stringFiltered.count do
				(
					subS 					= stringFiltered[i]
									
					if ((stricmp subS "mat.mtl") == 0) OR \
						(matchpattern subS pattern:"*_mat") then
					(
						newMtlBuild = ""
						for s=1 to stringFiltered.count do
						(
							if s != i then
							(
								newMtlBuild += stringFiltered[s] 
							)
						)
					)
				)		
					
				finalMtlPath = pathConfig.ResolvePathSymbols (pathConfig.AppendPath mtlDir (newMtlBuild + ".mtl"))				
				
				if doesfileexist finalMtlPath then
				(
					_Material_ = finalMtlPath
				)				
			)
		)
	)
)

fn CHR_LOADER \						
						caller: "CDF"	\
						&mtlFile: \
						&inst_Sub_Meshes: \
						&inst_CDF_Model: \
						&inst_CDF_Attachment: \
						&inst_CDF_Modifiers: =
(
	if inst_CDF_Model != unsupplied then
	(
		if inst_CDF_Model != undefined then
		(
			--The .chr is for newer cryengine versions just a helper and proxy skeleton, for import into max, we should not need it

			--Why do we increment the CA_SKIN_counter here? We found no CA_SKIN?
			--Well, because the old CryEngine used .chr for character etc (not CDF) thus some files are still legacy and incrementing
			--here we force treating this as a legacy character file			
			inst_Sub_Meshes.CA_SKIN_counter += 1
				
			--///////////////////////////////////// Load Model file (which contains the .chr) /////////////////////////////////////				
			if  NOT (Binary_CryTek_check File:inst_CDF_Model.n_File) then --if the xml file is not Crytek Binary XML
			(
				if ::g_CDF_Report then ( format "This is not a valid CryTek file, aborting!\n" ) --report
			)
			else
			(
				if ::g_CDF_Report then ( format "We will now attempt to load _File_: % ...\n" _File_ )	--report
					
				if (Binary_XML_check _Material_) then
				(			
					cryFile_loader \										
										inst_Sub_Meshes: 			&inst_Sub_Meshes \
										g_cryFile:						&inst_CDF_Model.n_File \
										caller:							"CDF"	\
										mtlFile:							&mtlFile \
										inst_CDF_Model:				&inst_CDF_Model \
										inst_CDF_Attachment: 		&inst_CDF_Attachment
				)
				else
				(
					cryFile_loader \
										inst_Sub_Meshes: 			&inst_Sub_Meshes \
										g_cryFile:						&inst_CDF_Model.n_File \
										caller:							"CDF" \
										inst_CDF_Model:				&inst_CDF_Model \
										inst_CDF_Attachment: 		&inst_CDF_Attachment
				)

					/* --Are we already doing this inside cryFile_loader?
					------------------ Try to read *.charparams if it exists (we read it here, but will use it later when and if we process the .caf ------------------
					local g_cryFile_chrparams 				= _File_ + "params"
					if doesfileexist g_cryFile_chrparams then
					(
						::g_inst_CHRPARAMS_Attribs 			= #() --reset global array
						
						format "g_cryFile_chrparams: %\n" g_cryFile_chrparams
						inst_xmlB_PROCESSOR.cry_CDF_xmlB_ASSETS_loader_ReaderV \
																											CDF_File:				&g_cryFile_chrparams \
																											inst_s_OPTIONS:		&inst_s_OPTIONS \
																											type:						(getFilenameType g_cryFile_chrparams)
						
						
						 load_CHRPARAMS_into_List ()			
						
						--Perhaps we should load the .dba for each file into the list instead
						--And if there is no .dba, there should be pure .caf files to load into the list
						
						--We should do all the CAF loading in here
						--Above we have read the .chrparams
						
						--So having read the .chrparams, we check and look for the .img and .dba inside the struct which we appended to this global array ::g_inst_CHRPARAMS_Attribs
						
						--load the caf animation pointers found in ::g_inst_CHRPARAMS_Attribs into a UI list
						
						--Let's say we pick a track, take the name of that track, and search the .img and read the CAF INFO
						--Then search the .dba and read the Controllers
					)
					-------------------------------------------------------------------------------------------------------------------------------------------------------------
					--*/
				)
				--////////////////////////////////////////////////////////////////////////////////////////////
		)
	)
)

fn ISOLATED_CDF_NODE_LOADER \
												&inst_xmlB_PROCESSOR: \
												&inst_s_OPTIONS: \
												&g_cryFile: \
												&nodeIsolation_arr: \
												&inst_Sub_Meshes: \
												&inst_CDF_Model: \
												&inst_CDF_Attachment: \
												&inst_CDF_Modifiers: =
(
	print "// ** // ** // ** // ** // ** // ** // ** // ** // ** // "
	format "Isolated Node, just before reading:\n"
	print nodeIsolation_arr
	print "// ** // ** // ** // ** // ** // ** // ** // ** // ** // "
	
	-------------------- Counters --------------------
	local AttachmentList_count 		= 0
	local Attachment_count			= 0
	local Modifiers_count 				= 0
	local Element_count					= 0	
	
	--------------------Predeclare--------------------
	local _File_Name 				= ""
	local _File_							= ""
		
	local _Material_Name 			= ""
	local _Material_ 					= ""
		
	local _Type_Name 				= ""
	local _Type_						= ""
					
	local _AName_Name				= ""
	local _AName_ 					= ""					
		
	local _Binding_Name				= ""
	local _Binding_					= ""
					
	local _LodDistances_Name 	= ""
	local _LodDistances_ 			= ""
				
	local _Flags_Name 				= ""
	local _Flags_ 						= ""
	
	---------------------- HFR ----------------------
	local _BoneName_Name 		= ""
	local _BoneName_ 				= ""
	
	local _Rotation_Name 			= ""
	local _Rotation_ 					= ""
	
	local _Position_Name 			= ""
	local _Position_ 					= ""
	-----------------------------------------------------
	
	for i=1 to nodeIsolation_arr.count do
	(
		local nTagString					= nodeIsolation_arr[i].nTagString
		
		if ::g_CDF_Report then ( format "\nCDF nTagString: %\n" nTagString ) --report		
		
		for x=1 to nodeIsolation_arr[i].attribName.count do
		(
			--------------------------------------------------------------------------------------------
			local attribName				= nodeIsolation_arr[i].attribName[x]
			local attribVal					= nodeIsolation_arr[i].attribVal[x]
			--------------------------------------------------------------------------------------------
			
			if ::g_CDF_Report then ( format "\t% = %\n" 	attribName		attribVal ) --report
			
			if stricmp nTagString "Model" == 0 then
			(
				case of
				(
					(stricmp attribName "File" == 0):
					(
						_File_Name		= attribName
						_File_			= attribVal	
						
						--We reference the filePath and the path will be updated if a valid file and if the file exists
						build_complete_filePath \
														attribVal:attribVal \
														dirPath:(::g_dirPath) \
														filePath:&_File_ --Note this is a reference and will update the g_cryFile above					

						inst_CDF_Model.n_File = _File_
					)
					(stricmp attribName "Material" == 0):
					(
						_Material_Name		= attribName
						_Material_				= attribVal
						
						--We reference the filePath and the path will be updated if a valid file and if the file exists
						build_complete_filePath \
														attribVal:attribVal \
														dirPath:(::g_dirPath) \
														filePath:&_Material_ --Note this is a reference and will update the g_cryFile above
						
						mtlName_deepCheck \
													_Material_:&_Material_
						
						inst_CDF_Model.n_Material = _Material_
					)
				)
			)			
			else if stricmp nTagString "AttachmentList" == 0 then
			(				
				AttachmentList_count += 1
			)
			else if stricmp nTagString "Attachment" == 0 then
			(
				Attachment_count += 1
				
				case of
				(
					(stricmp attribName "Type" == 0):
					(
						_Type_Name									= attribName
						_Type_											= attribVal						
						inst_CDF_Attachment.n_Type 		= _Type_
						
						if (stricmp _Type_ "CA_SKIN") == 0 then
						(
							-------------------------------------------------------------------------------------------
							inst_Sub_Meshes.CA_SKIN_counter += 1
							-------------------------------------------------------------------------------------------
						)
						
						if ::g_CDF_Report then ( format "\tType: % = %\n"	_Type_Name	_Type_ ) --report
					)
					(stricmp attribName "AName" == 0):
					(
						_AName_Name									= attribName
						_AName_												= attribVal
						inst_CDF_Attachment.n_AName 			= _AName_
						
						::g_AName = attribVal
						
						if ::g_CDF_Report then ( format "\tAName: % = %\n"	_AName_Name		_AName_ ) --report
					)
					(stricmp attribName "Binding" == 0):
					(
						_Binding_Name									= attribName
						_Binding_											= attribVal
						inst_CDF_Attachment.n_Binding 				= _Binding_
						
						--------------------------------------------Test-----------------------------------------------							
						inst_Sub_Meshes.Binding_BOOL 				= true
						-----------------------------------------------------------------------------------------------
						
						if ::g_CDF_Report then ( format "\tBinding: % = %\n"	_Binding_Name	_Binding_ ) --report
						
						--We reference the filePath and the path will be updated if a valid file and if the file exists
						build_complete_filePath \
														attribVal:attribVal \
														dirPath:(::g_dirPath) \
														filePath:&_Binding_ --Note this is a reference and will update the g_cryFile above
					)
					(stricmp attribName "Material" == 0):
					(
						_Material_Name									= attribName
						_Material_											= attribVal
						inst_CDF_Attachment.n_Material 		= _Material_
						
						check_4_mtl_suffix filePath:&_Material_
						
						--We reference the filePath and the path will be updated if a valid file and if the file exists
						build_complete_filePath \
														attribVal:attribVal \
														dirPath:(::g_dirPath) \
														filePath:&_Material_ --Note this is a reference and will update the g_cryFile above

						mtlName_deepCheck \
													_Material_:&_Material_
					)
					(stricmp attribName "LodDistances" == 0):
					(
						_LodDistances_Name								= attribName
						_LodDistances_										= attribVal	
						inst_CDF_Attachment.n_LodDistances	= _LodDistances_
						
						
						if ::g_CDF_Report then ( format "\tLodDistances: % = %\n"	_LodDistances_Name	_LodDistances_ ) --report
					)
					(stricmp attribName "Flags" == 0):
					(
						_Flags_Name										= attribName
						_Flags_												= attribVal		
						inst_CDF_Attachment.n_Flags				= _Flags_
						
						if ::g_CDF_Report then ( format "\tFlags: % = %\n"	_Flags_Name	_Flags_ ) --report
					)
					(stricmp attribName "Rotation" == 0):
					(
						_Rotation_Name										= attribName
						_Rotation_												= attribVal	
						inst_CDF_Attachment.n_Rotation				= _Rotation_
						
						if ::g_CDF_Report then ( format "\tFlags: % = %\n"	_Flags_Name	_Flags_ ) --report
					)
					(stricmp attribName "Position" == 0):
					(
						_Position_Name										= attribName
						_Position_												= attribVal
						inst_CDF_Attachment.n_Position					= _Position_
						
						if ::g_CDF_Report then ( format "\tFlags: % = %\n"	_Flags_Name	_Flags_ ) --report
					)
					(stricmp attribName "BoneName" == 0):
					(
						_BoneName_Name									= attribName
						_BoneName_											= attribVal	
						inst_CDF_Attachment.n_BoneName				= _BoneName_
						
						if ::g_CDF_Report then ( format "\tFlags: % = %\n"	_Flags_Name	_Flags_ ) --report
					)
					default:
					(									
					)
				)			
			)
			--HFR
			else if stricmp nTagString "Modifiers" == 0 then
			(
				Modifiers_count += 1
			)
			else if stricmp nTagString "Element" == 0 then
			(
				Element_count += 1
			)
			else if stricmp nTagString "enabled" then
			(				
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal

			)
			else if stricmp nTagString "guidHiPart" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "guidLoPart" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "sourceNode" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "name" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "crc32" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "targetVector" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "weight" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "draw" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "aimVector" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "length" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "stiffness" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "damping" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "forceMovementMultiplier" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "gravity" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "limitAngle" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "limitRotationAngles" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "limitPlane0" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "limitPlane1" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "drivenNode" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "originNode" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "originOffset" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "targetNode" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "targetOffset" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "upVector" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "upNode" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "upOffset" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
			else if stricmp nTagString "version" then
			(
				inst_CDF_Modifiers._set \
												nTagString: 		&nTagString \
												attribName: 		&attribName \
												attribVal:			&attribVal
			)
		)
	)
	
	format "\n"
	format "\n"
	format "##// Analysed isolated node ready to be sent to the mesh and skin builders //##\n"
	format "########################################################\n"
	print inst_CDF_Model
	
	if inst_CDF_Attachment.n_type == "CA_SKIN" then
	(
		print inst_CDF_Attachment
	)
	format "######################// end //############################\n"
	format "\n"
	format "\n"

	--//!-- NOTE
	--Note, we load the chr last ( IF - the .chr is legacy or for some reason, the user opts to load the .chr
	--which for newer cryfile version, is just a helper and proxy
	--however for legacy .chr it should be loaded, because that IS the character!
	--See the caller of this function *LOAD_CDF_ASSETS*
	--//!-- NOTE
	
	--////////////////////// Load Model Node Attachment( of type *CA_SKIN*) //////////////////////
	if stricmp _Type_ "CA_SKIN" == 0 then
	(
		if  NOT (Binary_CryTek_check File:_Binding_) then --if the xml file is not Crytek Binary XML
		(
			if ::g_CDF_Report then ( format "This is not a valid CryTek file, aborting!\n" ) --report
		)
		else
		(
			if ::g_CDF_Report then ( format "We will now attempt to load _File_: % ...\n" _Binding_ )	--report
			
			if (Binary_XML_check _Material_) then
			(
				cryFile_loader \
									g_cryFile:						&_Binding_ \
									caller:							"CDF" \
									mtlFile:							&_Material_ \
									inst_Sub_Meshes:			&inst_Sub_Meshes \
									inst_CDF_Model:				&inst_CDF_Model \
									inst_CDF_Attachment:		&inst_CDF_Attachment \
									inst_CDF_Modifiers:			&inst_CDF_Modifiers
			)
			else
			(
				cryFile_loader \
									g_cryFile:						&_Binding_ \
									caller:							"CDF" \
									inst_Sub_Meshes:			&inst_Sub_Meshes \
									inst_CDF_Model:				&inst_CDF_Model \
									inst_CDF_Attachment:		&inst_CDF_Attachment \
									inst_CDF_Modifiers:			&inst_CDF_Modifiers
			)
		)
	)
	--//////////////////////////////////////////////////////////////////////////////////////////////
	--*/
)

fn LOAD_CDF_ASSETS \								
								&inst_Sub_Meshes: \
								&inst_xmlB_PROCESSOR: \
								&g_cryFile: \
								&inst_s_OPTIONS: =
(
	inst_xmlB_PROCESSOR.cry_CDF_xmlB_ASSETS_loader_ReaderV \
																						CDF_File:				&g_cryFile \
																						inst_s_OPTIONS:		&inst_s_OPTIONS \
																						type:						(getFilenameType g_cryFile)
	
	format "LOAD_CDF_ASSETS ################# (getFilenameType g_cryFile): % ##################\n" (getFilenameType g_cryFile)
	
	--We create it here because there should only be one model node for each CDF
	inst_CDF_Model				= CDF_Model() 		--create instance of Modifiers nodes - this is probably always .chr file (which is just a helper and proxy)
	
	if ::g_inst_CDF_Attribs.count > 0 then
	(
		format "We have successfully filled the ::g_inst_CDF_Attribs!\n"
		format "We are now ready to load the assets from the .cdf file...\n\n"
		
		local uniqueNodes_arr = #()
		for i=1 to ::g_inst_CDF_Attribs.count do
		(
			--Model Node will be = 0, and so will all its associated attributes
			--However, "Attachment" nodes are more than one, and will have different idx's
			local idx							= ::g_inst_CDF_Attribs[i].idx
			
			AppendifUnique uniqueNodes_arr idx
		)		
		print uniqueNodes_arr
				
		for i=1 to uniqueNodes_arr.count do
		(
			local nodeIsolation_arr = #()				
			local uIDX					= uniqueNodes_arr[i]
				
			for ii=1 to ::g_inst_CDF_Attribs.count do
			(
				if uIDX == ::g_inst_CDF_Attribs[ii].idx do
				(
					Append nodeIsolation_arr ::g_inst_CDF_Attribs[ii]
				)
			)
			
			---------------------------- Create Instance Structs ----------------------------
			inst_CDF_Attachment 		= CDF_Attachment() 	--create instance of Attachment nodes
			inst_CDF_Modifiers			= CDF_Modifiers() 		--create instance of Modifiers nodes	
			--------------------------------------------------------------------------------------	
			
			ISOLATED_CDF_NODE_LOADER \
														inst_xmlB_PROCESSOR:		&inst_xmlB_PROCESSOR \
														inst_s_OPTIONS:				&inst_s_OPTIONS \
														g_cryFile:						&g_cryFile \										
														nodeIsolation_arr:			&nodeIsolation_arr \
														inst_Sub_Meshes:			&inst_Sub_Meshes \
														inst_CDF_Model:				&inst_CDF_Model \
														inst_CDF_Attachment:		&inst_CDF_Attachment \
														inst_CDF_Modifiers:			&inst_CDF_Modifiers
		)	
		
		--We check if there was no CA_SKIN at all - if so, then we treat the .chr as a legacy .chr file and load it
		if 	inst_Sub_Meshes.CA_SKIN_counter == 0 OR \
			NOT ::cryImport.chk_skip_chr.state then
		(
			CHR_LOADER \								
								caller: 							"CDF"	\
								mtlFile: 							&inst_CDF_Model.n_Material \
								inst_Sub_Meshes:			&inst_Sub_Meshes \
								inst_CDF_Model:				&inst_CDF_Model \
								inst_CDF_Attachment:		&inst_CDF_Attachment \
								inst_CDF_Modifiers:			&inst_CDF_Modifiers
		)
	)
)



fn cryFile_CDF_loader \
								&g_cryFile: =
(	
	get_game_dirPath()

	if ::g_dirpath != undefined then
	(
		if pathConfig.isLegalPath ::g_dirpath then
		(
			if g_cryFile != undefined then
			(
				if doesfileexist g_cryFile then
				(
					Reset_Arrays()					
					
					--//////////////////////////////////////////////////////////////////////////////////
					setINISetting 	::g_iniFile 	"paths" ("g_cryFile"+(getFilenameType g_cryFile)) 	::g_cryFile
					
					if (stricmp (getFilenameType g_cryFile) ".cdf") == 0 then
					(
						setINISetting 	::g_iniFile 	"paths" ("CDF_load") 										::g_cryFile --we will use this for loading the material xmlB
					)
					else if (stricmp (getFilenameType g_cryFile) ".chrparams") == 0 then
					(
						setINISetting 	::g_iniFile 	"paths" ("CHRPARAMS_load") 								::g_cryFile --we will use this for loading the material xmlB
					)
					
					inst_s_OPTIONS = s_OPTIONS()	--create instance			
					if ::g_dds then
					(
						inst_s_OPTIONS.chk_dds = ::g_dds 		
					)

					inst_xmlB_PROCESSOR = xmlB_PROCESSOR()
					
					if ::g_xmlB_Report 						then 	( inst_xmlB_PROCESSOR.report 							= true )				
					if ::g_xmlB_Debug_Report				then 	( inst_xmlB_PROCESSOR.xmlB_Debug_Report 		= true )
					if ::g_Build_Material_Report 			then 	( inst_xmlB_PROCESSOR.Build_Material_Report 		= true )	
					if ::g_skip_Lod_Materials				then 	( inst_xmlB_PROCESSOR.skip_Lod_Materials 			= true )	
					if ::g_xmlB_Report_v2					then 	( inst_xmlB_PROCESSOR.xmlB_Report_v2 				= true )

					--CDF
					if 	(stricmp (getFilenameType g_cryFile) ".cdf" ) == 0 OR \
						(stricmp (getFilenameType g_cryFile) ".chrparams" ) == 0 then --Character Definition File .cdf or .chrparams
					(
						--We start this storage here
						local inst_Sub_Meshes 		= Sub_Meshes()			
						
						----------------------------------- Load CDF Assets -----------------------------------
						LOAD_CDF_ASSETS \													
													inst_Sub_Meshes:			&inst_Sub_Meshes \
													inst_xmlB_PROCESSOR:		&inst_xmlB_PROCESSOR \
													g_cryFile:						&::g_cryFile \
													inst_s_OPTIONS:				&inst_s_OPTIONS
													
						-------------------------------------------------------------------------------------------				
					)
				)
			)
		)
	)	
)
