# Path: Ecstatica/ActorPartAncestor.py
# class ActorPartAncestor(object):
#     '''
#     This class is the common ancestor of Actor and Part. It could be possible that Ecstatica didn't actually
#     use subclassing but had Part and Actor each have an instance of this class at offset 0x0h...no, that does not
#     seem plausible.
#     '''
# 
#     def __init__(self, index, parent, actor, flags):
#         '''
#         Constructor
#         '''
#         self.idx = index
#         self.flags = Flags.Flags(flags) #there are 2 bytes of flags at offset +0x02h        
#         
#         #self.matrix_gbl = (0, 0, 0, 0, 0, 0, 0, 0, 0)   #rotation matrix into global coordinate system
#         self.origin_lcl = (0, 0, 0)                     #translatin part into global coordinate system
#         self.offset_lcl = (0, 0, 0)
#         
#         self.sub = None #points to another ActorPartAncestor, which can be an Actor or a Part
#         self.actor = actor  #points to the actor this object belongs to. For the actor himself, this pointer is None
#                             #(originally, in Ecstatica, it points to the actor objects itself)
#         self.rotation = (0, 0, 0)                       #angles to describe the rotation of the object
#         self.parent = parent
#         
#         self.primechild = None
#         self.silblings = []
#         
#         self.typeinfo = None
#         
#     #Flags at Offset 0x02h    
#     flagnames = {"PartIsLoose": 4, 
#     "PartIs2PartLimb": 5,
#     "PartIsFixed": 6,
#     "PartFixedIKZAxis": 7} #Not certain yet what exactly this means
#     
#     def setFlags(self, flag_word):
#         '''
#         Activates all flags for which a 1 appears in the flag_word. Does NOT clear flags
#         
#         @param flag_word: Flags 0-15 to set
#         '''
#         for i in range(16):
#             flagvalue = flag_word & (1 << i)
#             if flagvalue == 1:
#                 self.flagnames[i] = True    
#                 
#     def clearFlags(self, flag_word):
#         '''
#         Clears all flags for which a 1 appears in the flag_word. Does NOT set flags
#         
#         @param flag_word: Flags 0-15 to clear
#         '''
#         for i in range(16):
#             flagvalue = flag_word & (1 << i)
#             if flagvalue == 1:
#                 self.flagnames[i] = False
#         
#     def addChild(self, childpart):             
#         assert childpart != None
#         assert childpart.parent is self
#         assert not childpart is self
#         
#         if self.primechild != None:
#             self.primechild.addSilbling(childpart)
#         else:
#             self.primechild = childpart
#             
#     def _getChildren(self):
#         if self.primechild == None:
#             return []
#         else:
#             return [self.primechild, ] + self.primechild.silblings
#         
#     children = property(_getChildren)
#             
#     def addSilbling(self, silblingpart):
#         assert silblingpart != None
#         assert silblingpart.parent is self.parent
#         assert not silblingpart is self
#         
#         self.silblings.append(silblingpart)
# 
# Path: Ecstatica/Flags.py
# class Flags(object):
#     '''
#     Describes a 4byte field containing 32 flags
#     '''
#     
#     def __init__(self, startval=None):
#         if startval == None:
#             startval = 0
#         self.value = startval
#         
#         self._names = {} #in this dict we collect names for the entries to allow more intuitive access
#         
#     def __getitem__(self, idx):
#         if type(idx) == str:
#             assert idx in self.names.keys()
#             idx = self._names[idx]
#         
#         assert idx >= 0 and idx < 32
#         return self.value & (1 << idx)
#     
#     def __setitem__(self, idx, val):
#         if type(idx) == str:
#             assert idx in self.names.keys()
#             idx = self._names[idx]
# 
#         assert idx >= 0 and idx < 32
#         if val:        
#             self.value |= (1 << idx)
#         else:
#             self.value &= ~(1 << idx)
#                 
#     def __str__(self):
#         str = ""
#         for i in range(32):
#             str += str(self.value & (1 << i))
#         return str
#     
#     def clear(self):
#         self.value = 0
#         
#     def clearSelected(self, vals):
#         self.value &= ~vals
#         
#     def setSelected(self, vals):
#         self.value |= vals
#         
#     def registerName(self, name, entry):
#         '''
#         allows to register a name for a given entry
#         '''
#         if name in self.names.keys():
#             raise KeyError("Name in use already: " + name + ":" + self._names[name])
#         if entry in self.names.values():
#             raise ValueError("Entry has name already: " + filter(lambda e: e[1] == entry, self._names.entries())[0] + ":" + entry)
#         
#         self._names[name] = entry   
#         
#     def _getNames(self):
#         return self._names
#     
#     def overwrite(self, newval):
#         self.value = newval
#     
#     names = property(_getNames)     


