#!BPY
""" Registration info for Blender menus:
Name: 'OpenFlight (.flt)...'
Blender: 245
Group: 'Export'
Tip: 'Export to OpenFlight v16.0 (.flt)'
"""

__author__ = "Greg MacDonald, Geoffrey Bantle"
__version__ = "2.0 11/21/07"
__url__ = ("blender", "blenderartists.org", "Author's homepage, http://sourceforge.net/projects/blight/")
__bpydoc__ = """\
This script exports v16.0 OpenFlight files.  OpenFlight is a
registered trademark of MultiGen-Paradigm, Inc.

Feature overview and more availible at:
http://wiki.blender.org/index.php/Scripts/Manual/Export/openflight_flt
"""

# flt_export.py is an OpenFlight exporter for blender.
#
# Copyright (C) 2005 Greg MacDonald, 2007 Blender Foundation.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

import Blender
from Blender import Modifier
import os.path
import flt_properties
import flt_defaultp as defaultp
from flt_filewalker import FltOut
from flt_filewalker import FileFinder
from flt_properties import *
import shutil
import trace
import sys

FF = FileFinder()
records = process_recordDefs()
		
class ExporterOptions:
	
	def read_state(self):
		reg = Blender.Registry.GetKey('flt_export',1)
		if reg:
			for key in self.state:
				if reg.has_key(key):
					self.state[key] = reg[key]
	
	def write_state(self):
		d = dict()
		for key in self.state:
			d[key] = self.state[key]
			Blender.Registry.SetKey('flt_export', d, 1) 
	def __init__(self):
		self.verbose = 1
		self.tolerance = 0.001
		self.writevcol = True
		
		self.state = {'export_shading' : 0, 
				'shading_default' : 45, 
				'basepath' : os.path.dirname(Blender.Get('filename')),
				'scale': 1.0,
				'doxrefs' : 1,
				'attrib' : 0,
				'copytex' : 0,
				'transform' : 0,
				'xapp' : 1}
				
		#default externals path
		if(os.path.exists(os.path.join(self.state['basepath'],'externals'))):
			self.state['externalspath'] = os.path.join(self.state['basepath'],'externals')
		else:
			self.state['externalspath'] = self.state['basepath'] 
		
		if(os.path.exists(os.path.join(self.state['basepath'],'textures'))):
			self.state['texturespath'] = os.path.join(self.state['basepath'],'textures')
		else:
			self.state['texturespath'] = self.state['basepath']

		self.state['xappath'] = ''
		self.read_state() #read from registry
		
		
options = ExporterOptions()
tex_files = dict() #a list of (possibly) modified texture path names

tex_layers = ['Layer0', 'Layer1', 'Layer2', 'Layer3', 'Layer4', 'Layer5', 'Layer6', 'Layer7']
mask = 2147483648
mtexmasks = []
for i in xrange(7):
	mtexmasks.append(mask)
	mask = mask / 2

FLOAT_TOLERANCE = options.tolerance

#need to move all this stuff to flt_properties.py.
identity_matrix = [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]]
alltypes = [2,4,14,11,73,63,111]
childtypes = { 
	2 : [111,2,73,4,14,63],
	4 : [111],
	73 : [111,2,73,4,14,63],
	63 : [],
	14 : [111,2,73,4,14,63],
	111 : []
}
recordlen = {
	2: 44,
	4: 28,
	73: 80,
	63: 216,
	14: 384,
	111: 156
}

def is_identity(m):
	for i in xrange(4):
		for j in xrange(4):
			if abs(m[i][j] - identity_matrix[i][j]) > FLOAT_TOLERANCE:
				return False
	return True

class MaterialDesc:
	def __init__(self):
		self.name = 'Blender'

		# Colors, List of 3 floats.
		self.diffuse = [1.0, 1.0, 1.0]
		self.specular = [1.0, 1.0, 1.0]

		# Scalars
		self.ambient = 0.1 # [0.0, 1.0]
		self.emissive = 0.0 # [0.0, 1.0]
		self.shininess = 32.0 # Range is [0.0, 128.0]
		self.alpha = 1.0 # Range is [0.0, 1.0]

class VertexDesc:
	def __init__(self, co=None, no=None, uv=None, fltindex=None,cindex=None):
		if co: self.x, self.y, self.z = tuple(co)
		else: self.x = self.y = self.z = 0.0
		if no: self.nx, self.ny, self.nz = tuple(no)
		else: self.nx = self.ny = self.nz = 0.0
		if uv: self.u, self.v = tuple(uv)
		else: self.u = self.v = 0.0
		if cindex: self.cindex = cindex
		else: self.cindex = 127
		self.fltindex = fltindex
		self.accum = 0

class shadowVert:
	def __init__(self,bvert,object,world,normal):
                global options
		
		self.co = Blender.Mathutils.Vector(bvert.co[0],bvert.co[1],bvert.co[2])
                #if world:
		#	vec = self.co
		#	vec = Blender.Mathutils.Vector(vec[0] * options.scale, vec[1] * options.scale, vec[2] * options.scale) #scale
		#	self.co =  Blender.Mathutils.TranslationMatrix(vec) * (self.co * object.getMatrix('worldspace'))
		
		if normal:
                        #if world:
			#	self.no = Blender.Mathutils.Vector(normal * object.getMatrix('worldspace')).normalize()
			#else:
			self.no = Blender.Mathutils.Vector(normal[0],normal[1],normal[2])
			
		else:
			#if world:
				#self.no = Blender.Mathutils.Vector(bvert.no * object.getMatrix('worldspace')).normalize() 
			#else:
			self.no = Blender.Mathutils.Vector(bvert.no[0],bvert.no[1],bvert.no[2])
			
		#do scaling factor
		#if options.scale != 1.0:
			#self.co[0] = self.co[0] * options.scale
			#self.co[1] = self.co[1] * options.scale
			#self.co[2] = self.co[2] * options.scale
			
		self.index = bvert.index

