############################################################################################




from Blender import *

from Blender import Draw
from Blender import BGL
from Blender import Window


############################################################################################
status=''
error=False
obj=0
mesh=0
filename=""

normals=True

texCoords=False

materials=False

faceMode=False

frame=False

frameHierarchy=False
############################################################################################
	
if(len(Object.GetSelected())>0):
	obj=Object.GetSelected()[0]
	mesh=obj.getData(mesh=1)
	filename=obj.getName()+".x"
	
	try: 
		mesh.verts
		status='Exporting '+obj.getName()+' to Direct-X Format'
	except:
		status='Error: Please select a mesh object!'
		error=True

else:
	status='Error: Please select a mesh object!'
	error=True

############################################################################################


def filename_callback(str):
	global filename
	filename=str

def draw():
	BGL.glClearColor(0.5,0.7,0.5,1)
	BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
	BGL.glColor3i(0,0,0)
	BGL.glRasterPos2i(10,190)
	Draw.Text(status)
	
	if(not error):
		Draw.String("Filename: ",1,10,70,300,20,filename,200,"Filename i.e. car.x")
		Draw.PushButton("Browse",2,315,70,50,20,"Browse directory for exporting your model.")
		Draw.PushButton("Export",3,130,10,100,50,"Export the model now.")
		Draw.Toggle("Normals",4,10,100,100,20,normals,"Export normals.")
		Draw.Toggle("Texture UVs",5,120,100,100,20,texCoords,"Export texture coordinates.")
		Draw.Toggle("Material",6,230,100,100,20,materials,"Export materials and texure filenames.")
		Draw.Toggle("Face Mode",7,10,130,100,20,faceMode,"Every face has it's own vertices, normals and texture coordinates.")
		Draw.Toggle("Frame",8,10,160,100,20,frame,"Export a frame with matrix for the selected object.")
		Draw.Toggle("Frame Hierarchy",9,120,160,100,20,frameHierarchy,"Export the frame hierarchy of the selected object")
	Draw.PushButton("Exit",0,10,10,100,50,"Exit mgXPort now.")
	
def button(evt):
	global faceMode,frame,frameHierarchy
	
	if(evt==0):
		Draw.Exit()
		return
	elif(evt==2):
		Window.FileSelector(filename_callback,"Create X-File",obj.getName()+'.x')
	elif(evt==3):
		export()
	elif(evt==4):
		global normals
		normals=not normals
	elif(evt==5):
		global texCoords
		if(not faceMode):
			if(not texCoords):
				if not mesh.vertexUV:
					Draw.PupMenu("Error: UVs are not sticky!")
				else:
					texCoords=True
		else:
			texCoords=not texCoords
	elif(evt==6):
		global materials
		if len(mesh.materials)>0:
			for m in mesh.materials:
				if m==None: Draw.PupMenu('You have to assign all materials.')
				else: materials=not materials
		else: Draw.PupMenu('You have to create a material.')
	elif(evt==7):
		if not mesh.vertexUV: texCoords=False
		faceMode=not faceMode
	elif(evt==8):

		frame=not frame
		if not frame: frameHierarchy=False
	elif(evt==9):

		frameHierarchy=not frameHierarchy
		if(frameHierarchy): frame=True;
	Draw.Redraw(0)
	
def event(evt,val):
	if(evt==Draw.ESCKEY):
		Draw.Exit()
		return


Draw.Register(draw,event,button)
############################################################################################


def getChildrenOfObject(obj):
	children=[]
	
	scene=Scene.GetCurrent()
	
	for o in scene.objects:
		if o.getParent()==obj: 
			children+=[o]
		
		
			
	return children



############################################################################################




def export():
	global status
	file=open(filename,"w")
	
	file.write("xof 0303txt 0032")
	file.write("//exported by mgXPort from Blender\n")
	
	if(frame):
		export_frame(file,obj)
	else:
		if(faceMode):
			export_mesh_faceMode(file,mesh)
		else:
			export_mesh(file,mesh)
		
	
	status=obj.getName()+' was exported sucessfully!'
	
	file.close()
	
############################################################################################


