def loadModule(self, moduleName):
        for m in self.moduleList:
            if m.name == moduleName:
                if m.hasDependencies: # load modules on wich the main module depends before the main module is loaded
                    for moduleDependencie in m.moduleDependencies:
                        for m2 in self.moduleList:
                            if m2.name == moduleDependencie:
                                m2.load()
                                self.modelSelectionDialog.scanDirForModels(m2.moduleRoot)
                                self.mainModuledependencieList.append(m2)

                m.load()
                self.modelSelectionDialog.scanDirForModels(m.moduleRoot)
                self.mainModule = m
                self.moduleExplorer.setCurrentModule(m)
                
#        self.moduleExplorer.updateView()
#        n = self.sceneManager.getRootSceneNode().createChildSceneNode()
#        e = self.sceneManager.createEntity("west342wt346t",  "UniCube.mesh")
#        e.setMaterialName("PlainColor")
#        e.getSubEntity(0).setCustomParameter(1, og.Vector4(0.0, 0.0, 1.0, 1.0))
#
#        e2 = self.sceneManager.createEntity("west342wt34635t",  "UniSphere.mesh")
#        e2.setMaterialName("PlainColor")
#        e2.getSubEntity(0).setCustomParameter(1, og.Vector4(0, 1, 0, 1))
#        n.attachObject(e)
#        n.attachObject(e2)
#        n.setScale(og.Vector3(10, 5, 20))
#        
        if self.selectionBuffer is None:
            self.selectionBuffer = SelectionBuffer(self.sceneManager, self.ogreRoot.getRenderTarget("OgreMainWin"))
class ModuleManager():
    def __init__(self,  ogreRoot,  sceneManager):
        self.sceneManager = sceneManager
        self.ogreRoot = ogreRoot
        self.modelSelectionDialog = None

        self.moduleCfgPath = ""

        self.gocManager = GameObjectClassManager()
        # we need to hold a reference to the game object representaions ourself
        # python does not recognize the a reference to a c++ object (Entity in our case) is passed
        # and deletes the object
        self.gameObjectRepresentationDict = []

        self.mainModule = []
        self.mainModuledependencieList =[]
        self.moduleList = []
        self.userSelectionList = []
        self.cutList = [] # selection objects that has been cut out and wait to be pasted again
        self.cutListPreviousNodes = [] # contains the nodes they where copnnected to before the cut

        self.moduleExplorer = None

        self.lastRay = None
        self.rayLine = None

        # pivot is initialzed and set in the Lockenwickler.setUpOgre function
        self.pivot = None
        self.movingPivot = False

        self.leftMouseDown = False
        self.middleMouseDown = False
        self.rightMouseDown = False

        self.dropCount = 0
        self.dropNode = None
        self.dropEntity = None
        self.dropCollisionPlane = og.Plane(og.Vector3().UNIT_Y, og.Vector3().ZERO)

        self.numerOfCopys = 0 #everytime a copy is made this numer is increased to generate unique node and mesh names
        self.moduleConfigIsParsed = False

        self.selectionBuffer = None
    
    def resetParsedModuleConfig(self):
        self.moduleConfigIsParsed = False
        self.moduleList = []

    def parseModuleConfig(self):
        if self.moduleConfigIsParsed:
            return

        import codecs
        f = codecs.open(self.moduleCfgPath, 'r', 'utf-8')

        for line in f:
            if line.startswith('#'):
                continue

            if line.startswith('module='):
                splines = line.split('=')
                str = splines[1].rstrip().rstrip()
                self.moduleList.append(Module(str, self.moduleCfgPath.replace("/modules.cfg",  ""), self.sceneManager, self.ogreRoot, self.gocManager))

        self.moduleConfigIsParsed = True


    def moduleExists(self, name):
        lowerA = str(name).lower()
        
        for m in self.moduleList:
            lowerB = m.name.lower()
            if lowerA == lowerB:
                return True
        
        return False

    def openLoadModuleDialog(self):
        self.moduleFolder = str(self.moduleCfgPath.replace("modules.cfg", ""))

        self.parseModuleConfig()

        dlg = QDialog()
        list = QListWidget()
        btnBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        dlg.connect(btnBox, SIGNAL("accepted()"), dlg.accept)
        dlg.connect(btnBox, SIGNAL("rejected()"), dlg.reject)

        for m in self.moduleList:
            if not m.isCommon():
                list.addItem(m.name)

        layout = QVBoxLayout()
        layout.addWidget(list)
        layout.addWidget(btnBox)
        dlg.setLayout(layout)
        if dlg.exec_():
            self.loadModule(str(list.currentItem().text()))

    # I'm sorry for this
    def loadModule(self, moduleName):
        for m in self.moduleList:
            if m.name == moduleName:
                if m.hasDependencies: # load modules on wich the main module depends before the main module is loaded
                    for moduleDependencie in m.moduleDependencies:
                        for m2 in self.moduleList:
                            if m2.name == moduleDependencie:
                                m2.load()
                                self.modelSelectionDialog.scanDirForModels(m2.moduleRoot)
                                self.mainModuledependencieList.append(m2)

                m.load()
                self.modelSelectionDialog.scanDirForModels(m.moduleRoot)
                self.mainModule = m
                self.moduleExplorer.setCurrentModule(m)
                