class GlobalResourceRepository:
	def new_face_name(self):
		self.face_name += 1
		return 'f%i' % (self.face_name-1)

	def vertex_count(self):
		return len(self.vertex_lst)

	def request_vertex_desc(self, i):
		return self.vertex_lst[i]

	def request_vertex_index(self, object, mesh, face, vfindex, uvok,cindex):

		flatShadeNorm = None
		vno = None

		
		if type(face) is list:
			vertex = face[vfindex]
		elif str(type(face)) == "<type " + "'Blender MVert'>": 
			vertex = face
			vno = Blender.Mathutils.Vector(0.0,0.0,1.0)
		elif str(type(face)) == "<type " + "'Blender MEdge'>":
			if vfindex == 1:
				vertex = face.v1
			elif vfindex == 2:
				vertex = face.v2
		elif str(type(face)) == "<type " + "'Blender MFace'>":
                        if not face.smooth:
                                flatShadeNorm = face.no
			vertex = face.v[vfindex]
		else: 
			return None
						
		if not self.namehash.has_key(object.name):
			self.namehash[object.name] = dict()
		indexhash = self.namehash[object.name]
		
		#export in global space? THIS HAS BEEN MADE REDUNDANT... REMOVE ME
		if not options.state['transform']:
			vertex = shadowVert(vertex,object,True,flatShadeNorm)
		else:
                        vertex = shadowVert(vertex,object,False,flatShadeNorm)
		
		if vno:
			vertex.no = vno        
        
     
		#Check to see if this vertex has been visited before. If not, add
		if not indexhash.has_key(vertex.index):
			if uvok:
				newvdesc = VertexDesc(vertex.co, vertex.no, face.uv[vfindex], self.nextvindex,cindex=cindex)
			else:
				newvdesc = VertexDesc(co=vertex.co, no=vertex.no,fltindex=self.nextvindex,cindex=cindex)
			
			indexhash[vertex.index] = [newvdesc]
			self.vertex_lst.append(newvdesc)
			self.nextvindex = self.nextvindex + 1
			return newvdesc.fltindex
		
		else:
			desclist = indexhash[vertex.index]
			if uvok: 
				faceu = face.uv[vfindex][0]
				facev = face.uv[vfindex][1]
			else:
				faceu = 0.0
				facev = 0.0
			for vdesc in desclist:
				if\
				abs(vdesc.x - vertex.co[0]) > FLOAT_TOLERANCE or\
				abs(vdesc.y - vertex.co[1]) > FLOAT_TOLERANCE or\
				abs(vdesc.z - vertex.co[2]) > FLOAT_TOLERANCE or\
				abs(vdesc.nx - vertex.no[0]) > FLOAT_TOLERANCE or\
				abs(vdesc.ny - vertex.no[1]) > FLOAT_TOLERANCE or\
				abs(vdesc.nz - vertex.no[2]) > FLOAT_TOLERANCE or\
				vdesc.cindex != cindex or\
				abs(vdesc.u - faceu) > FLOAT_TOLERANCE or\
				abs(vdesc.v - facev) > FLOAT_TOLERANCE:
					pass
				else:
					return vdesc.fltindex
				
			#if we get this far, we didnt find a match. Add a new one and return
			if uvok:
				newvdesc = VertexDesc(vertex.co, vertex.no, face.uv[vfindex], self.nextvindex,cindex=cindex)
			else:
				newvdesc = VertexDesc(co=vertex.co, no=vertex.no,fltindex=self.nextvindex,cindex=cindex)
			indexhash[vertex.index].append(newvdesc)
			self.vertex_lst.append(newvdesc)
			self.nextvindex = self.nextvindex + 1
			return newvdesc.fltindex
					
			
	def request_texture_index(self, image):
		match = None
		for i in xrange(len(self.texture_lst)):
			if self.texture_lst[i] != image:
				continue
			match = i
			break
		if match != None:
			return match
		else:
			self.texture_lst.append(image)
			return len(self.texture_lst) - 1

	def request_texture_filename(self, index):
		return Blender.sys.expandpath(self.texture_lst[index].getFilename())

	def texture_count(self):
		return len(self.texture_lst)

	def request_material_index(self, desc):
		match = None
		for i in xrange(len(self.material_lst)):
			if self.material_lst[i].diffuse != desc.diffuse:
				continue
			if self.material_lst[i].specular != desc.specular:
				continue
			if self.material_lst[i].ambient != desc.ambient:
				continue
			if self.material_lst[i].emissive != desc.emissive:
				continue
			if self.material_lst[i].shininess != desc.shininess:
				continue
			if self.material_lst[i].alpha != desc.alpha:
				continue
			match = i
			break

		if match != None:
			return i
		else:
			self.material_lst.append(desc)
			return len(self.material_lst) - 1

	def request_material_desc(self, index):
		return self.material_lst[index]

	def material_count(self):
		return len(self.material_lst)

	# Returns not actual index but one that includes intensity information.
	# color_index = 127*intensity + 128*actual_index
	def request_color_index(self, col):
		r,g,b = tuple(col)
		m = max(r, g, b)
		if m > 0.0:
			intensity = m / 1.0
			r = int(round(r/m * 255.0))
			g = int(round(g/m * 255.0))
			b = int(round(b/m * 255.0))
			brightest = [r, g, b]
		else:
			brightest = [255, 255, 255]
			intensity = 0.0

		match = None
		for i in xrange(len(self.color_lst)):
			if self.color_lst[i] != brightest:
				continue

			match = i
			break

		if match != None:
			index = match
		else:
			length = len(self.color_lst)
			if length <= 1024:
				self.color_lst.append(brightest)
				index = length
			else:
				if options.verbose >= 1:
					print 'Warning: Exceeded max color limit.'
				index = 0

		color_index = int(round(127.0*intensity)) + 128*index
		return color_index

	# Returns color from actual index.
	def request_max_color(self, index):
		return self.color_lst[index]

	def color_count(self):
		return len(self.color_lst)

	def __init__(self):
		#Vertex handling
		self.vertex_lst = []
		self.nextvindex = 0
		self.namehash = dict()
		
		self.texture_lst = []
		self.material_lst = []
		self.color_lst = [[255, 255, 255]]
		self.face_name = 0