def export_frame(file,obj):
	file.write('Frame '+obj.getName().replace('.','_')+'\n{\n')
	
	file.write('FrameTransformMatrix \n{\n %f,%f,%f,%f,\n%f,%f,%f,%f,\n%f,%f,%f,%f,\n%f,%f,%f,%f;;\n}\n'%
				(obj.mat[0][0],obj.mat[0][1],obj.mat[0][2],obj.mat[0][3],
				 obj.mat[1][0],obj.mat[1][1],obj.mat[1][2],obj.mat[1][3],
				 obj.mat[2][0],obj.mat[2][1],obj.mat[2][2],obj.mat[2][3],
				 obj.mat[3][0],obj.mat[3][1],obj.mat[3][2],obj.mat[3][3]))
	mesh=obj.getData(mesh=1)
	if(mesh):
		if(faceMode):
			export_mesh_faceMode(file,mesh)
		else:
			export_mesh(file,mesh)
		
	if frameHierarchy:
		for child in getChildrenOfObject(obj):
			export_frame(file,child)
		
	
	file.write('}\n')

	
############################################################################################	
def export_mesh(file,mesh):
	
	file.write('Mesh\n{\n')
	
	vertexCount=len(mesh.verts)
	
	file.write('%i;\n'%vertexCount)
	
	i=0
	for vert in mesh.verts:
		i=i+1
		if(i==vertexCount):
			file.write('%f;%f;%f;;\n'%(vert.co[0],vert.co[1],vert.co[2]))
		else:
			file.write('%f;%f;%f;,\n'%(vert.co[0],vert.co[1],vert.co[2]))
			
	export_faces(file,mesh)
	
	if(normals): export_normals(file,mesh)
		
	if(texCoords): export_texCoords(file,mesh)
		
	if(materials): export_materialList(file,mesh)
			
	file.write('}\n')


############################################################################################	
def export_mesh_faceMode(file,mesh):
	
	file.write('Mesh\n{\n')
	
	vertexCount=0
	
	for face in mesh.faces:
		vertexCount+=len(face.verts)
	
	file.write('%i;\n'%vertexCount)
	
	i=0
	for face in mesh.faces:
		for vert in face.verts:
			i=i+1
			if(i==vertexCount):
				file.write('%f;%f;%f;;\n'%(vert.co[0],vert.co[1],vert.co[2]))
			else:
				file.write('%f;%f;%f;,\n'%(vert.co[0],vert.co[1],vert.co[2]))
			
	export_faces_faceMode(file,mesh)
	
	if(normals): export_normals_faceMode(file,mesh)
		
	if(texCoords): export_texCoords_faceMode(file,mesh)
		
	if(materials): export_materialList(file,mesh)
			
	file.write('}\n')
	
############################################################################################		
def export_faces(file,mesh):
	faceCount=len(mesh.faces)
	
	file.write('%i;\n'%faceCount)
	
	i=0
	for face in mesh.faces:
		i=i+1
		
		faceVertexCount=len(face.verts)
		file.write('%i; '%faceVertexCount)
		
		l=0
		for vert in face.verts:
			l=l+1
			if(l==len(face.verts)):
				file.write('%i;'%vert.index)
			else:
				file.write('%i,'%vert.index)
			
		if(i==faceCount):
			file.write(';\n')
		else:
			file.write(',\n')
			

############################################################################################	
def export_faces_faceMode(file,mesh):
	faceCount=len(mesh.faces)
	
	file.write('%i;\n'%faceCount)
	
	vertexIndex=0
	
	i=0
	for face in mesh.faces:
		i=i+1
		
		faceVertexCount=len(face.verts)
		file.write('%i; '%faceVertexCount)
		
		l=0
		for vert in face.verts:
			l=l+1
			if(l==len(face.verts)):
				file.write('%i;'%vertexIndex)
			else:
				file.write('%i,'%vertexIndex)
			vertexIndex+=1
			
		if(i==faceCount):
			file.write(';\n')
		else:
			file.write(',\n')
			

	