#        self.moduleExplorer.updateView()
#        n = self.sceneManager.getRootSceneNode().createChildSceneNode()
#        e = self.sceneManager.createEntity("west342wt346t",  "UniCube.mesh")
#        e.setMaterialName("PlainColor")
#        e.getSubEntity(0).setCustomParameter(1, og.Vector4(0.0, 0.0, 1.0, 1.0))
#
#        e2 = self.sceneManager.createEntity("west342wt34635t",  "UniSphere.mesh")
#        e2.setMaterialName("PlainColor")
#        e2.getSubEntity(0).setCustomParameter(1, og.Vector4(0, 1, 0, 1))
#        n.attachObject(e)
#        n.attachObject(e2)
#        n.setScale(og.Vector3(10, 5, 20))
#        
        if self.selectionBuffer is None:
            self.selectionBuffer = SelectionBuffer(self.sceneManager, self.ogreRoot.getRenderTarget("OgreMainWin"))

    # called when a click into Main Ogre Window occurs
    def selectionClick(self, screenX, screenY, ray,  controlDown=False,  shiftDown=False):
        so = None
        
        if self.selectionBuffer is not None:
            so = self.selectionBuffer.onSelectionClick(screenX, screenY)
        
        
        
        if so is not None:
            if not so.isPivot:
                if not controlDown and not shiftDown:
                    self.resetSelection()
                    so.setSelected(True)
                    self.userSelectionList.append(so)
                    self.updatePivots()
                elif controlDown and not shiftDown:
                    so.setSelected(True)

                    for soFromList in self.userSelectionList:
                        if soFromList == so:
                            return # object already selected

                    self.userSelectionList.append(so)
                    self.updatePivots()


                elif not controlDown and shiftDown:
                    for selo in self.userSelectionList:
                        if so == selo:
                            so.setSelected(False)
                            self.userSelectionList.remove(selo)
                    self.updatePivots()
            else:
                #so.entity is the pivot direction that was clicked
                self.pivot.startTransforming(so.entity,  self.userSelectionList)
        else:
            self.resetSelection() # click in empty space, deselect everything
            if self.pivot is not None:
                self.pivot.hide()

        if self.rayLine == None:
            self.rayLine = self.sceneManager.createManualObject("rayLine")
            self.rayLine.setDynamic(True)
            self.sceneManager.getRootSceneNode().createChildSceneNode("raynode").attachObject(self.rayLine)

            self.rayLine.begin("BaseWhiteNoLighting", og.RenderOperation.OT_LINE_STRIP)

            self.rayLine.position(ray.getOrigin())
            self.rayLine.position( ray.getPoint(10000))

            self.rayLine.end()

        else:
            self.rayLine.beginUpdate(0)

            self.rayLine.position(ray.getOrigin())
            self.rayLine.position( ray.getPoint(10000))

            self.rayLine.end()

    def deleteObjects(self):
        if len(self.userSelectionList) < 1:
            return

        self.pivot.hide()

        for so in self.userSelectionList:
            self.sceneManager.destroySceneNode(so.entity.getParentNode().getName())
            del so

        self.userSelectionList = []

    def incrementNameSuffixNumber(self, name):
        newName = ""
        split = name.split("_")
        lastPart = len(split)-1
        newName = name.rstrip(split[lastPart])
        newName = newName + str(self.numerOfCopys)

