class AbstractData(object):
	def __init__(self):
		self.uid          = None
		self.name         = None
		self.index        = -1
		self.references   = []
		self.properties   = {}
		self.size         = 0
		self.visible      = False
		self.construction = False
		self.segment      = None
		self.geometry     = None
		self.sketchIndex  = None
		self.sketchPos    = None
		self.valid        = True
		self.handled      = False
		self.node         = None

	def __content__(self, name, value, cls):
		if cls is None: return ''
		result = ''
		if (cls == VAL_REF): return result  # will be handled later!
		if (name): result = '%s=' %(name)

		if (type(value) == float):             return '%s%g'     %(result, value)
		if (type(value) == bool):              return '%s%s'     %(result, value)
		if (isinstance(value, Color)):         return '%s%s'     %(result, value)
		if (isinstance(value, UID)):           return '%s{%s}'   %(result, value)
		if (isinstance(value, AbstractValue)): return '%s%s'     %(result, value.toStandard())
		if (type(value) == tuple):             return '%s(%s)'   %(result, ",".join([self.__content__(None, v, cls) for v in value]))
		if (type(value) == list):              return '%s[%s]'   %(result, ",".join([self.__content__(None, v, cls) for v in value]))
		if (type(value) == dict):              return '%s{%s}'   %(result, ",".join(["%s:%s" %(self.__content__(None, n, cls), self.__content__(None, v, cls)) for n, v in value.items()]))
		if (cls == VAL_ENUM):
			values = self.get('Values')
			try:
				return '%s%s'     %(result, values[value])
			except:
				return '%s%s'     %(result, value)
		if (type(value) == str):
			if (cls == VAL_STR8):   return '%s\'%s\'' %(result, value)
			return '%s"%s"' %(result, value)
		if (type(value) == int):
			if (cls == VAL_ENUM):   return '%s%d'     %(result, value)
			if (cls == VAL_UINT8):  return '%s%02X'   %(result, value)
			if (cls == VAL_UINT16): return '%s%03X'   %(result, value)
			if (cls == VAL_UINT32): return '%s%04X'   %(result, value)
			return '%s%d'     %(result, value)
		return '%s%s' %(result, value)

	@property
	def content(self):
		result = " ".join([self.__content__(n, p[0], p[1]) for n, p in self.properties.items()])
		if (len(self.data) > 0):
			result += " aX=(%s)" %(" ".join(["%02X"%(c) for c in self.data]))
		return result

	def set(self, name, value, cls = VAL_GUESS):
		'''
		Sets the value for the property name.
		name:  The name of the property.
		value: The value of the property.
		'''
		if (name):
			self.properties[name] = (value, cls)

	def get(self, name):
		'''
		Returns the value of the property given by the name.
		name: The name of the property.
		Returns None if the property is not yet set.
		'''
		return self.properties.get(name, (None, None))[0]

	def delete(self, name):
		'''
		Removes the value from the property given by the name.
		name: The name of the property.
		'''
		if (name in self.properties):
			del self.properties[name]

	def getName(self):
		if (hasattr(self, 'nameSet')): return self.name
		if (self.name is None):
			label = self.get('next')
			if (not label is None):
				self.nameSet = True
				self.name = label.name
		return self.name

	def __str__(self): # return unicode
		if (self.name is None):
			return u"(%04X): %s%s" %(self.index, self.uid, self.content.encode(sys.getdefaultencoding()))
		return u"(%04X): %s '%s'%s" %(self.index, self.uid, self.name, self.content.encode(sys.getdefaultencoding()))

	def __repr__(self):
		if (self.node is None):
			if (self.name is None):
				return u"(%04X): %s" %(self.index, self.uid)
			return u"(%04X): %s '%s'" %(self.index, self.uid, self.name)
		return self.node.getRefText()
 class AbstractValue(object):
	def __init__(self, x, factor, offset, unit):
		self.x      = x
		self.factor = factor
		self.offset = offset
		self.unit   = unit
	def __str__(self):  return u"%g%s" %(self.x / self.factor - self.offset, self.unit)
	def __repr__(self): return self.toStandard()
	def toStandard(self):  return self.__str__()
	def getNominalValue(self):
		return self.x / self.factor + self.offset
	def __sub__(self):
		return self.__class__(-self.x, self.factor, self.unit)
	def __neg__(self):
		return self.__class__(-self.x, self.factor, self.unit)
	def __sub__(self, other):
		if (isinstance(other, AbstractValue)):
			return self.__class__(self.x - other.x, self.factor, self.unit)
		return self.__class__(self.x - other, self.factor, self.unit)
	def __add__(self, other):
		if (isinstance(other, AbstractValue)):
			return self.__class__(self.x + other.x, self.factor, self.unit)
		return self.__class__(self.x + other, self.factor, self.unit)
	def __mul__(self, other):
		if (isinstance(other, AbstractValue)):
			return self.__class__(self.x * other.x, self.factor, self.unit)
		return self.__class__(self.x * other, self.factor, self.unit)
 class Header0(object):
	def __init__(self, m, x):
		self.m = m
		self.x = x
	def __str__(self):  return 'm=%X x=%03X' %(self.m, self.x)
	def __repr__(self): return '(%04X,%03X)' %(self.m, self.x)
 class Angle(AbstractValue):
	def __init__(self, a, factor, unit):
		super(Angle, self).__init__(a, factor, 0.0, unit)
	def getRAD(self):     return self.x
	def getGRAD(self):    return degrees(self.x)
	def toStandard(self): return '%g\xC2\xB0' %(self.getGRAD())
 class GraphicsFont(object):
	def __init__(self):
		self.number      = -1      # UInt32
		self.ukn1        = 0       # UInt16[4]
		self.ukn2        = []      # UInt8[2]
		self.ukn3        = []      # UInt16[2]
		self.name        = []      # getLen32Text16
		self.ukn4        = []      # Float32[2]
		self.ukn5        = []      # UInt8[3]

	def __str__(self):
		return u"(%d) %s %r %r %r %r %r" %(self.number, self.name, self.ukn1, self.ukn2, self.ukn3, self.ukn4, self.ukn5)
 class Lightning(object):
	def __init__(self):
		self.n1 = 0
		self.c1 = None
		self.c2 = None
		self.c3 = None
		self.a1 = []
		self.a2 = []
	def __str__(self):
		return '%d: %s, %s, %s, [%s], [%s]' %(self.n1, self.c1, self.c2, self.c3, FloatArr2Str(self.a1), FloatArr2Str(self.a2))
 class ModelerTxnMgr(object):
	def __init__(self):
		self.node  = 0  # DC.node
		self.dcIdx = 0  # DC-index ref
		self.lst = []   # 1st= ref BRep.node.ref_1,byte,key; 2nd = ref to Result.node,byte,key => mapping

	def __str__(self):
		s = ",".join(["(%04X,%02X,%04X)" %a for a in self.lst])
		return '%04X %04X [%s]' %(self.node, self.dcIdx, s)
	def __repr__(self): return self.__str__()
 class NtEntry(object):
	def __init__(self, nameTable, key):
		self.nameTable = nameTable & 0x7FFFFFFF
		self.key       = key
		self.entry     = None
	def __str__(self):
		if (self.nameTable):
			return u"%04X[%04X]" %(self.nameTable, self.key)
		return u""
	def __repr__(self):
		return self.__str__()
 class ParameterNode(DataNode):
	def __init__(self, data):
		super(ParameterNode, self).__init__(data)

	def getValueRaw(self):
		return self.get('valueNominal')

	def getRefText(self): # return unicode
		x = self.getValue()
		try:
			if (isinstance(x, Angle)):  return u"(%04X): %s '%s'=%s" %(self.index, self.typeName, self.name, x)
			if (isinstance(x, Length)): return u"(%04X): %s '%s'=%s" %(self.index, self.typeName, self.name, x)
			return u"(%04X): %s '%s'=%s" %(self.index, self.typeName, self.name, x)
		except Exception as e:
			return u"(%04X): %s '%s'=%s - %s" %(self.index, self.typeName, self.name, x, e)

	def getParameterFormula(self, parameterData, asText):
		subFormula = ''
		typeName   = parameterData.typeName

		if (typeName == 'ParameterValue'):
			type   = parameterData.get('type')
			unitName = ''
			if (asText):
				unitName = parameterData.getUnitName()
				if (len(unitName) > 0): unitName = ' ' + unitName
			if (type == 0xFFFF):
				subFormula = '%g%s' %(parameterData.get('value'), unitName)
			else:
				value  = parameterData.get('value')
				offset = parameterData.getUnitOffset()
				factor = parameterData.getUnitFactor()
				if (type == 0x0000): # Integer value!
					subFormula = '%d%s' %(round((value / factor) - offset, 0), unitName)
				else: # floating point value!
					subFormula = '%g%s' %((value / factor) - offset, unitName)
		elif (typeName == 'ParameterConstant'):
			unitName = ''
			if (asText):
				unitName = parameterData.getUnitName()
				if (len(unitName) > 0): unitName = ' ' + unitName
			subFormula = '%s%s' %(parameterData.name, unitName)
		elif (typeName == 'ParameterRef'):
			target = parameterData.get('operand1')
			if (asText):
				subFormula = target.name
			else:
				subFormula = '%s_' %(target.name)
		elif (typeName == 'ParameterFunction'):
			function          = parameterData.name
			operandRefs = parameterData.get('operands')
			subFormula = "%s(%s)" %(function, ';'.join(["%s" %(self.getParameterFormula(ref, asText)) for ref in operandRefs]))
			if ((function in FunctionsNotSupported) and (not asText)):
				nominalValue = self.getValue().getNominalValue()
				logWarning(u"Function '%s' not supported in formula of '%s' (%s) - using nominal value %g!", function, self.name, subFormula, nominalValue)
				subFormula = '%g' %(nominalValue)
		elif (typeName == 'ParameterOperatorUnaryMinus'):
			subFormula = '-' + self.getParameterFormula(parameterData.get('operand1'), asText)
		elif (typeName == 'ParameterOperatorPowerIdent'):
			subFormula = self.getParameterFormula(parameterData.get('operand1'), asText)
		elif (typeName.startswith('ParameterOperator')):
			operation = parameterData.name
			operand1 = self.getParameterFormula(parameterData.get('operand1'), asText)
			operand2 = self.getParameterFormula(parameterData.get('operand2'), asText)
			subFormula = '(%s %s %s)' %(operand1, operation, operand2)
			if ((not asText) and (operation == '%')):
				subFormula = 'mod(%s, %s)' %(operand1, operand2)
		else:
			logError(u"    Don't now how to build formula for %s: %s!", typeName, parameterData)

		return subFormula

	def getFormula(self, asText):
		data = self.data
		if (data):
			refValue = data.get('value')
			if (refValue):
				if (asText):
					return u"'" + self.getParameterFormula(refValue, asText)
				try:
					return u"=" + self.getParameterFormula(refValue, asText)
				except BaseException as be:
					# replace by nominal value and unit!
					value = self.getValue()
					logWarning(u"    %s - replacing by nominal value %s!" %(be, value))
			else:
				value = self.getValue()
			if (asText):
				return u"'%s" %(value)
			return u"=%s" %(value.getNominalValue())

		return u''

	def getValue(self):
		x = self.getValueRaw()
		#unitRef = self.get('unit')
		#type = unitRef.get('type')

		type = self.getUnitName()
		# Length
		if (type == 'km')    : return Length(x,  100000.00000, type)
		if (type == 'm')     : return Length(x,     100.00000, type)
		if (type == 'dm')    : return Length(x,      10.00000, type)
		if (type == 'cm')    : return Length(x,       1.00000, type)
		if (type == 'mm')    : return Length(x,       0.10000, type)
		if (type == u'\xB5m'): return Length(x,       0.00100, type)
		if (type == 'in')    : return Length(x,       2.54000, type)
		if (type == 'ft')    : return Length(x,      30.48000, type)
		if (type == 'sm')    : return Length(x,  185324.52180, type)
		if (type == 'mil')   : return Length(x,       0.00254, type)
		# Mass
		if (type == 'kg')    : return Mass(x,       1.0000000, type)
		if (type == 'g')     : return Mass(x,       0.0010000, type)
		if (type == 'slug')  : return Mass(x,      14.5939000, type)
		if (type == 'lb')    : return Mass(x,       0.4535920, type)
		if (type == 'oz')    : return Mass(x,       0.0283495, type)
		# Time
		if (type == 's')     : return Time(x,       1.0000000, type)
		if (type == 'min')   : return Time(x,      60.0000000, type)
		if (type == 'h')     : return Time(x,    3600.0000000, type)
		# Temperature
		if (type == 'K')     : return Temperature(x,     1.0,   0.00, type)
		if (type == u'\xB0C'): return Temperature(x,     1.0, 273.15, type)
		if (type == u'\xB0F'): return Temperature(x, 5.0/9.0, 523.67, type)
		# Angularity
		if (type == 'rad')   : return Angle(x, 1.0     , type)
		if (type == u'\xb0') : return Angle(x, pi/180.0, type)
		if (type == 'gon')   : return Angle(x, pi/200.0, type)
		# Velocity
		if (type == 'm/s')   : return Velocity(x, 100.0     , type)
		# Area
		if (type == 'mm^2')  : return Area(x, 1.0           , type)
		# Volume
		if (type == 'l')     : return Volume(x, 1.0         , type)
		# Force
		if (type == 'N')     : return Force(x, 1.0          , type)
		if (type == 'dyn')   : return Force(x, 1.0          , type)
		if (type == 'ozf')   : return Force(x, 0.278013851  , type)
		# Pressure
		if (type == 'psi')   : return Pressure(x,    6890.0 , type)
		if (type == 'ksi')   : return Pressure(x, 6890000.0 , type)
		# Work
		if (type == 'J')     : return Work(x,         1.0   , type)
		if (type == 'erg')   : return Work(x,         1.0   , type)
		if (type == 'Cal')   : return Work(x,         4.184 , type)
		# Electrical
		if (type == 'A')     : return Electrical(x,   1.0   , type)
		# Luminosity
		if (type == 'cd')    : return Luminosity(x, type)
		# Substance
		if (type == 'mol')   : return Substance(x, type)
		# without Unit
		if (type == '')      : return Scalar(x) # parameter has no unit
		derivedUnit = self.getDerivedUnitName()
		if (derivedUnit is not None):
			# Length
			# Mass
			# Temperature
			# Angularity
			if (derivedUnit == 'sr')       : return Angle(x   ,   1.0, type)
			# Velocity
			if (derivedUnit == 'f/s')      : return Velocity(x,   1.0, type)
			if (derivedUnit == 'mil/h')    : return Velocity(x,   1.0, type)
			if (derivedUnit == '1/min')    : return Velocity(x,   1.0, type)
			# Area
			if (derivedUnit == 'circ.mil') : return Area(x,       1.0, type)
			# Volume
			if (derivedUnit == 'gal')      : return Volume(x,     1.0, type)
			# Force
			if (derivedUnit == 'lbf')      : return Force(x,      1.0, type)
			# Pressure
			if (derivedUnit == 'Pa')       : return Pressure(x,   1.0, type)
			# Power
			if (derivedUnit == 'W')        : return Power(x,      1.0, type)
			if (derivedUnit == 'hp')       : return Power(x,      1.0, type)
			# Work
			if (derivedUnit == 'BTU')      : return Work(x,       1.0, type)
			# Electrical
			if (derivedUnit == 'V')        : return Electrical(x, 1.0, type)
			if (derivedUnit == 'ohm')      : return Electrical(x, 1.0, type)
			if (derivedUnit == 'C')        : return Electrical(x, 1.0, type)
			if (derivedUnit == 'F')        : return Electrical(x, 1.0, type)
			if (derivedUnit == 'y')        : return Electrical(x, 1.0, type)
			if (derivedUnit == 'Gs')       : return Electrical(x, 1.0, type)
			if (derivedUnit == 'H')        : return Electrical(x, 1.0, type)
			if (derivedUnit == 'Hz')       : return Electrical(x, 1.0, type)
			if (derivedUnit == 'maxwell')  : return Electrical(x, 1.0, type)
			if (derivedUnit == 'mho')      : return Electrical(x, 1.0, type)
			if (derivedUnit == 'Oe')       : return Electrical(x, 1.0, type)
			if (derivedUnit == 'S')        : return Electrical(x, 1.0, type)
			if (derivedUnit == 'T')        : return Electrical(x, 1.0, type)
			if (derivedUnit == 'Wb')       : return Electrical(x, 1.0, type)
			# Luminosity
			if (derivedUnit == 'lx')       : return Luminosity(x, type)
			if (derivedUnit == 'lm')       : return Luminosity(x, type)
			logWarning(u"    found unsuppored derived unit - [%s] using [%s] instead!", derivedUnit, type)
		else:
			logWarning(u"WARNING: unknown unit (%04X): '%s' - [%s]", self.index, self.typeName, type)
		return Derived(x, type)
 REF_CHILD    = 2
 REF_CROSS    = 1
 REF_PARENT   = 3
 VAL_UINT8    = 1
 VAL_UINT16   = 2
 VAL_UINT32   = 3
 VAL_REF      = 5
 VAL_STR8     = 6
 VAL_STR16    = 7
 VAL_ENUM     = 9
 class Transformation3D(object):
	def __init__(self):
		self.a0 = 0x00000000
		self.m = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]

	def read(self, data, offset):
		n, k = getUInt32(data, offset)
		if (n == 0x00000203):
			i = k
		else:
			i = offset
		'''           +---- Value for the 4. row to be used for the transformation matrix
		              |+--- Value for the 3. row to be used for the transformation matrix
		              ||+-- Value for the 2. row to be used for the transformation matrix
		              |||+- Value for the 1. row to be used for the transformation matrix
		              ||||
		              vvvv '''
		d1, i = getUInt16(data, i)
		'''           +-------- Mask for the 4. row of the transformation matrix
		              |+------- Mask for the 3. row of the transformation matrix
		              ||+------ Mask for the 2. row of the transformation matrix
		              |||+----- Mask for the 1. row of the transformation matrix
		              ||||
		              vvvv'''
		d2, i = getUInt16(data, i)
		self.a0 = d1 | (d2 << 16)
		self.m = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
		for row in range(4):
			for col in range(4):
				j = col + 4 * row
				b = (1 << j)
				if (d2 & b == 0):
					if (d1 & b == 0):
						value, i = getFloat64(data, i)
						if (math.fabs(value) < 1.0e-6): value = 0.0
					else:
						value = 1
				else:
					value = 0 if (d1 & b == 0) else -1
				self.m[row][col] = value
		return i

	def getX(self): return self.m[0][3] * 10.0

	def getY(self): return self.m[1][3] * 10.0

	def getZ(self): return self.m[2][3] * 10.0

	def __m2s__(self, index):
		v = self.m[index]
		return u"[%g, %g, %g, %g]" %(v[0], v[1], v[2], v[3] * 10.0)

	def __str__(self): # return unicode
		m = self.__repr__()
		j = 0
		mask = '|'
		d1 = (self.a0 & 0xFFFF0000) >> 16
		d2 = (self.a0 & 0x0000FFFF)
		while (j < 16):
			b = (1 << j)
			if (d1 & b):
				if (d2 & b):
					mask += '-'
				else:
					mask += '0'
			else:
				if (d2 & b):
					mask += '+'
				else:
					mask += 'x'
			j += 1
			if ((j % 4) == 0):
				mask += '|'
		return u' transformation={a0=%s m=%s}' %(mask, m)

	def __repr__(self):
		m0 = self.__m2s__(0)
		m1 = self.__m2s__(1)
		m2 = self.__m2s__(2)
		m3 = self.__m2s__(3)
		return u"[%s,%s,%s,%s]" %(m0, m1, m2, m3)

	def getBase(self):
		x = self.m[0, 3]
		y = self.m[1, 3]
		z = self.m[2, 3]
		return VEC(x, y, z)

	def getRotation(self):
		"""Return quaternion from the transformation matrix.
		"""
		# the trace is the sum of the diagonal elements; see http://mathworld.wolfram.com/MatrixTrace.html
		xx = self.m[0][0]
		xy = self.m[0][1]
		xz = self.m[0][2]
		yx = self.m[1][0]
		yy = self.m[1][1]
		yz = self.m[1][2]
		zx = self.m[2][0]
		zy = self.m[2][1]
		zz = self.m[2][2]
		t = xx + yy + zz

		# we protect the division by s by ensuring that s>=1
		if (t >= 0): # |w| >= .5
			s = math.sqrt(t + 1) # |s|>=1 ...
			w = 0.5 * s
			s = 0.5 / s # so this division isn't bad
			x = (zy - yz) * s
			y = (xz - zx) * s
			z = (yx - xy) * s
		elif ((xx > yy) and (xx > zz)):
			s = math.sqrt(1.0 + xx - yy - zz) # |s|>=1
			x = s * 0.5 #|x| >= 0.5
			s = 0.5 / s
			y = (yx + xy) * s
			z = (xz + zx) * s
			w = (zy - yz) * s
		elif (yy > zz):
			s = math.sqrt(1.0 - xx + yy - zz) # |s|>=1
			y = s * 0.5 # |y| >= 0.5
			s = 0.5 / s
			x = (yx + xy) * s
			z = (zy + yz) * s
			w = (xz - zx) * s
		else:
			s = math.sqrt(1.0 + zz - xx - yy) # |s|>=1
			z = s * 0.5 # |z| >= 0.5
			s = 0.5 / s
			x = (xz + zx) * s
			y = (zy + yz) * s
			w = (yx - xy) * s
		return ROT(x, y, z, w)

	def getMatrix(self):
		m = self.m
		return MAT(
			m[0][0], m[0][1], m[0][2], m[0][3],
			m[1][0], m[1][1], m[1][2], m[1][3],
			m[2][0], m[2][1], m[2][2], m[2][3],
			m[3][0], m[3][1], m[3][2], m[3][3]
			)

