fn ReadFixedString bstream fixedLen = (
   local str = ""
   For i = 1 to fixedLen do
   (
      str0 = ReadByte bstream #unsigned
      If str0!=0xFD AND str0!=0xFC do str+= bit.intAsChar str0
   )
   str
)
fn addHexaDecimalPadding nr = (
	case of (
		(nr <= 15): ("0" + ((bit.intAsHex(nr))as string))
		(nr > 15): ((bit.intAsHex(nr))as string)
	)
)	
fn ReadFixedByteString bstream fixedLen = (
   local str = ""
   For i = 1 to fixedLen do
   (
      str += addHexaDecimalPadding (ReadByte bstream #unsigned)
	  If mod i 1 == 0 do str += " "
   )
   str
   print str
)
fn GetName bstream Offset = (
	fseek bstream Offset #seek_set
	MeshName = readstring bstream
	return MeshName
)
fn Readword fstream = (
return readshort fstream #unsigned
)
fn FindNumofOcurrences narray num = (
	j=0
	for i in narray do (
		if i == num do j+=1
	)
	return j
)
fn paddstring len instring = (
	instring=instring as string
	local str=""
	if instring.count <=len then (
		for i = 1 to (len-instring.count) do(
			str+="0"
		)
		str = (str+instring)
	)
	else (
		for i = 1 to len do(
			str+="0";str[i]=instring[i]
		)
	)
	str
)
fn ApplyNormals amesh nArr toggle= (
	max modify mode
	cui.expertModeOn()

	with redraw off (
	   --your import code
		
	   for face = 1 to amesh.numfaces do setFaceSmoothGroup amesh face 1
		
	   select amesh
	   addmodifier amesh (Edit_Normals ()) ui:off
	   amesh.Edit_Normals.MakeExplicit selection:#{1..nArr.count}
	   EN_convertVS = amesh.Edit_Normals.ConvertVertexSelection
	   EN_setNormal = amesh.Edit_Normals.SetNormal
	   normID = #{}
		
	   for v = 1 to nArr.count do
	   (
		  free normID
		  EN_convertVS #{v} &normID
		  for id in normID do EN_setNormal id nArr[v]
	   )
	   
	   if toggle == 1 do collapseStack amesh
	)

	cui.expertModeOff()
)
fn SplitLayout Split =(
	str=""
	j=0
	for i in Split do (
		j+=1
		if j >1 do (
			str += i
			if j != Split.count do str += "_" 
		)
	)
	str
)
fn PrintFileCount Files= (
	If Files.count == 1 then (print ((Files.Count as string)+ " File"))
	Else(print ((Files.Count as string)+ " Files"))
)

Global Fscale = 100

--Define local variables
folderPath = getSavePath caption:"DeadSpace 2/3 Geometry" initialDir:"C:\\Users\\gesankey524\\Documents\\stuff\\models\\Dead Space Models"
if folderPath != undefined do (

	--Find geo files in chosen directory
	Files = getFiles (folderPath + "\\*.geo")
	clearlistener()
-- 	print Files.count
	PrintFileCount Files
	
	delete $*
	
	paths=#()
	--Loop through all files found
	for a=1 to Files.count do (
		If (Files[a]!=undefined) and ((DoesFileExist Files[a])==true) then (
			f = fopen Files[a] "rb"
			
-- 			actionMan.executeAction 0 "550"  -- Views: Viewport Visual Style Shaded
			actionMan.executeAction -844228238 "1"  -- Viewport Lighting and Shadows: Viewport Visual Style Realistic

			FilePath = GetFilenamePath Files[a]
			Leaf = pathConfig.removePathLeaf Files[a]
			ParentFolder = pathConfig.removePathLeaf Leaf
			FileExtension = getFileNameType Files[a]
			UVFolder = ParentFolder + "\MeshVolatile\\"
			FileName = getFileNameFile Files[a]
			
			Split = filterString FileName "_"
			UVID= ((Split[1] as number)+1)
			Rest = SplitLayout (Split)
			UVPath = (UVFolder + (paddstring 4 (UVID as string)) + "_" + Rest + ".geo")
-- 			print UVPath as string
			format "\n"
			
			
-- 			If ((FindItem Split "cap")!=0) or ((FindItem Split "lodmodel")!=0) or ((FindItem Split "tc")!=0) or ((FindItem Split "bc")!=0) or ((FindItem Split "sc")!=0) or ((FindItem Split "pc")!=0) do (
			If ((FindItem Split "cap")==0) and ((FindItem Split "lodmodel")==0) and ((FindItem Split "tc")==0) and ((FindItem Split "torsocap")==0) and ((FindItem Split "bc")==0) and ((FindItem Split "sc")==0) and ((FindItem Split "pc")==0) do (
			print files[a] as string	
			Ext_UV = false
-- 				print uvpath as string
				If  (UVPath!=undefined) and ((DoesFileExist UVPath)==true) do (
-- 					print "true"
					Ext_UV = true
					g = fopen UVPath "rb"
					print g as string
					append paths(UVPath)
				)
				
				Print "===================================="
				print (FileName + FileExtension) as string
				Print "===================================="
				
				
				Magic = readfixedstring f 4
				Ukw = readlong f	-- always 0x32
				Ukw2 = readlong f	-- always 0x3
				fseek f 0x14 #seek_cur	-- bunch of shit
				
				ModelNameOffset = readlong f #unsigned
				Ukw3 = readlong f
				fseek f 0xc #seek_cur
				
				TableCount = readlong f
				Ukw4 = readlong f	-- always 0x83
				fseek f 0xc #seek_cur	-- look at later, may be important
				
				UkwTableCount=readlong f
				UkwTable=readlong f
				
				DataTable1=readlong f
				UkwTable2=readlong f
				fseek f 0x08 #seek_cur
				
				UkwBuffer=readlong f	-- looks like uv's
				null = readlong f
				DataTable2=readlong f
				ukw3=readlong f		--always 40 more than datatable2
				
				fseek f 0x9c #seek_set
				UVOffsetLocal = readlong f
				
				
-- 				print ("Table count is "+((TableCount)as string))	
-- 				print ("DataTable 1 offset is 0x"+((bit.intAsHex(DataTable1))as string))
-- 				print ("DataTable 2 offset is 0x"+((bit.intAsHex(DataTable2))as string))
-- 				format "\n"
				
				MeshNameOffset=#()
				VertCount=#()
				VertSize=#()
				VertOffset=#()
				VertID=#()
				UVSize=#()
				FaceOffset=#()
				FaceCount=#()
				LodType=#()
				
				fseek f DataTable1 #seek_set	
				For x=1 to TableCount do (
-- 					Print "===================================="------------------------------
-- 					Print (("Table "+((x)as string))+("					   0x"+(bit.intAsHex(ftell f))))
-- 					Print "===================================="------------------------------
					
					MeshNameOffset[x]=readlong f 
					backjump = ftell f
					fseek f MeshNameOffset[x] #seek_set
					print (readstring f)
					fseek f backjump #seek_set
					fseek f 0x4 #seek_cur	-- data, look into
					null = readlong f
					fseek f 0x14 #seek_cur
					TableOffset = readlong f
					ukw2=readshort f
					_0x14 = readbyte f	-- always 0x14
					UVSize[x]=readbyte f
					fseek f 0x08 #seek_cur
					
					FaceCount[x]=readlong f 
					null=readlong f 
					VertCount[x]=readshort f 
					ukwcount = readshort f
					LodType[x]=readshort f 	--determines whether or not its a lod model and uses tristrips.  5 If it is, 4 If it isnt
					ukw4 = readlong f 	-- looks like an offset
					ukw5 = readshort f
					ukwOffset=readlong f 
					fseek f 0x1c #seek_cur	-- blank
					ReadFixedByteString f 0xc
					fseek f (-12) #seek_cur
					VertSize[x]=readlong f	--	-1 For vertsize of 0x20,  Else For 0x14
					Ukw6 = readlong f
					VertID[x] = readlong f
					fseek f 0xc #seek_cur
					null = readlonglong f
					VertOffset[x]=readlong f 
					FaceOffset[x]=readlong f 
					fseek f 0x34 #seek_cur
					
-- 					Print ("Vertex offset is 0x"+((bit.intAsHex(VertOffset[x]))as string))
-- 					Print ("Vertex size is "+(VertSize[x]as string))
-- 					Print ("Lod type is 0x"+((bit.intAsHex(LodType[x]))as string))
					/*
					
					
					Print ("Vertex count is 0x"+((bit.intAsHex(VertCount[x]))as string))
					Print ("Face count is 0x"+((bit.intAsHex(FaceCount[x]))as string))
					Print ("Face offset is 0x"+((bit.intAsHex(FaceOffset[x]))as string))
					*/
				)
				format "\n"
				
				UniqueID_array = makeUniqueArray VertID	-- array of all ID's w/o duplications
-- 				print ("VertID = "+(VertID)as string)
				print ("UniqueID_array = "+(UniqueID_array)as string)
				
				BaseVertArray=#()
				BaseNormalArray=#()
				BaseFaceArray=#()
				BaseUVArray=#()
				UVBufferSize=#()
				BaseUVOffsetArray=#()
				MeshNameArray=#()
				
				For x=1 to UniqueID_array.count do (
					append BaseVertArray(#())
					append BaseUVArray(#())
					append BaseUVOffsetArray(0)
					append UVBufferSize(0)
					append BaseNormalArray(#())
					append BaseFaceArray(#())
					append MeshNameArray(#())
				)
				
-- 				format "\n"
-- 				print ("BaseVertArray = "+(BaseVertArray)as string)	-- an array of all the verts. where an element would an array of all verts of the same id. each id consisting of an array of each individual vert buffer.
-- 				print ("BaseFaceArray = "+(BaseFaceArray)as string)
-- 				print ("MeshNameArray = "+(MeshNameArray)as string)
				print ("UVBufferSize = "+(UVBufferSize)as string)
				print ("BaseUVOffsetArray = "+(BaseUVOffsetArray)as string)
				
				
				j=0
				For a in BaseFaceArray do (
					j+=1
					For x=1 to (FindNumofOcurrences VertID UniqueID_array[j]) do (
						append a (#())
					) 
				)
				
-- 				format "\n"
-- 				print ("BaseVertArray after = "+(BaseVertArray)as string)
-- 				print ("BaseFaceArray after = "+(BaseFaceArray)as string)
				-- print ("MeshNameArray after = "+(MeshNameArray)as string)
				
				
				
				-- Getting UV buffer size associated by vert id
				For x=1 to TableCount do (
					GetUniqueIDElement = FindItem UniqueID_array VertID[x]
					
					If Ext_UV == true then (						
						Case UVSize[x] of (
							
							(0x8):(
								UVBufferSize[GetUniqueIDElement] += (VertCount[x] * 0x8)
							)
							(0xc):(
								UVBufferSize[GetUniqueIDElement] += (VertCount[x] * 0xc)
							)
							(0x10):(
								UVBufferSize[GetUniqueIDElement] += (VertCount[x] * 0x10)
							)
							(0x14):(
								UVBufferSize[GetUniqueIDElement] += (VertCount[x] * 0x14)
							)
							(0x1c):(
								UVBufferSize[GetUniqueIDElement] += (VertCount[x] * 0x1c)
							)
							
						)
					)
				)
				
				-- Setting the initial offset of the vert id's uv buffer
				addto = 0
				For x=2 to (UniqueID_Array.count ) do (
					BaseUVOffsetArray[x] += UVBufferSize[x-1] + addto
					addto = BaseUVOffsetArray[x] 
				)
				
				format "\n"
				print ("BaseUVOffsetArray updated = "+(BaseUVOffsetArray)as string)
				print ("UVBufferSize updated = "+(UVBufferSize)as string)
				format "\n"
				
				UV_array=#()
				UV_Offset = 0
				For x=1 to TableCount do ( --should be tablecount
					
					Vert_array=#()
					Normal_array=#()
					Face_array=#()
					
					Tri_strip = false
					
					-- Building Vertices --
					fseek f VertOffset[x] #seek_set
					
					GetUniqueIDElement = FindItem UniqueID_array VertID[x]	-- getting the index position of the basevertarray based on the current table's id
				-- 	print GetUniqueIDElement	-- this would be 1
-- 					format "\n"
					
					Case VertSize[x] of (
						
						(-1): (
							
-- 							print "x20"
-- 							print "Tri Lists"
							
							For y = 1 to VertCount[x] do(
								vx=readfloat f
								vy=readfloat f
								vz=readfloat f
								nx=readword f
								ny=readword f
								nz=readword f
								fseek f 0xe #seek_cur
								append BaseVertArray[GetUniqueIDElement]([vx*-1,vz,vy]*fscale)
								append BaseNormalArray[GetUniqueIDElement]([nx*-1,nz,ny]*fscale)
								append UV_array[0,0,0]
								
							)
							
						)
						
						default:(
							Case LodType[x] of (
								(4):(
-- 									print "x14"
-- 									print "Tri Lists"
									
									for x = 1 to VertCount[x] do(
										vx=readfloat f
										vy=readfloat f
										vz=readfloat f
										nx=readword f
										ny=readword f
										nz=readword f
										fseek f 0x2 #seek_cur
										append BaseVertArray[GetUniqueIDElement]([vx*-1,vz,vy]*fscale)
										append UV_array[0,0,0]
									)
								)
								
								(5):(
-- 									print "x0c"
-- 									print "Tri Strips"
									Tri_Strip = true
									
									for x = 1 to VertCount[x] do(
										vx=readfloat f
										vy=readfloat f
										vz=readfloat f
										append BaseVertArray[GetUniqueIDElement]([vx*-1,vz,vy]*fscale)
										append UV_array[0,0,0]
									)
								)
								
								default: Throw "Lod type unrecognized"
							)
						)
					)
					
					-- Reading UV's --
					If Ext_UV == true then (
						Print "External UV's"
-- 						fseek g UV_Offset #seek_set
						fseek g BaseUVOffsetArray[GetUniqueIDElement] #seek_set
						print (bit.intashex(UVSize[x]) as string)
-- 						append UV_array[0,0,0]
						
						Case UVSize[x] of (
							
							(0x8):(
								For y=1 to VertCount[x] do (
									tu = readfloat g
									tv = readfloat g
									append BaseUVArray[GetUniqueIDElement][tu,tv*-1,0]		
								)
								Print ("Last Read g @ 0x"+((bit.intAsHex(ftell g))as string))
							)
							(0xc):(
								For y=1 to VertCount[x] do (
									tu = readfloat g
									tv = readfloat g
									tw = readfloat g
									append BaseUVArray[GetUniqueIDElement][tu,tv*-1,0]
								)
								Print ("Last Read g @ 0x"+((bit.intAsHex(ftell g))as string))
							)
							(0x10):(
								For y=1 to VertCount[x] do (
									tu = readfloat g
									tv = readfloat g
									fseek g 0x8 #seek_cur
									append BaseUVArray[GetUniqueIDElement][tu,tv*-1,0]
								)
								Print ("Last Read g @ 0x"+((bit.intAsHex(ftell g))as string))
							)
							(0x14):(
								For y=1 to VertCount[x] do (
									tu = readfloat g
									tv = readfloat g
									fseek g 0xc #seek_cur
									append BaseUVArray[GetUniqueIDElement][tu,tv*-1,0]		
								)
								Print ("Last Read g @ 0x"+((bit.intAsHex(ftell g))as string))
							)
							(0x1c):(
								For y=1 to VertCount[x] do (
									tu = readfloat g
									tv = readfloat g
									tw = readfloat g
									fseek g 0x10 #seek_cur
									append BaseUVArray[GetUniqueIDElement][tu,tv*-1,0]
								)
								Print ("Last Read g @ 0x"+((bit.intAsHex(ftell g))as string))
							)
							
						)
					)
					Else (
						print "Local UV's"
						fseek f UVOffsetLocal #seek_set
						print (bit.intashex(UVSize[x]) as string)
-- 						append UV_array[0,0,0]
						
						Case UVSize[x] of (
							
							(0xc):(
								For y=1 to VertCount[x] do (
									tu = readfloat f
									tv = readfloat f
									tw = readfloat f
									append BaseUVArray[GetUniqueIDElement][tu,tv*-1,tw]
								)
								Print ("Last Read uv @ 0x"+((bit.intAsHex(ftell f))as string))
							)
							(0x8):(
								For y=1 to VertCount[x] do (
									tu = readfloat f
									tv = readfloat f
									append BaseUVArray[GetUniqueIDElement][tu,tv*-1,0]		
								)
								Print ("Last Read uv @ 0x"+((bit.intAsHex(ftell f))as string))
							)
							(0x14):(
								For y=1 to VertCount[x] do (
									tu = readfloat f
									tv = readfloat f
									fseek f 0xc #seek_cur
									append BaseUVArray[GetUniqueIDElement][tu,tv*-1,0]		
								)
								Print ("Last Read uv @ 0x"+((bit.intAsHex(ftell f))as string))
							)
							
						)
					)
-- 					UV_Offset = ftell g
					BaseUVOffsetArray[GetUniqueIDElement] = ftell g
					
					-- Building Indices --
					fseek f FaceOffset[x] #seek_set
					
					j=0	-- Getting the index value of the first empty array
					For a in BaseFaceArray[GetUniqueIDElement] do (
						j+=1
						if a.count == 0 then exit
					)
-- 					print ("j is "+(j)as string)
					
					If Tri_Strip == true then (
						facestart = (ftell f)
						StartDirection = 1	--was -1
						f1 = (Readword f) + 1
						f2 = (Readword f) + 1  
						FaceDirection = StartDirection
						Do (
							f3 = (Readword f)
							if (f3==0xFFFF) then (
								f1 = (Readword f) + 1
								f2 = (Readword f) + 1
								FaceDirection = StartDirection   
							)
							else (
								f3 += 1
								FaceDirection *= -1
								if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
									if FaceDirection > 0 then append BaseFaceArray[GetUniqueIDElement][j] [f1,f2,f3]
									else append BaseFaceArray[GetUniqueIDElement][j] [f1,f3,f2]
								)
								f1 = f2
								f2 = f3
							)  
						)
						while (ftell f) < (facestart + (FaceCount[x]*2))	
					)
					Else (
						for y = 1 to FaceCount[x]/3 do (
							fa = (readword f) + 1
							fb = (readword f) + 1
							fc = (readword f) + 1
							append BaseFaceArray[GetUniqueIDElement][j] [fa,fb,fc]
						)
					)
					
					MeshNameArray[GetUniqueIDElement][j] = GetName f MeshNameOffset[x]
					
				-- 	print BaseVertArray[2]
				-- 	print BaseFaceArray[1]
					
				)
				
				For x=1 to UniqueID_Array.count do (
					
					For y=1 to BaseFaceArray[x].count do (
						msh = mesh vertices:BaseVertArray[x] faces:BaseFaceArray[x][y]
						msh.numTVerts = UV_array.count
						msh.wirecolor = random black white
						msh.name = MeshNameArray[x][y]
						buildTVFaces msh
						for j = 1 to BaseUVArray[x].count do setTVert msh j BaseUVArray[x][j]
						for j = 1 to BaseFaceArray[x][y].count do setTVFace msh j BaseFaceArray[x][y][j]
						meshop.deleteIsoVerts msh
						
						bar = filterString MeshNameArray[x][y] "_"
						if bar.count == 4 and bar[3].count == 4 do (
-- 							print bar
							delete msh
						)
						
-- 						ApplyNormals msh BaseNormalArray[x] 0
-- 						select msh
-- 						convertTo $ PolyMeshObject
-- 						$.EditablePoly.deleteIsoVerts ()
-- 						convertTo $ TriMeshGeometry
-- 						modPanel.addModToSelection (smooth ()) ui:on
-- 						$.modifiers[#Smooth].autosmooth = on
-- 						deselect msh
						
					)
					
				)
				
				Print ("Last Read @ 0x"+((bit.intAsHex(ftell f))as string))
			)
		)
		format "\n"
	)
-- 	print paths
	
	select $*
-- 	actionMan.executeAction 0 "310"  -- Tools: Zoom Extents Selected
-- 	deselect $*

	gc()
	fclose f
	
)
	