#        if split[lastPart].isdigit() and not split[lastPart].startswith("0"):
#            num = int(split[lastPart])
#            num = num + 1
#            newName = name.rstrip(split[lastPart])
#            newName = newName + str(num)
#        else:
#            newName = name + "_1"

        self.numerOfCopys = self.numerOfCopys + 1
        return newName

    def copyObjects(self):
        if len(self.userSelectionList) < 1:
            return

        newSelectionList = []

        for so in self.userSelectionList:
            if so.entity.getUserObject() is not None:
                if so.entity.getUserObject().getType() == "GAME_OBJECT_REPRESENTATION":
                    go = self.gocManager.getGameObjectWithClassId(so.entity.getUserObject().gocName)
                    meshFile = go.getMeshFileName()

                    if go is not None:
                        newEntity = self.sceneManager.createEntity("dropMesh" + str(self.dropCount), str(meshFile))
                        newNode = self.sceneManager.getRootSceneNode().createChild("dropNode" + str(self.dropCount))
                        newNode.attachObject(newEntity)
                        newNode.setPosition(so.entity.getParentNode().getPosition())

                        newGO = GameObjectRepresentation(self.dropCount, so.entity.getUserObject().gocName, newNode, meshFile)
                        self.gameObjectRepresentationDict.append(newGO)
                        newEntity.setUserObject(newGO)
                        newGO.setPosition(og.Vector3(0, 0, 0))

                        newSO = SelectionObject(newEntity, so.distance)
                        newSO.setSelected(True)
                        newSelectionList.append(newSO)
                        self.dropCount += 1
            else:
                nodeName = self.incrementNameSuffixNumber(so.entity.getParentNode().getName())
                newNode = self.sceneManager.getRootSceneNode().createChild(nodeName)

                entityName = self.incrementNameSuffixNumber(so.entity.getName())
                newEntity = self.sceneManager.createEntity(entityName, so.entity.getMesh().getName())

                newNode.attachObject(newEntity)
                newNode.setPosition(so.entity.getParentNode().getPosition())
                newNode.setOrientation(so.entity.getParentNode().getOrientation())
                newNode.setScale(so.entity.getParentNode().getScale())

                newSO = SelectionObject(newEntity, so.distance)
                newSO.setSelected(True)
                newSelectionList.append(newSO)

        self.resetSelection()
        self.userSelectionList = newSelectionList

    def cutObjects(self):
        if len(self.userSelectionList) < 1:
            return

        self.cutList = []
        for so in self.userSelectionList:
            self.cutListPreviousNodes.append(so.entity.getParentNode().getParent())
            so.entity.getParentNode().getParent().removeChild(so.entity.getParentNode())
            # set the "point of gravity" of all the cutted nodes to world origin at 0,0,0
            # so we only have to translate them to their new destination when they get pasted
            # the position of the pivot point is considered as the center of gravity
            so.entity.getParentNode().setPosition(so.entity.getParentNode().getPosition() - self.pivot.getPosition())
            self.cutList.append(so)
        self.resetSelection()

    def pasteObjects(self,  ray):
        if len(self.cutList) < 1:
            return

        result = og.Math.intersects(ray, self.dropCollisionPlane)
        if result.first == True:
            i=0
            while i < len(self.cutList):
                self.cutListPreviousNodes[i].addChild(self.cutList[i].entity.getParentNode())
                self.cutList[i].entity.getParentNode().translate(ray.getPoint(result.second))
                i = i+1
        else:
            i=0
            while i < len(self.cutList):
                self.cutListPreviousNodes[i].addChild(self.cutList[i].entity.getParentNode())
                self.cutList[i].entity.getParentNode().translate(ray.getPoint(100.0))
                i = i+1
        self.cutList = []

    def leftMouseUp(self):
        if self.pivot is not None and self.pivot.isTransforming:
            self.pivot.stopTransforming()

    def resetSelection(self):
        for so in self.userSelectionList:
            so.setSelected(False)

        self.userSelectionList = []



    def updatePivots(self):
        newPivotPosition = og.Vector3(0, 0, 0)

        for so in self.userSelectionList:
            newPivotPosition += so.entity.getParentNode().getPosition()
        if self.pivot is not None:
            self.pivot.setPosition(newPivotPosition / len(self.userSelectionList))

    def unload(self,  saveOnUnload=True):
        pass

    def save(self):
        pass

    def startDropGameObjectAction(self, classid, ray):
        go = self.gocManager.getGameObjectWithClassId(classid)

        if go is not None:
            meshFile = go.getMeshFileName()
            dropEntity = self.sceneManager.createEntity("dropMesh" + str(self.dropCount), str(meshFile))
            dropNode = self.sceneManager.getRootSceneNode().createChild("dropNode" + str(self.dropCount))
            dropNode.attachObject(dropEntity)

            result = og.Math.intersects(ray, self.dropCollisionPlane)
            if result.first == True:
                dropNode.setPosition(ray.getPoint(result.second))
            else:
                dropNode.setPosition(ray.getPoint(50))

            self.dropGO = GameObjectRepresentation(self.dropCount, classid, dropNode, meshFile)
            dropEntity.setUserObject(self.dropGO)

        self.dropCount += 1

    def moveDropGameObjectAction(self, ray):
        result = og.Math.intersects(ray, self.dropCollisionPlane)
        if result.first == True:
            self.dropGO.setPosition(ray.getPoint(result.second))
        else:
            self.dropGO.setPosition(ray.getPoint(50))

    def stopDropGameObjectAction(self, ray):
        print "sd"

    def startDropModelAction(self, meshFile, ray):
        self.dropEntity = self.sceneManager.createEntity("dropMesh" + str(self.dropCount), str(meshFile))
        self.dropNode = self.sceneManager.getRootSceneNode().createChild("dropNode" + str(self.dropCount))
        self.dropNode.attachObject(self.dropEntity)

        result = og.Math.intersects(ray, self.dropCollisionPlane)
        if result.first == True:
            self.dropNode.setPosition(ray.getPoint(result.second))
        else:
            self.dropNode.setPosition(ray.getPoint(50))

        self.dropCount += 1

    def moveDropModelAction(self, ray):
        result = og.Math.intersects(ray, self.dropCollisionPlane)
        if result.first == True:
            self.dropNode.setPosition(ray.getPoint(result.second))
        else:
            self.dropNode.setPosition(ray.getPoint(50))


    def stopDropModelAction(self, ray):
        pass