class Node:
	# Gathers info from blender needed for export.
	# The =[0] is a trick to emulate c-like static function variables
	# that are persistant between calls.
	def blender_export(self, level=[0]):
		if self.object:
			if options.verbose >= 2:
				print '\t' * level[0], self.name, self.object.type
		level[0] += 1
		
		self.children.reverse()
		for child in self.children:
			child.blender_export()
			
		level[0] -= 1

	# Exports this node's info to file.
	def write(self):
		pass

	def write_matrix(self):
		if self.matrix and not is_identity(self.matrix):
			self.header.fw.write_short(49)   # Matrix opcode
			self.header.fw.write_ushort(68)  # Length of record
			for i in xrange(4):
				for j in xrange(4):
					self.header.fw.write_float(self.matrix[i][j])

	def write_push(self):
		self.header.fw.write_short(10)
		self.header.fw.write_ushort(4)

	def write_pop(self):
		self.header.fw.write_short(11)
		self.header.fw.write_ushort(4)
		
	def write_push_extension(self):
		self.header.fw.write_short(21)
		self.header.fw.write_ushort(24)
		self.header.fw.pad(18)
		self.header.fw.write_ushort(0)
		
	def write_pop_extension(self):
		self.header.fw.write_short(22)
		self.header.fw.write_ushort(24)
		self.header.fw.pad(18)
		self.header.fw.write_ushort(0)
		
	def write_longid(self, name):
		length = len(name)
		if length >= 8:
			self.header.fw.write_short(33)              # Long ID opcode
			self.header.fw.write_ushort(length+5)       # Length of record
			self.header.fw.write_string(name, length+1) # name + zero terminator
			
	def write_comment(self,comment):
		length = len(comment)
		if length >= 65535:
			comment = comment[:65530]
			length = len(comment)
		
		pad = (length % 4) - 1
		if pad < 0: 
			pad = None
			reclength = length + 5
		else:
			reclength = length + 5 + pad
		
		self.header.fw.write_short(31)					# Comment Opcode
		self.header.fw.write_ushort(reclength)			# Length of record is 4 + comment length + null terminator + pad
		self.header.fw.write_string(comment,length+1)	# comment + zero terminator
		if pad:
			self.header.fw.pad(pad)						# pad to multiple of 4 bytes
		
	# Initialization sets up basic tree structure.
	def __init__(self, parent, header, object,props):
		global options
		
		self.header = header
		self.object = object
		if object:
			self.name = self.object.name
			if not options.state['transform']:
				oloc = Blender.Mathutils.Vector(object.getLocation('worldspace'))
				vec = Blender.Mathutils.Vector(oloc[0] * options.state['scale'], oloc[1] * options.state['scale'], oloc[2] * options.state['scale']) #scale
				self.matrix =  self.object.getMatrix('worldspace') *  Blender.Mathutils.TranslationMatrix(vec - oloc)			
			else:
				self.matrix = self.object.getMatrix('localspace') #do matrix mult here.
			self.props = props
			self.child_objects = self.header.parenthash[object.name]
		else:
			self.name = 'no name'
			self.matrix = None
			self.props = None
			self.child_objects = self.header.child_objects
		
		self.children = []
		self.parent = parent
		if parent:
			parent.children.append(self)
		
		# Spawn children.
		for child in self.child_objects:			
			if(not child.restrictDisplay):
				childprops = None
				ftype = None
				if not child.properties.has_key('FLT'):
					if child.type == 'Empty':
						if child.DupGroup:
							childprops = FLTXRef.copy()
							ftype = 63
						else:
							childprops = FLTGroup.copy()
							ftype = 2
					elif child.type == 'Mesh':
						if self.header.childhash[child.name] or not child.parent:
							childprops = FLTGroup.copy()
							ftype = 2
						else:
							childprops = FLTObject.copy()
							ftype = 4
							
				else:
					childprops = dict()
					for prop in child.properties['FLT']:
						childprops[prop] = child.properties['FLT'][prop]
					ftype = child.properties['FLT']['type']
				
				if ftype in self.childtypes and ftype in alltypes:
					Newnode = FLTNode(self,header,child,childprops,ftype)
					if child.type == 'Mesh':
						self.header.mnodes.append(Newnode)
class FaceDesc:
	def __init__(self):
		self.vertex_index_lst = []
		self.mface = None
		self.texture_index = -1
		self.material_index = -1
		self.color_index = 127
		self.renderstyle = 0
		self.twoside = 0
		self.name = None #uses next FLT name if not set... fix resolution of conflicts!
		self.billboard = 0
		
		#Multi-Tex info. Dosn't include first UV Layer!
		self.uvlayer = list() #list of list of tuples for UV coordinates.
		self.images = list()  #list of texture indices for seperate UV layers
		self.mtex = list()
		self.subface = None #can either be 'Push' or 'Pop'

def edge_get_othervert(vert, edge):
	if edge.v1 == vert:
		return edge.v2
	elif edge.v2 == vert:
		return edge.v1
	return None

class FLTNode(Node):
	def walkLoop(self, targetvert, startvert, startedge, edgelist, visited, vedges, closeloop):
		loop = [targetvert]
		
		curvert = startvert
		curedge = startedge
		visited[curedge] = True
		found = False
		
		while not found:
			loop.append(curvert)
			disk = vedges[curvert.index]
			if not closeloop:
				if len(disk) == 1:
					visited[curedge] = True
					break
			else:
				if len(disk) < 2: #what?
					visited[curedge] = True
					return None
			
			if disk[0] == curedge:
				curedge = disk[1]
			else:
				curedge = disk[0]
			if curedge.v1.index == curvert.index:
				curvert = curedge.v2
			else:
				curvert = curedge.v1

			visited[curedge] = True
			
			if(curvert == targetvert):
				found = True
		
		return loop
	
	def buildVertFaces(self,vertuse):
		for vert in self.exportmesh.verts:
			if vertuse[vert.index][0] == False and vertuse[vert.index][1] == 0:
				face_desc = FaceDesc()
				face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object, self.exportmesh, vert, 0,0,0))
				face_desc.renderstyle = 3
				face_desc.color_index = 227
				self.face_lst.append(face_desc)

	def buildEdgeFaces(self,vertuse):
		for edge in self.exportmesh.edges:
			v1 = vertuse[edge.v1.index]
			v2 = vertuse[edge.v2.index]
			if v1[0] == False and v2[0] == False:
				if v1[1] == 1 and v2[1] == 1:
					face_desc = FaceDesc()
					face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object, self.exportmesh, edge, 1, 0,0))
					face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object, self.exportmesh, edge, 2, 0,0))					
					face_desc.renderstyle = 3
					face_desc.color_index = 227
					self.face_lst.append(face_desc)


	def vertwalk(self, startvert, loop, disk, visited):
		visited[startvert] = True
		for edge in disk[startvert]:
			othervert = edge_get_othervert(startvert, edge)
			if not visited[othervert]:
				loop.append(othervert)
				self.vertwalk(othervert,loop,disk,visited)

	def buildOpenFacesNew(self, vertuse):
		wireverts = list()
		wiredges = list()
		visited = dict()
		disk = dict()
		loops = list()
		
		for edge in self.exportmesh.edges:
			v1 = vertuse[edge.v1.index]
			v2 = vertuse[edge.v2.index]
			if v1[0] == False and v2[0] == False:
				if v1[1] < 3 and v2[1] < 3:
					wireverts.append(edge.v1)
					wireverts.append(edge.v2)
					wiredges.append(edge)
				
		#build disk data
		for vert in wireverts:
			visited[vert] = False
			disk[vert] = list()
		for edge in wiredges:
			disk[edge.v1].append(edge)
			disk[edge.v2].append(edge)
		
		#first pass: do open faces
		for vert in wireverts:
			if not visited[vert] and vertuse[vert.index][1] == 1:
				loop = list()
				done = 0
				startvert = vert
				while not done:
					done = 1
					visited[startvert] = True
					loop.append(startvert)
					for edge in disk[startvert]:
						othervert = edge_get_othervert(startvert, edge)
						if not visited[othervert]:
							done = 0
							startvert = othervert
							break
				if len(loop) > 2: loops.append( ('Open', loop) )
		for vert in wireverts:
			if not visited[vert]:
				loop = list()
				done = 0
				startvert = vert
				while not done:
					done = 1
					visited[startvert] = True
					loop.append(startvert)
					for edge in disk[startvert]:
						othervert = edge_get_othervert(startvert,edge)
						if not visited[othervert]:
							done = 0
							startvert = othervert
							break
				if len(loop) > 2: loops.append( ('closed', loop) )
		
		#now go through the loops and append.
		for l in loops:
			(ftype, loop) = l
			face_desc = FaceDesc()
			for i,vert in enumerate(loop):
				face_desc.vertex_index_lst.append(self.header.GRR.request_vertex_index(self.object,self.exportmesh,loop,i,0,0))
				if ftype  == 'closed':
					face_desc.renderstyle = 2
				else:
					face_desc.renderstyle = 3
				face_desc.color_index = 227
			self.face_lst.append(face_desc)



	def sortFLTFaces(self,a,b):
		aindex = a.getProperty("FLT_ORIGINDEX")
		bindex = b.getProperty("FLT_ORIGINDEX")
		
		if aindex > bindex:
			return 1
		elif aindex < bindex:
			return -1
		return 0

	def buildNormFaces(self):
		
		global options
		meshlayers = self.exportmesh.getUVLayerNames()
		oldlayer = self.exportmesh.activeUVLayer
		uvok = 0
		subfaceok = 0
		subfacelevel = 0
		
		#special case
		if self.exportmesh.faceUV and len(meshlayers) == 1:
			uvok = 1
		elif self.exportmesh.faceUV and tex_layers[0] in meshlayers:
			self.exportmesh.activeUVLayer = tex_layers[0] 
			uvok = 1
		
		#Sort faces according to the subfaces/FLT indices
		if "FLT_ORIGINDEX" in self.exportmesh.faces.properties and "FLT_SFLEVEL" in self.exportmesh.faces.properties:
			exportfaces = list()
			for face in self.exportmesh.faces:
				exportfaces.append(face)
			exportfaces.sort(self.sortFLTFaces)
			subfaceok = 1
		else:
			exportfaces = self.exportmesh.faces
			
		# Faces described as lists of indices into the GRR's vertex_lst.
		for face in exportfaces:
			descs = list()
			#first we export the face as normal
			index_lst = []
			face_v = face.verts
			for i, v in enumerate(face_v):
				index_lst.append(self.header.GRR.request_vertex_index(self.object,self.exportmesh,face,i,uvok,0))
			face_desc = FaceDesc()
			face_desc.vertex_index_lst = index_lst
			face_desc.mface = face
			descs.append(face_desc)
			
			#deal with subfaces			
			if subfaceok:
				fsflevel = face.getProperty("FLT_SFLEVEL")
				for face_desc in descs:
					if fsflevel > subfacelevel:
						face_desc.subface = 'Push'
						subfacelevel = fsflevel
					elif fsflevel < subfacelevel:
						face_desc.subface = 'Pop'
						subfacelevel = fsflevel
		
			
			if uvok and (face.mode & Blender.Mesh.FaceModes.TWOSIDE):
				face_desc.renderstyle = 1
			for face_desc in descs:	
				if "FLT_COL" in self.exportmesh.faces.properties:
					color_index = face.getProperty("FLT_COL")