from .ActorPartAncestor import ActorPartAncestor
from .Flags import Flags
    Represents an ecstatica ellipse
    '''
    def __init__(self, idx, flags, origin_lcl, centre_lcl, offset_lcl, halfaxes, rotation, colour, parent, actor):
        '''
        '''
        ActorPartAncestor.__init__(self, idx, parent, actor, flags)
        
        self.idx = idx
        
        self._origin_lcl = origin_lcl
        self.centre_lcl = centre_lcl
        self.offset_lcl = offset_lcl        
        
        self._rotation = rotation            
        
        self._halfaxes = halfaxes
        self._colour = colour
        
        self.pSub = None
        self.next_silbling = None
        
        self.points = []
        
        self.flags.registerName("unknown_pos_flag_2", 1)        
        self.flags.registerName("joint_is_loose", 4)
        self.flags.registerName("is_2part_limb",  5)
        self.flags.registerName("part_is_fixed", 6)
        self.flags.registerName("unknown_rot_flag_200", 9)        
        self.flags.registerName("unknown_rot_flag_4000", 14)
        

# Path: Ecstatica/ActorPartAncestor.py
# class ActorPartAncestor(object):
#     '''
#     This class is the common ancestor of Actor and Part. It could be possible that Ecstatica didn't actually
#     use subclassing but had Part and Actor each have an instance of this class at offset 0x0h...no, that does not
#     seem plausible.
#     '''
# 
#     def __init__(self, index, parent, actor, flags):
#         '''
#         Constructor
#         '''
#         self.idx = index
#         self.flags = Flags.Flags(flags) #there are 2 bytes of flags at offset +0x02h        
#         
#         #self.matrix_gbl = (0, 0, 0, 0, 0, 0, 0, 0, 0)   #rotation matrix into global coordinate system
#         self.origin_lcl = (0, 0, 0)                     #translatin part into global coordinate system
#         self.offset_lcl = (0, 0, 0)
#         
#         self.sub = None #points to another ActorPartAncestor, which can be an Actor or a Part
#         self.actor = actor  #points to the actor this object belongs to. For the actor himself, this pointer is None
#                             #(originally, in Ecstatica, it points to the actor objects itself)
#         self.rotation = (0, 0, 0)                       #angles to describe the rotation of the object
#         self.parent = parent
#         
#         self.primechild = None
#         self.silblings = []
#         
#         self.typeinfo = None
#         
#     #Flags at Offset 0x02h    
#     flagnames = {"PartIsLoose": 4, 
#     "PartIs2PartLimb": 5,
#     "PartIsFixed": 6,
#     "PartFixedIKZAxis": 7} #Not certain yet what exactly this means
#     
#     def setFlags(self, flag_word):
#         '''
#         Activates all flags for which a 1 appears in the flag_word. Does NOT clear flags
#         
#         @param flag_word: Flags 0-15 to set
#         '''
#         for i in range(16):
#             flagvalue = flag_word & (1 << i)
#             if flagvalue == 1:
#                 self.flagnames[i] = True    
#                 
#     def clearFlags(self, flag_word):
#         '''
#         Clears all flags for which a 1 appears in the flag_word. Does NOT set flags
#         
#         @param flag_word: Flags 0-15 to clear
#         '''
#         for i in range(16):
#             flagvalue = flag_word & (1 << i)
#             if flagvalue == 1:
#                 self.flagnames[i] = False
#         
#     def addChild(self, childpart):             
#         assert childpart != None
#         assert childpart.parent is self
#         assert not childpart is self
#         
#         if self.primechild != None:
#             self.primechild.addSilbling(childpart)
#         else:
#             self.primechild = childpart
#             
#     def _getChildren(self):
#         if self.primechild == None:
#             return []
#         else:
#             return [self.primechild, ] + self.primechild.silblings
#         
#     children = property(_getChildren)
#             
#     def addSilbling(self, silblingpart):
#         assert silblingpart != None
#         assert silblingpart.parent is self.parent
#         assert not silblingpart is self
#         
#         self.silblings.append(silblingpart)
# 
# Path: Ecstatica/Flags.py
# class Flags(object):
#     '''
#     Describes a 4byte field containing 32 flags
#     '''
#     
#     def __init__(self, startval=None):
#         if startval == None:
#             startval = 0
#         self.value = startval
#         
#         self._names = {} #in this dict we collect names for the entries to allow more intuitive access
#         
#     def __getitem__(self, idx):
#         if type(idx) == str:
#             assert idx in self.names.keys()
#             idx = self._names[idx]
#         
#         assert idx >= 0 and idx < 32
#         return self.value & (1 << idx)
#     
#     def __setitem__(self, idx, val):
#         if type(idx) == str:
#             assert idx in self.names.keys()
#             idx = self._names[idx]
# 
#         assert idx >= 0 and idx < 32
#         if val:        
#             self.value |= (1 << idx)
#         else:
#             self.value &= ~(1 << idx)
#                 
#     def __str__(self):
#         str = ""
#         for i in range(32):
#             str += str(self.value & (1 << i))
#         return str
#     
#     def clear(self):
#         self.value = 0
#         
#     def clearSelected(self, vals):
#         self.value &= ~vals
#         
#     def setSelected(self, vals):
#         self.value |= vals
#         
#     def registerName(self, name, entry):
#         '''
#         allows to register a name for a given entry
#         '''
#         if name in self.names.keys():
#             raise KeyError("Name in use already: " + name + ":" + self._names[name])
#         if entry in self.names.values():
#             raise ValueError("Entry has name already: " + filter(lambda e: e[1] == entry, self._names.entries())[0] + ":" + entry)
#         
#         self._names[name] = entry   
#         
#     def _getNames(self):
#         return self._names
#     
#     def overwrite(self, newval):
#         self.value = newval
#     
#     names = property(_getNames)     


# Path: Ecstatica/Part.py
from .ActorPartAncestor import ActorPartAncestor
from .Flags import Flags

    Represents an ecstatica ellipse
    '''
    def __init__(self, idx, flags, origin_lcl, centre_lcl, offset_lcl, halfaxes, rotation, colour, parent, actor):
        '''
        '''
        ActorPartAncestor.__init__(self, idx, parent, actor, flags)
        
        self.idx = idx
        
        self._origin_lcl = origin_lcl
        self.centre_lcl = centre_lcl
        self.offset_lcl = offset_lcl        
        
        self._rotation = rotation            
        
        self._halfaxes = halfaxes
        self._colour = colour
        
        self.pSub = None
        self.next_silbling = None
        
        self.points = []
        
        self.flags.registerName("unknown_pos_flag_2", 1)        
        self.flags.registerName("joint_is_loose", 4)
        self.flags.registerName("is_2part_limb",  5)
        self.flags.registerName("part_is_fixed", 6)
        self.flags.registerName("unknown_rot_flag_200", 9)        
        self.flags.registerName("unknown_rot_flag_4000", 14)
        

        self.updateflags = Flags()