############################################################################################	
def export_normals(file,mesh):
	
	file.write('MeshNormals\n{\n')
	
	normalCount=len(mesh.verts)
	
	file.write('%i;\n'%normalCount)
	
	i=0
	for vert in mesh.verts:
		i=i+1
		if(i==normalCount):
			file.write('%f;%f;%f;;\n'%(vert.no[0],vert.no[1],vert.no[2]))
		else:
			file.write('%f;%f;%f;,\n'%(vert.no[0],vert.no[1],vert.no[2]))
	
	
	export_faces(file,mesh)
			
	file.write('}\n')


############################################################################################	
def export_normals_faceMode(file,mesh):
	
	file.write('MeshNormals\n{\n')
	
	normalCount=0
	
	for face in mesh.faces:
		normalCount+=len(face.verts)
	
	file.write('%i;\n'%normalCount)
	
	i=0
	for face in mesh.faces:
		for vert in face:
			i=i+1
			if(i==normalCount):
				file.write('%f;%f;%f;;\n'%(vert.no[0],vert.no[1],vert.no[2]))
			else:
				file.write('%f;%f;%f;,\n'%(vert.no[0],vert.no[1],vert.no[2]))
	
	
	export_faces_faceMode(file,mesh)
			
	file.write('}\n')



############################################################################################
def export_texCoords(file,mesh):
	
	file.write('MeshTextureCoords\n{\n')
	
	vertexCount=len(mesh.verts)
	
	file.write('%i;\n'%vertexCount)
	
	i=0
	for vert in mesh.verts:
		i=i+1
		if(i==vertexCount):
			file.write('%f;%f;;\n'%(vert.uvco[0],vert.uvco[1]))
		else:
			file.write('%f;%f;,\n'%(vert.uvco[0],vert.uvco[1]))
			
			
	file.write('}\n')



############################################################################################
def export_texCoords_faceMode(file,mesh):
	
	file.write('MeshTextureCoords\n{\n')
	
	
	vertexCount=0
	
	for face in mesh.faces:
		vertexCount+=len(face.verts)
	
	file.write('%i;\n'%vertexCount)
	
	i=0
	for face in mesh.faces:
		for uv in face.uv:
			i=i+1
			if(i==vertexCount):
				file.write('%f;%f;;\n'%(uv[0],uv[1]))
			else:
				file.write('%f;%f;,\n'%(uv[0],uv[1]))
			
			
	file.write('}\n')



############################################################################################
def export_materialList(file,mesh):
	
	file.write('MeshMaterialList\n{\n')
	
	materialCount=len(mesh.materials)
	
	file.write('%i;\n'%materialCount)
	
	faceCount=len(mesh.faces)
	
	file.write('%i;\n'%faceCount)


	i=0
	for face in mesh.faces:
		i=i+1
		if(i==faceCount):
			file.write("%i;;\n"%face.mat)
		else:
			file.write("%i,\n"%face.mat)
	
	
	export_materials(file,mesh)
	
	file.write("}\n")
	
	
############################################################################################	
def export_materials(file,mesh):
	
	
	for mat in mesh.materials:
		reflectivity=mat.getRef()
		col=mat.getRGBCol()
		specularCol=mat.getSpecCol()
		specularity=mat.getSpec()
		alpha=mat.getAlpha()
		hardness=mat.getHardness()
		emit=mat.getEmit()
		
		diffuse=[reflectivity*col[0],reflectivity*col[1],reflectivity*col[2],alpha]
		
		specular=[specularity*specularCol[0],specularity*specularCol[1],specularity*specularCol[2]]
		
		power=hardness
		
		emissive=[emit*diffuse[0],emit*diffuse[1],emit*diffuse[2]]
		
		file.write('Material '+mat.getName()+' \n{\n')
		
		file.write('%f;%f;%f;%f;;\n%i;\n%f;%f;%f;;\n%f;%f;%f;;'%
				(diffuse[0],diffuse[1],diffuse[2],diffuse[3],power,
				 specular[0],specular[1],specular[2],emissive[0],emissive[1],emissive[2]))
	
		textures=mat.getTextures()
	
		for texture in textures:
			if(texture):
				image=texture.tex.getImage()
				if(not image==None):
					file.write('TextureFilename{ "'+image.getFilename()+'"; }\n')
					break;
		
		file.write('}\n')