#					if(color_index < 127):
#						color_index = 127 #sanity check for face color indices
					if(color_index == 0):
						color_index = 127
					face_desc.color_index = color_index
				else:
					face_desc.color_index = 127
				if "FLT_ID" in self.exportmesh.faces.properties:
					face_desc.name = face.getProperty("FLT_ID") #need better solution than this.
				
				if uvok and face.mode & Blender.Mesh.FaceModes["BILLBOARD"]:
					face_desc.billboard = 1
					
				self.face_lst.append(face_desc)
		if uvok:		
			self.exportmesh.activeUVLayer = oldlayer

	def buildTexData(self):
		
		meshlayers = self.exportmesh.getUVLayerNames()
		oldlayer = self.exportmesh.activeUVLayer
		uvok = 0
		
		if self.exportmesh.faceUV and len(meshlayers) == 1:
			uvok = 1
		if self.exportmesh.faceUV and tex_layers[0] in meshlayers:
			self.exportmesh.activeUVLayer = tex_layers[0] 
			uvok = 1
		
		if uvok: 
			#do base layer. UVs have been stored on vertices directly already.
			for i, face in enumerate(self.face_lst):
				if face.mface:
					mface = face.mface
					image = mface.image
					if image != None and mface.mode & Blender.Mesh.FaceModes["TEX"]:
						index = self.header.GRR.request_texture_index(image)
					else:
						index = -1
					face.texture_index = index

			for i, face in enumerate(self.face_lst):
				if face.mface:
					mface_v = face.mface.v
					for v in mface_v:
						face.uvlayer.append([])
			
			for layername in tex_layers[1:]:
				if layername in meshlayers:
					self.exportmesh.activeUVLayer=layername
					for i, face in enumerate(self.face_lst):
						if face.mface:

							face.mtex.append(layername)
							mface = face.mface
							mface_v = mface.v
							image = mface.image
						
							if image != None and mface.mode & Blender.Mesh.FaceModes["TEX"]:
								index = self.header.GRR.request_texture_index(image)
								face.images.append(index)
							else:
								face.images.append(-1)

							for j, v in enumerate(mface_v):
								face.uvlayer[j].append(tuple(mface.uv[j]))
		if uvok:
			self.exportmesh.activeUVLayer = oldlayer
	def blender_export(self):
		global options
		Node.blender_export(self)
		if self.opcode == 111:
			self.exportmesh = Blender.Mesh.New()
			self.exportmesh.getFromObject(self.object.name)			

			for vert in self.exportmesh.verts:
				if not options.state['transform']:
					vec = vert.co
					vec = Blender.Mathutils.Vector(vec[0] * options.state['scale'], vec[1] * options.state['scale'], vec[2] * options.state['scale']) #scale
					vert.co =  Blender.Mathutils.TranslationMatrix(vec) * (vert.co * self.object.getMatrix('worldspace'))						
				
				if options.state['scale'] != 1.0:
					vert.co = vert.co * options.state['scale']

			if("FLT_VCOL") in self.mesh.verts.properties:
				for v in self.exportmesh.verts:
					self.vert_lst.append(self.header.GRR.request_vertex_index(self.object,self.exportmesh,v,0,0,v.getProperty("FLT_VCOL")))
			else:
				for v in self.mesh.verts:
					self.vert_lst.append(self.header.GRR.request_vertex_index(self.object,self.mesh,v,0,0,127))
			
		
		
		elif self.mesh:
                        orig_mesh = self.object.getData(mesh=True)
			self.exportmesh = Blender.Mesh.New()
			default = None


			if options.state['export_shading']:
				mods = self.object.modifiers
				hasedsplit = False
				for mod in mods:
					if mod.type == Blender.Modifier.Types.EDGESPLIT:
						hasedsplit = True
						break
				if not hasedsplit:
					default = mods.append(Modifier.Types.EDGESPLIT)
					default[Modifier.Settings.EDGESPLIT_ANGLE] = options.state['shading_default']
					default[Modifier.Settings.EDGESPLIT_FROM_ANGLE] = True
					default[Modifier.Settings.EDGESPLIT_FROM_SHARP] = False
					self.object.makeDisplayList()

			self.exportmesh.getFromObject(self.object.name)

			#recalculate vertex positions
			for vert in self.exportmesh.verts:
				if not options.state['transform']:
					vec = vert.co
					vec = Blender.Mathutils.Vector(vec[0] * options.state['scale'], vec[1] * options.state['scale'], vec[2] * options.state['scale']) #scale
					vert.co =  Blender.Mathutils.TranslationMatrix(vec) * (vert.co * self.object.getMatrix('worldspace'))						
				
				if options.state['scale'] != 1.0:
					vert.co = vert.co * options.state['scale']			
			
			flipped = self.object.getMatrix('worldspace').determinant()
			
			if not options.state['transform']:
				self.exportmesh.calcNormals()
			

			if default:
                                #remove modifier from list
				mods.remove(default)
				self.object.makeDisplayList()
				
			#build some adjacency data
			vertuse = list()
			wiredges = list()
			openends = list()
			for v in self.exportmesh.verts:
				vertuse.append([False,0])
			
			#build face incidence data
			for face in self.exportmesh.faces:
				for i, v in enumerate(face.verts):
					vertuse[v.index][0] = True

			for edge in self.exportmesh.edges: #count valance
				vertuse[edge.v1.index][1] = vertuse[edge.v1.index][1] + 1
				vertuse[edge.v2.index][1] = vertuse[edge.v2.index][1] + 1

			#create all face types
			self.buildVertFaces(vertuse)
			self.buildEdgeFaces(vertuse)
			self.buildOpenFacesNew(vertuse)
			self.buildNormFaces()
			self.buildTexData()
			
			if not options.state['transform']:
				if flipped < 0:
					for vdesc in self.header.GRR.vertex_lst:
						vdesc.accum = 0
					for face in self.face_lst:
						face.vertex_index_lst.reverse()
						for vert in face.vertex_index_lst:
							self.header.GRR.vertex_lst[vert].accum = 1
							
					for vdesc in self.header.GRR.vertex_lst:
						if vdesc.accum:
							vdesc.nx = vdesc.nx * -1
							vdesc.ny = vdesc.ny * -1
							vdesc.nz = vdesc.nz * -1


	def write_faces(self):
		sublevel = 0
		for face_desc in self.face_lst:
			if face_desc.name:
				face_name = face_desc.name
			else:
				face_name = self.header.GRR.new_face_name()
			
			#grab the alpha value.
			alpha = 0
			if face_desc.texture_index > -1:
				try:
					typestring = os.path.splitext(self.header.GRR.texture_lst[face_desc.texture_index].getFilename())[1]
					if typestring == '.inta' or typestring == '.rgba':
						alpha = 1
				except:
					pass
					
			if not alpha:
				for index in face_desc.images:
					try:
						typestring = os.path.splitext(self.header.GRR.texture_lst[index].getFilename())[1]
						if typestring == '.inta' or typestring == '.rgba':
							alpha = 1
					except:
						pass
						
			if face_desc.billboard:
				alpha = 2
				
			if face_desc.subface:
				if face_desc.subface == 'Push':
					self.header.fw.write_short(19)
					self.header.fw.write_ushort(4)
					sublevel += 1
				else:
					self.header.fw.write_short(20)
					self.header.fw.write_ushort(4)
					sublevel -= 1
			self.header.fw.write_short(5)                                   # Face opcode
			self.header.fw.write_ushort(80)                                 # Length of record
			self.header.fw.write_string(face_name, 8)                       # ASCII ID
			self.header.fw.write_int(-1)                                    # IR color code
			self.header.fw.write_short(0)									# Relative priority
			self.header.fw.write_char(face_desc.renderstyle)                # Draw type
			self.header.fw.write_char(0)                                    # Draw textured white.
			self.header.fw.write_ushort(0)                                  # Color name index
			self.header.fw.write_ushort(0)                                  # Alt color name index
			self.header.fw.write_char(0)                                    # Reserved
			self.header.fw.write_char(alpha)                                    # Template
			self.header.fw.write_short(-1)                                  # Detail tex pat index
			self.header.fw.write_short(face_desc.texture_index)             # Tex pattern index
			self.header.fw.write_short(face_desc.material_index)            # material index
			self.header.fw.write_short(0)                                   # SMC code
			self.header.fw.write_short(0)                                   # Feature 					code
			self.header.fw.write_int(0)                                     # IR material code
			self.header.fw.write_ushort(0)                                  # transparency 0 = opaque
			self.header.fw.write_uchar(0)                                   # LOD generation control
			self.header.fw.write_uchar(0)                                   # line style index
			self.header.fw.write_int(0)                            # Flags
			self.header.fw.write_uchar(2)                                   # Light mode
			#self.header.fw.write_uchar(3)                                   # Light mode

			self.header.fw.pad(7)                                           # Reserved
			self.header.fw.write_uint(0)                                   # Packed color
			self.header.fw.write_uint(0)                                   # Packed alt color
			self.header.fw.write_short(-1)                                  # Tex map index
			self.header.fw.write_short(0)                                   # Reserved
			self.header.fw.write_uint(face_desc.color_index)                # Color index
			self.header.fw.write_uint(127)                                  # Alt color index
			self.header.fw.write_short(0)                                   # Reserved
			self.header.fw.write_short(-1)                                  # Shader index

			self.write_longid(face_name)
			
			
			#Write Multitexture field if appropriate
			mtex = len(face_desc.mtex)
			if mtex:
				uvmask = 0
				for layername in face_desc.mtex:
					mask = mtexmasks[tex_layers.index(layername)-1]
					uvmask |= mask
				self.header.fw.write_ushort(52)									# MultiTexture Opcode
				self.header.fw.write_ushort(8 + (mtex * 8))		# Length
				self.header.fw.write_uint(uvmask)								# UV mask
				for i in xrange(mtex):
					self.header.fw.write_ushort(face_desc.images[i])			# Tex pattern index
					self.header.fw.write_ushort(0)								# Tex effect
					self.header.fw.write_ushort(0)								# Tex Mapping index
					self.header.fw.write_ushort(0)								# Tex data. User defined
			
			self.write_push()

			# Vertex list record
			self.header.fw.write_short(72)                        # Vertex list opcode
			num_verts = len(face_desc.vertex_index_lst)
			self.header.fw.write_ushort(4*num_verts+4)            # Length of record

			for vert_index in face_desc.vertex_index_lst:
				# Offset into vertex palette
				self.header.fw.write_int(vert_index*64+8)
			
			#UV list record
			if mtex:
				#length = 8 + (numverts * multitex * 8)
				self.header.fw.write_ushort(53)									# UV List Ocode
				self.header.fw.write_ushort(8 + (num_verts*mtex*8))				# Record Length
				self.header.fw.write_uint(uvmask)								# UV mask
				for i, vert_index in enumerate(face_desc.vertex_index_lst):
					for uv in face_desc.uvlayer[i]:
						self.header.fw.write_float(uv[0])						#U coordinate
						self.header.fw.write_float(uv[1])						#V coordinate				
			self.write_pop()
		#clean up faces at the end of meshes....
		if sublevel:
			self.header.fw.write_short(20)
			self.header.fw.write_ushort(4)

	def write_lps(self):
		# Vertex list record
		self.write_push()
		self.header.fw.write_short(72)                        # Vertex list opcode
		num_verts = len(self.vert_lst)
		self.header.fw.write_ushort(4*num_verts+4)            # Length of record

		for vert_index in self.vert_lst:
			# Offset into vertex palette
			self.header.fw.write_int(vert_index*64+8)
		self.write_pop()
	def write(self):
		self.header.fw.write_short(self.opcode)
		self.header.fw.write_ushort(recordlen[self.opcode])
		exportdict = FLT_Records[self.opcode].copy()
		if self.object:
			self.props['3t8!id'] = self.object.name[:7]
		for key in exportdict.keys():
			if self.props.has_key(key):
				exportdict[key] = self.props[key]

                if self.opcode == 63 and options.state['externalspath']:
				try:
					exportdict['3t200!filename'] = os.path.join(options.state['externalspath'],self.object.DupGroup.name+'.flt')
					self.header.xrefnames.append(self.object.DupGroup.name)
				except:
					pass
		
		for key in records[self.opcode]:
			(ftype,length,propname) = records[self.opcode][key]
			write_prop(self.header.fw,ftype,exportdict[propname],length)
		
		if self.props.has_key('comment'):
			self.write_comment(self.props['comment'])

		if self.object and self.object.properties.has_key('FLT') and self.object.properties['FLT'].has_key('EXT'):
			datalen = len(self.object.properties['FLT']['EXT']['data'])
			self.write_push_extension()
			self.header.fw.write_short(100)
			self.header.fw.write_ushort(24 + datalen)
			for key in records[100]:
				(ftype,length,propname) = records[100][key]
				write_prop(self.header.fw,ftype,self.object.properties['FLT']['EXT'][propname],length)
			#write extension data
			for i in xrange(datalen):
				self.header.fw.write_char(self.object.properties['FLT']['EXT']['data'][i])
			self.write_pop_extension()


		self.write_longid(self.name) #fix this!
		
		if options.state['transform'] or self.opcode == 63:
			#writing transform matrix....
			self.write_matrix()

		if self.opcode == 111:
			self.write_lps()
		elif self.face_lst != [] or self.children:
			self.write_push()
			if self.face_lst != []:
				#self.write_push()
				self.write_faces()
				#self.write_pop()
		
			if self.children:
				#self.write_push()
				for child in self.children:
					child.write()
				#self.write_pop()
			self.write_pop()
			
	def __init__(self, parent, header, object,props,ftype):
		self.opcode = ftype #both these next two lines need to be in the node class....
		self.childtypes = childtypes[self.opcode]
		Node.__init__(self, parent, header, object,props)
		self.face_lst = []
		self.vert_lst = [] #for light points.
		self.mesh = None
		self.uvlayer = 0
		self.flipx = False
		self.flipy = False
		self.flipz = False
		
				
		if self.object.type == 'Mesh':
			self.mesh = self.object.getData(mesh=True)
			if(self.mesh.faceUV):
				self.uvLayer = len(self.mesh.getUVLayerNames())