from importerClasses        import AbstractData, AbstractValue, Header0, Angle, GraphicsFont, Lightning, ModelerTxnMgr, NtEntry, ParameterNode
from importerConstants      import REF_CHILD, REF_CROSS, REF_PARENT, VAL_UINT8, VAL_UINT16, VAL_UINT32, VAL_REF, VAL_STR8, VAL_STR16, VAL_ENUM
from importerUtils          import *
from math                   import log10, pi
from importerTransformation import Transformation3D

			return offset+cnt

	def getList2Childs(self, name, offset, cnt, arraysize):
		lst = []
		i   = offset
		for j in range(cnt):
			i = self.ReadChildRef(i, name, j)
			lst.append(self.get(name))
		self.set(name, lst, VAL_REF)
		return i

	def getListXRefs(self, name, offset, cnt, arraysize):
		lst = []
		i   = offset
		for j in range(cnt):
			i = self.ReadCrossRef(i, name, j)
			lst.append(self.get(name))
		self.set(name, lst, VAL_REF)
		return i

	def getListString8s(self, name, offset, cnt, arraysize):
		return  self.__getListStrings(name, offset, cnt, getLen32Text8, VAL_STR8)

	def getListString16s(self, name, offset, cnt, arraysize):
		return  self.__getListStrings(name, offset, cnt, getLen32Text16, VAL_STR16)

	def getListUInt8s(self, name, offset, cnt, arraysize):
		return self.__getList2Nums(name, offset, cnt, 'B', 1, u"%02X")

	def getListSInt16s(self, name, offset, cnt, arraysize):
		return self.__getList2Nums(name, offset, cnt, 'b', 1, u"%d")

	def getListUInt16s(self, name, offset, cnt, arraysize):
		return self.__getList2Nums(name, offset, cnt, 'H', 2, u"%03X")

	def getListSInt16s(self, name, offset, cnt, arraysize):
		return self.__getList2Nums(name, offset, cnt, 'h', 2, u"%d")

	def getListUInt32s(self, name, offset, cnt, arraysize):
		return self.__getList2Nums(name, offset, cnt, 'L', 4, u"%04X")

	def getListSInt32s(self, name, offset, cnt, arraysize):
		return self.__getList2Nums(name, offset, cnt, 'l', 4, u"%d")

	def getListFloat32s(self, name, offset, cnt, arraysize):
		return self.__getList2Nums(name, offset, cnt, 'f', 4, u"%g")

	def getListFloat64s(self, name, offset, cnt, arraysize):
		return self.__getList2Nums(name, offset, cnt, 'd', 8, u"%g")

	def getListUInt8sA(self, name, offset, cnt, arraysize):
		return self.__getList2NumsA(name, offset, cnt, arraysize, 'B', 1, u"%02X")

	def getListSInt8sA(self, name, offset, cnt, arraysize):
		return self.__getList2NumsA(name, offset, cnt, arraysize, 'b', 1, u"%d")

	def getListUInt16sA(self, name, offset, cnt, arraysize):
		return self.__getList2NumsA(name, offset, cnt, arraysize, 'H', 2, u"%03X")

	def getListSInt16sA(self, name, offset, cnt, arraysize):
		return self.__getList2NumsA(name, offset, cnt, arraysize, 'h', 2, u"%d", (getFileVersion() > 2010))

	def getListUInt32sA(self, name, offset, cnt, arraysize):
		return self.__getList2NumsA(name, offset, cnt, arraysize, 'L', 4, u"%04X")

	def getListSInt32sA(self, name, offset, cnt, arraysize):
		return self.__getList2NumsA(name, offset, cnt, arraysize, 'l', 4, u"%d")

	def getListFloat32sA(self, name, offset, cnt, arraysize):
		return self.__getList2NumsA(name, offset, cnt, arraysize, 'f', 4, u"%g", (getFileVersion() > 2010))

	def getListFloat64sA(self, name, offset, cnt, arraysize):
		return self.__getList2NumsA(name, offset, cnt, arraysize, 'd', 8, u"%g")

	def getListFonts(self, name, offset, cnt, arraysize):
		lst    = []
		i      = offset
		skip   = 2 * getBlockSize()
		if (self.segment.segment.version.major >= 25): skip += 1 # skip 00
		FONT_A = Struct('<LHHHHBBHH').unpack_from
		FONT_B = Struct('<ffBBB').unpack_from
		for j in range(cnt):
			val = GraphicsFont()
			a   = FONT_A(self.data, i)
			val.number = a[0]
			val.ukn1   = a[1:5]
			val.ukn2   = a[5:7]
			val.ukn3   = a[7:]
			i += 18
			val.name, i   = getLen32Text16(self.data, i)
			a = FONT_B(self.data, i)
			val.ukn4 = a[0:2]
			val.ukn5 = a[2:]
			i += 11
			lst.append(val)
			i += skip
		self.set(name, lst)
		return i

	def getListLightnings(self, name, offset, cnt, arraysize):
		lst = []
		i   = offset
		if (getFileVersion() > 2010):
			LIGHTNING = Struct('<Hffffffffffffddddddfffffff').unpack_from
			for j in range(cnt):
				vals = LIGHTNING(self.data, i)
				i += 126
				val = Lightning()
				val.n1 = vals[0]
				val.c1 = Color(vals[1], vals[2], vals[3], vals[4])
				val.c2 = Color(vals[5], vals[6], vals[7], vals[8])
				val.c3 = Color(vals[9], vals[10], vals[11], vals[12])
				val.a1 = vals[13:19]
				val.a2 = vals[19:]
				lst.append(val)
		else:
			LIGHTNING = Struct('<HffffLffffLffffLddddddfffffffL').unpack_from
			for j in range(cnt):
				vals = LIGHTNING(self.data, i)
				i += 142

				val = Lightning()