class Database(Node):
	def write_header(self):
		if options.verbose >= 2:
			print 'Writing header.'
		self.fw.write_short(1)          # Header opcode
		self.fw.write_ushort(324)       # Length of record
		self.fw.write_string('db', 8)   # ASCII ID
		self.fw.write_int(1600)         # Revision Number
		self.fw.pad(44)
		self.fw.write_short(1)          # Unit multiplier.
		self.fw.write_char(0)           # Units, 0 = meters
		self.fw.write_char(0)           # texwhite on new faces 0 = false
		self.fw.write_uint(0x80000000)  # misc flags set to saving vertex normals
		self.fw.pad(24)
		self.fw.write_int(0)            # projection type, 0 = flat earth
		self.fw.pad(30)
		self.fw.write_short(1)          # double precision
		self.fw.write_int(100)			# database origin type
		self.fw.pad(88)
		try:
			self.fw.write_double(self.header.scene.properties['FLT']['origin lat'])	#database origin lattitude
		except:
			self.fw.write_double(0)
		try:
			self.fw.write_double(self.header.scene.properties['FLT']['origin lon']) #database origin longitude
		except:
			self.fw.write_double(0)
		self.fw.pad(32)
		self.fw.write_int(0)            # ellipsoid model, 0 = WSG 1984
		
		self.fw.pad(52)

	def write_vert_pal(self):
		if options.verbose >= 2:
			print 'Writing vertex palette.'
		# Write record for vertex palette
		self.fw.write_short(67)                             # Vertex palette opcode.
		self.fw.write_short(8)                              # Length of record
		self.fw.write_int(self.GRR.vertex_count() * 64 + 8) # Length of everything.
		# Write records for individual vertices.
		for i in xrange(self.GRR.vertex_count()):
			desc = self.GRR.request_vertex_desc(i)
			self.fw.write_short(70)                         # Vertex with color normal and uv opcode.
			self.fw.write_ushort(64)                        # Length of record
			self.fw.write_ushort(0)							# Color name index
			self.fw.write_short(0x20000000)					# Flags
			self.fw.write_double(desc.x)
			self.fw.write_double(desc.y)
			self.fw.write_double(desc.z)
			self.fw.write_float(desc.nx)
			self.fw.write_float(desc.ny)
			self.fw.write_float(desc.nz)
			self.fw.write_float(desc.u)
			self.fw.write_float(desc.v)
			self.fw.pad(4)
			self.fw.write_uint(desc.cindex)
			self.fw.pad(4)

	def write_tex_pal(self):
		if options.verbose >= 2:
			print 'Writing texture palette.'
		# Write record for texture palette
		for i, img in enumerate(self.GRR.texture_lst):
			filename = tex_files[img.name]
			self.fw.write_short(64)                                         # Texture palette opcode.
			self.fw.write_short(216)                                        # Length of record
			self.fw.write_string(filename, 200) # Filename
			self.fw.write_int(i)                                            # Texture index
			self.fw.write_int(0)                                            # X
			self.fw.write_int(0)                                            # Y

	def write_mat_pal(self):
		if options.verbose >= 2:
			print 'Writing material palette.'
		for i in xrange(self.GRR.material_count()):
			desc = self.GRR.request_material_desc(i)
			self.fw.write_short(113)                # Material palette opcode.
			self.fw.write_short(84)                 # Length of record
			self.fw.write_int(i)                    # Material index
			self.fw.write_string(desc.name, 12)     # Material name
			self.fw.write_uint(0x80000000)          # Flags
			self.fw.write_float(desc.ambient[0])    # Ambient color.
			self.fw.write_float(desc.ambient[1])    # Ambient color.
			self.fw.write_float(desc.ambient[2])    # Ambient color.
			self.fw.write_float(desc.diffuse[0])    # Diffuse color.
			self.fw.write_float(desc.diffuse[1])    # Diffuse color.
			self.fw.write_float(desc.diffuse[2])    # Diffuse color.
			self.fw.write_float(desc.specular[0])   # Specular color.
			self.fw.write_float(desc.specular[1])   # Specular color.
			self.fw.write_float(desc.specular[2])   # Specular color.
			self.fw.write_float(desc.emissive[0])   # Emissive color.
			self.fw.write_float(desc.emissive[1])   # Emissive color.
			self.fw.write_float(desc.emissive[2])   # Emissive color.
			self.fw.write_float(desc.shininess)
			self.fw.write_float(desc.alpha)
			self.fw.write_int(0)                    # Reserved

	def write_col_pal(self):
		if options.verbose >= 2:
			print 'Writing color palette.'
		self.fw.write_short(32)                     # Color palette opcode.
		self.fw.write_short(4228)                   # Length of record
		self.fw.pad(128)
		try:
			cpalette = self.scene.properties['FLT']['Color Palette']
		except:
			cpalette = defaultp.pal
		count = len(cpalette)
		for i in xrange(count):
			color = struct.unpack('>BBBB',struct.pack('>I',cpalette[i]))
			self.fw.write_uchar(color[3])               # alpha
			self.fw.write_uchar(color[2])               # b
			self.fw.write_uchar(color[1])               # g
			self.fw.write_uchar(color[0])               # r
		self.fw.pad(max(4096-count*4, 0))

	def write(self):
		self.write_header()
		self.write_vert_pal()
		self.write_tex_pal()
		self.write_mat_pal()
		self.write_col_pal()

		self.write_push()
		
		for child in self.children:
			child.write()
		self.write_pop()
	
	def export_textures(self,texturepath):
		for i in xrange(self.GRR.texture_count()):
			texture = self.GRR.texture_lst[i]
			
			if options.state['copytex']:
				filename = os.path.normpath(os.path.join(options.state['texturespath'], os.path.basename(self.GRR.request_texture_filename(i))))
			else:
				filename = os.path.normpath(self.GRR.request_texture_filename(i))
			
			tex_files[texture.name] = filename

	def blender_export(self):
		Node.blender_export(self)
		self.export_textures(self)
		return self.xrefnames
	def __init__(self, scene, fw):
		self.fw = fw
		self.opcode = 1
		self.childtypes = [73,14,2,63]
		self.scene = scene
		self.childhash = dict()
		self.parenthash = dict()
		self.child_objects = list()
		self.mnodes = list()
		self.xrefnames = list()
		for i in self.scene.objects:
			self.parenthash[i.name] = list()
			self.childhash[i.name] = False
		for i in self.scene.objects:
			if i.parent:
				self.childhash[i.parent.name] = True
				self.parenthash[i.parent.name].append(i)
			else:
				self.child_objects.append(i)

		self.GRR = GlobalResourceRepository()
		Node.__init__(self, None, self, None,None)

def write_attribute_files():
	for imgname in tex_files:
		blentex = Blender.Image.Get(imgname)
		exportdict = FLT_Records['Image'].copy()
		
		if blentex.properties.has_key('FLT'):
			for key in exportdict.keys():
				if blentex.properties.has_key(key):
					exportdict[key] = blentex.properties['FLT'][key]
		
		# ClampX/Y override
		if blentex.clampX:
			exportdict['11i!WrapU'] = 1
		if blentex.clampY:
			exportdict['12i!WrapV'] = 1 
		
		exportdict['16i!Enviorment'] = 0 
		
		# File type
		typecode = 0
		try:
			typestring = os.path.splitext(blentex.getFilename())[1]
			
			if typestring == '.rgba':
				typecode = 5
			elif typestring == '.rgb':
				typecode = 4
			elif typestring == '.inta':
				typecode = 3
			elif typestring == '.int':
				typecode = 2
		except:
			pass
		
		exportdict['7i!File Format'] = typecode

		fw = FltOut(tex_files[imgname] + '.attr')
		size = blentex.getSize()
		fw.write_int(size[0])
		fw.write_int(size[1])
		for key in records['Image']:
			(ftype,length,propname) = records['Image'][key]
			write_prop(fw,ftype,exportdict[propname],length)
		fw.close_file()

#globals used by the scene export function
exportlevel = None
xrefsdone = None

def dbexport_internal(scene):
	global exportlevel
	global xrefsdone
	global options

	if exportlevel == 0 or not options.state['externalspath']:
		fname = os.path.join(options.state['basepath'],scene.name + '.flt')
	else:
		fname = os.path.join(options.state['externalspath'],scene.name + '.flt')
	
	fw = FltOut(fname)
	db = Database(scene,fw)
	
	if options.verbose >= 1:
		print 'Pass 1: Exporting ', scene.name,'.flt from Blender.\n'
	
	xreflist = db.blender_export()
	if options.verbose >= 1:
		print 'Pass 2: Writing %s\n' % fname
	db.write()
	fw.close_file()
	
	if options.state['doxrefs']:
		for xname in xreflist:
			try:
				xrefscene = Blender.Scene.Get(xname)
			except:
				xrefscene = None
			if xrefscene and xname not in xrefsdone:
				xrefsdone.append(xname)
				exportlevel+=1
				dbexport_internal(xrefscene)
				exportlevel-=1
	return fname
#main database export function
def dbexport():
	global exportlevel
	global xrefsdone
	exportlevel = 0
	xrefsdone = list()
	
	Blender.Window.WaitCursor(True)
	time1 = Blender.sys.time() # Start timing
	
	if options.verbose >= 1:
		print '\nOpenFlight Exporter'
		print 'Version:', __version__
		print 'Author: Greg MacDonald, Geoffrey Bantle'
		print __url__[2]
		print
	
	fname = dbexport_internal(Blender.Scene.GetCurrent())
	if options.verbose >=1:
		print 'Done in %.4f sec.\n' % (Blender.sys.time() - time1)
	Blender.Window.WaitCursor(False)
	
	#optional: Copy textures
	if options.state['copytex']:
		for imgname in tex_files:
			#Check to see if texture exists in target directory
			if not os.path.exists(tex_files[imgname]):
				#Get original Blender file name
				origpath = Blender.sys.expandpath(Blender.Image.Get(imgname).getFilename())
				#copy original to new
				if os.path.exists(origpath):
					shutil.copyfile(origpath,tex_files[imgname])
	
	#optional: Write attribute files
	if options.state['attrib']:
		write_attribute_files()

	if options.state['xapp']:
		cmd= options.state['xappath'] + " " + fname 
		status = os.system(cmd)
	

#Begin UI code
FLTExport = None
FLTClose = None
FLTLabel = None

FLTBaseLabel = None
FLTTextureLabel = None
FLTXRefLabel = None

FLTBaseString = None
FLTTextureString = None
FLTXRefString = None

FLTBasePath = None
FLTTexturePath = None
FLTXRefPath = None

FLTShadeExport = None
FLTShadeDefault = None

FLTCopyTex = None
FLTDoXRef = None
FLTGlobal = None

FLTScale = None

FLTXAPP = None
FLTXAPPath = None
FLTXAPPString = None
FLTXAPPLabel = None
FLTXAPPChooser = None

FLTAttrib = None


FLTWarn = None

def setshadingangle(ID,val):
	global options
	options.state['shading_default'] = val
def setBpath(fname):
	global options
	options.state['basepath'] = os.path.dirname(fname)
	#update xref and textures path too....
	if(os.path.exists(os.path.join(options.state['basepath'],'externals'))):
		options.state['externalspath'] = os.path.join(options.state['basepath'],'externals')
	if(os.path.exists(os.path.join(options.state['basepath'],'textures'))):
		options.state['texturespath'] = os.path.join(options.state['basepath'],'textures')
def setexportscale(ID,val):
	global options
	options.state['scale'] = val

def setTpath(fname):
	global options
	options.state['texturespath'] = os.path.dirname(fname)
def setXpath(fname):
	global options
	options.state['externalspath'] = os.path.dirname(fname)
def setXApath(fname):
	global options
	options.state['xappath'] = fname
def event(evt, val):
	x = 1
def but_event(evt):
	global options
	
	global FLTExport
	global FLTClose 
	global FLTLabel
	
	global FLTBaseLabel
	global FLTTextureLabel
	global FLTXRefLabel

	global FLTBaseString
	global FLTTextureString
	global FLTXRefString
	
	global FLTBasePath
	global FLTTexturePath
	global FLTXRefPath
	
	global FLTShadeExport
	global FLTShadeDefault
	
	global FLTCopyTex
	global FLTDoXRef
	global FLTGlobal
	
	global FLTScale
	
	
	global FLTXAPP
	global FLTXAPPath
	global FLTXAPPString
	global FLTXAPPLabel 	
	global FLTXAPPChooser

	global FLTAttrib
	
	global FLTWarn
	
	#choose base path for export
	if evt == 4:
		Blender.Window.FileSelector(setBpath, "DB Root", options.state['basepath'])
		
	#choose XREF path
	if evt == 6:
		Blender.Window.FileSelector(setXpath,"DB Externals",options.state['externalspath'])

	#choose texture path
	if evt == 8:
		Blender.Window.FileSelector(setTpath,"DB Textures",options.state['texturespath'])

	#export shading toggle
	if evt == 9:
		options.state['export_shading'] = FLTShadeExport.val
	#export Textures
	if evt == 11:
		options.state['copytex']= FLTCopyTex.val
	#export XRefs
	if evt == 13:
		options.state['doxrefs'] = FLTDoXRef.val
	#export Transforms
	if evt == 12:
		options.state['transform'] = FLTGlobal.val
		
	if evt == 14:
		options.state['xapp'] = FLTXAPP.val
	if evt == 16:
		Blender.Window.FileSelector(setXApath,"External Application",options.state['xappath'])
	if evt == 20:
		options.state['attrib'] = FLTAttrib.val
	
	#Export DB
	if evt == 1:
		try:
			dbexport()		
		except Exception, inst:
			import traceback
			FLTWarn = Draw.PupBlock("Export Error", ["See console for output!"])
			traceback.print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)

	#exit
	if evt == 2:
		Draw.Exit()

	options.write_state()

from Blender.BGL import *
from Blender import Draw
def gui():
	
	global options
	
	global FLTExport
	global FLTClose 
	global FLTLabel
	
	global FLTBaseLabel
	global FLTTextureLabel
	global FLTXRefLabel

	global FLTBaseString
	global FLTTextureString
	global FLTXRefString
	
	global FLTBasePath
	global FLTTexturePath
	global FLTXRefPath
	
	global FLTShadeExport
	global FLTShadeDefault
	
	global FLTCopyTex
	global FLTDoXRef
	global FLTGlobal
	
	global FLTScale
	
	global FLTXAPP
	global FLTXAPPath
	global FLTXAPPString
	global FLTXAPPLabel
	global FLTXAPPChooser	
	
	global FLTAttrib
	
	glClearColor(0.880,0.890,0.730,1.0 )
	glClear(GL_COLOR_BUFFER_BIT)
	
	areas = Blender.Window.GetScreenInfo()
	curarea = Blender.Window.GetAreaID()
	curRect = None
	
	for area in areas:
		if area['id'] == curarea:
			curRect = area['vertices']
			break
	
	width = curRect[2] - curRect[0]
	height = curRect[3] - curRect[1]
	#draw from top to bottom....
	cx = 50
	#Draw Title Bar...
	#glRasterPos2d(cx, curRect[3]-100)
	#FLTLabel = Draw.Text("FLT Exporter V2.0",'large')
	cy = height - 80
	
	FLTBaseLabel = Draw.Label("Base Path:",cx,cy,100,20)
	FLTBaseString = Draw.String("",3,cx+100,cy,300,20,options.state['basepath'],255,"Folder to export to")
	FLTBaseChooser = Draw.PushButton("...",4,cx+400,cy,20,20,"Choose Folder")
	
	cy = cy-40
	
	#externals path
	FLTXRefLabel = Draw.Label("XRefs:",cx,cy,100,20)
	FLTXRefString = Draw.String("",5,cx+100,cy,300,20,options.state['externalspath'],255,"Folder for external references")
	FLTXRefChooser = Draw.PushButton("...",6,cx+400,cy,20,20,"Choose Folder")
	cy = cy-40
	#Textures path
	FLTTextureLabel = Draw.Label("Textures:",cx,cy,100,20)
	FLTTextureString = Draw.String("",7,cx+100,cy,300,20,options.state['texturespath'],255,"Folder for texture files")
	FLTTextureChooser = Draw.PushButton("...",8,cx+400,cy,20,20,"Choose Folder")
	cy=cy-40
	#External application path
	FLTXAPPLabel = Draw.Label("XApp:",cx,cy,100,20)
	FLTXAPPString = Draw.String("",15,cx+100,cy,300,20,options.state['xappath'],255,"External application to launch when done")
	FLTXAPPChooser = Draw.PushButton("...",16,cx+400, cy,20,20,"Choose Folder")
	
	cy = cy-60
	#Shading Options
	FLTShadeExport = Draw.Toggle("Default Shading",9,cx,cy,100,20,options.state['export_shading'],"Turn on export of custom shading")
	FLTShadDefault = Draw.Number("",10,cx + 120,cy,100,20,options.state['shading_default'],0.0,180.0,"Default shading angle for objects with no custom shading assigned",setshadingangle)
	
	cy = cy-40
	FLTScale = Draw.Number("Export Scale",14,cx,cy,220,20,options.state['scale'],0.0,100.0,"Export scaling factor",setexportscale)
	
	cy = cy-40
	#misc Options
	FLTCopyTex = Draw.Toggle("Copy Textures",11,cx,cy,220,20,options.state['copytex'],"Copy textures to folder indicated above")
	cy = cy-40
	FLTGlobal = Draw.Toggle("Export Transforms",12,cx,cy,220,20,options.state['transform'],"If unchecked, Global coordinates are used (recommended)")
	cy = cy-40
	FLTDoXRef = Draw.Toggle("Export XRefs", 13,cx,cy,220,20,options.state['doxrefs'],"Export External references (only those below current scene!)")
	cy = cy-40
	FLTXAPP = Draw.Toggle("Launch External App", 14, cx,cy,220,20,options.state['xapp'],"Launch External Application on export")
	cy = cy-40
	FLTAttrib = Draw.Toggle("Write Attribute Files", 20, cx, cy, 220,20,options.state['attrib'], "Write Texture Attribute files")
	#FLTXAPPATH = Draw.String("",15,cx,cy,300,20,options.xappath,255,"External application path")
	

	#Draw export/close buttons
	FLTExport = Draw.PushButton("Export",1,cx,20,100,20,"Export to FLT")
	FLTClose = Draw.PushButton("Close", 2, cx+120,20,100,20,"Close window")
	

Draw.Register(gui,event,but_event)