def disconnectNode(self, isQuit):
        """ close the connection with the node """

        debug.debug_info("navigator.disconnectNode(" + str(isQuit) + ")")
        if (self.isConnected == 1):
            #print "navigator.disconnectNode()"
            #f = file("Debug.txt", 'a')
            #f.write("navigator.disconnectNode()\n")
            #f.close()
            try:
                # save the last position of the node
                self.saveLastPositionNode(isQuit)

                # close the services
                self.closeChatService()
                self.closeDisplay2dService()

                # close the connection with the node
                self.my_node.closeConnection()
                self.isConnected = 0

                # clear ihm
                self.ihm.clear2dView()
                self.ihm.clearChatterList()               
                
                return 1

            except:
                #sys.stderr.write("EXCEPTION : Problem in the node deconnection\n")
                commun.displayError(self.ihm, "Problem in the disconnection from the node !")
                return 0
    def resizeAvatars(self, size):
        """ Resize the avatars of the neighbors """
        debug.debug_info("avatarSizeDialog.resizeAvatars(" + str(size) +")")
        # initialize the avatars list
        try:
            avatarsList = os.listdir(commun.AVATAR_DIR_NAME)
        except:
            # no avatar in the avatars directory
            return

        for avatar in avatarsList:
            avatarFile = commun.AVATAR_DIR_NAME + os.sep + avatar
            if os.path.isfile(avatarFile):
                # open avatar file
                debug.debug_info("avatarFile = " + avatarFile)
                avatarImg = PIL.Image.open(avatarFile)
                # convert in RGBA format for transparency
                avatarImg = avatarImg.convert("RGBA")

                # resize the image file
                (width, height) = avatarImg.size
                newSize = width * size/100
                if newSize < 5:
                    # min size = 5 pixels
                    newSize = 5
                avatarImg = avatarImg.resize((newSize, newSize))

                # save the resize image
                resizeFile = commun.AVATAR_DIR_NAME + os.sep + commun.RESIZE_DIR_NAME + os.sep + avatar
                avatarImg.save(resizeFile)
    def isNodeConnected(self, host, port):
        """ check if the node passed in parameter is alive """
        """ the function returns 1 if the node is alive and 0 if not """

        #self.mutex.acquire()
        debug.debug_info("navigator.isNodeConnected()")
        answer = 0

        # create TCP socket to send a isAlive signal to the node
        try:
            node_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            node_socket.connect( (host, int(port)) )
        except:
            # the connection fails if the node is dead
            #self.mutex.release()
            return answer

        # send message
        msg = "isAlive"
        node_socket.send(msg)

        # waiting for answer
        answer = node_socket.recv(1024)
        node_socket.close()

        #self.mutex.release()
        return answer
    def connectNode(self, node_host, node_port):
        """ establish the connection with the node passed in parameter """

        debug.debug_info("navigator.connectNode()")
 
        try:
            # launch the node connection
            self.my_node = MyNode(node_host, node_port, self)
            self.my_node.launchConnection()

            # get information on the connected node
            self.my_node.getInfos()

            # add the services
            self.addChatService()
            self.addDisplay2dService()

            # change the connected status
            self.isConnected = 1

            # draw the 2d View after connection
            self.draw2dView()

            # refresh chatter
            #self.displayChatterList()
            return 1

        except:        
            commun.displayError(self.ihm, "Problem in the connection with the node !")
            return 0
 def addDisplay2dServiceNeighbor(self, event):
     debug.debug_info("ihm.addDisplay2dServiceNeighbor()")
     id=event.id
     if self.neighbor_item.has_key(id):
         self.neighbor_item[id][4] = TRUE
         # refresh the drawing
         self.toRefresh = TRUE
    def newNode(self, id, posX, posY, ca, pseudo, ori):
        """ we meet a new node inside the awareness radius"""
        debug.debug_info("connection.newNode : [%s]" %pseudo)

        # we check this neighbor doesn't exist yet
        if not self.my_node.neighbors.has_key(id):

            #we create an object of the class 'Neighbor' as a representative of this node
            new_neighbor = Neighbor(id, long(posX), long(posY), long(ca), pseudo, int(ori))

            #insert in me's neighbors
            self.my_node.neighbors[id] = new_neighbor

        else:
            #print 'ERROR : node %s allready exists ' %pseudo
            return 0


        # we inform the navigator with this neighbor
        #self.mutex.acquire()
        self.my_node.navigator.newNeighbor(new_neighbor)
        #wxPostEvent(self.my_node.navigator.ihm, wxMainFrame.newNeighborEvent(neighbor=new_neighbor))
        #self.mutex.release()

        return 1
    def deleteDisplay2dServiceNeighbor(self, id):
        """ delete the display2d service of the node id """

        #self.mutex.acquire()
        debug.debug_info("navigator.deleteDisplay2dServiceNeighbor()")

        self.ihm.deleteDisplay2dServiceNeighbor(id)        
    def imageGeneration(self):
        """ Generate the result image """
        debug.debug_info("createAvatarDialog.imageGeneration()")

        # control errors
        if not self.imageFileName:
            commun.displayError(self, 'Please, select your image file !')
            return
        else:
            # open image files
            maskImg = PIL.Image.open(self.maskFileName)
            fileImg = PIL.Image.open(self.imageFileName)

            # contol the file size (for resizing)
            (width, height) = fileImg.size
            if ((width < self.avatarSize) or (height < self.avatarSize)):
                commun.displayError(self, 'Your image has a bad format. Please, choose a bigger one !')
                return

            # resize the image file with the size of avatars
            maskImg = maskImg.convert("RGBA")
            fileImg = fileImg.resize((self.avatarSize, self.avatarSize))
            fileImg = fileImg.convert("RGBA")
            resultImg = PIL.ImageChops.multiply(fileImg, maskImg)
            return resultImg
    def jumpMyNode(self, x, y):

        #self.mutex.acquire()
        debug.debug_info("navigator.jumpMyNode()")

        if self.isConnected == 1:
            self.my_node.jump(x, y)
    def update2dView(self):
        """ update the 2D View of the node """

        #self.mutex.acquire()
        debug.debug_info("navigator.update2dView()")

        # set scale of Solipsis world displayed
        self.ihm.setScale(self.my_node.ar)
    def receiveImage(self, sender, image_name):

        #self.mutex.acquire()
        debug.debug_info("navigator.receiveImage(" + sender + "," + image_name + ")")

        # check if the Display2d is active
        if (self.isDisplay2dActive == 1):
            self.ihm.displayNeighborImage(sender, image_name)            
    def drawMyAvatar(self, image_name):
        """ draw the avatar selected in the 2D View """
        debug.debug_info("ihm.drawMyAvatar()")

        self.myNode_avatar = image_name

        # refresh the drawing
        self.toRefresh = TRUE
    def deleteImage(self, sender):

        #self.mutex.acquire()
        debug.debug_info("navigator.deleteImage()")

        # check if the Display2d is active
        if (self.isDisplay2dActive == 1):
            self.ihm.deleteNeighborImage(sender)            
    def OnAvatarSize(self, event):
        """ Display the avatar size dialog box """
        debug.debug_info("ihm.OnAvatarSize()")
        dlg = avatarSizeDialog(self)
        dlg.ShowModal()

        # refresh the display (to change the avatar size)
        self.toRefresh = TRUE
 def deleteDisplay2dServiceNeighbor(self, event):
     id=event.id
     debug.debug_info("ihm.deleteDisplay2dServiceNeighbor()")
     if self.neighbor_item.has_key(id):
         self.neighbor_item[id][4] = FALSE
         # refresh the drawing
         self.toRefresh = TRUE
     debug.debug_info("ihm.deleteDisplay2dServiceNeighbor() OK")
    def getIsConnected(self):
        """ return the connected status of the navigator """

        #self.mutex.acquire()
        debug.debug_info("navigator.getIsConnected()")
        connected_status = self.isConnected
        #self.mutex.release()
        return connected_status
    def newChatMessage(self, pseudo_sender, message):

        #self.mutex.acquire()
        debug.debug_info("navigator.newChatMessage()")

        # display message in window
        text_to_display = pseudo_sender + " says: " + message +"\n"
        self.ihm.addMessageInChatText(text_to_display)        
    def deleteNeighborImage(self, id):
        """ delete the image of the neighbor in the display2d """
        debug.debug_info("ihm.deleteNeighborImage()")
        # delete the neighbor image
        if self.neighbor_item.has_key(id):
            self.neighbor_item[id][6] = ""

            # refresh the drawing
            self.toRefresh = TRUE
        debug.debug_info("ihm.deleteNeighborImage() OK")
    def OnDisplayPseudos(self, event):
        """ change the display pseudos option """
        debug.debug_info("ihm.OnDisplayPseudos()")

        # save the new parameter value in the conf file
        self.isDisplayPseudos = self.menu2DView.IsChecked(wxID_WXMAINFRAMEMENU2DVIEWDISPLAYPSEUDOS)
        configuration.writeConfParameterValue("displayPseudos", self.isDisplayPseudos)

        # refresh the display
        self.toRefresh = TRUE
    def insertNeighbor(self, id, posX, posY, pseudo):

        debug.debug_info("ihm.insertNeighbor()")

        # store the new neighbor item with no service and no image
        self.neighbor_item[id] = [posX, posY, pseudo, FALSE, FALSE, FALSE, ""]

        # refresh the drawing
        #self.DoDrawing()
        self.toRefresh = TRUE
 def deleteChatServiceNeighbor(self, event):
     """ delete the chat service picto of the corresponding neighbor """
     
     debug.debug_info("ihm.deleteChatServiceNeighbor()")        
     id=event.id
     if self.neighbor_item.has_key(id):
         self.neighbor_item[id][3] = FALSE
         # refresh the drawing
         self.toRefresh = TRUE
     debug.debug_info("ihm.deleteChatServiceNeighbor() OK")
    def deleteNeighbor(self, id):
        debug.debug_info("ihm.deleteNeighbor(%s)" %id)
        # delete the neighbor item from the dictionnary
        del self.neighbor_item[id]

        # refresh the drawing
        #self.DoDrawing()
        self.toRefresh = TRUE
        # refresh the chatter list
        #self.navigator.displayChatterList()
        debug.debug_info("ihm.deleteNeighbor() OK")
    def getNodeAr(self):
        """ return the ar value of the connected node """

        #self.mutex.acquire()
        debug.debug_info("navigator.getNodeAr()")
        if (self.isConnected == 1):
            #self.mutex.release()
            return self.my_node.ar
        else:
            #self.mutex.release()
            return 0
    def draw2dView(self):
        """ draw the 2D View of the node """

        #self.mutex.acquire()
        debug.debug_info("navigator.draw2dView()")

        # set scale of Solipsis world displayed
        self.ihm.setScale(self.my_node.ar)
        
        # draw my node
        self.ihm.drawMyNode(self.my_node.pseudo, self.my_node.ar)
    def OnBrowseButton(self, event):
        """ Open a file dialog box to choose the image file """
        debug.debug_info("createAvatarDialog.OnBrowseButton()")

        wildcard = "Image files (*.bmp, *.jpg, *.gif, *.png)|*.bmp;*.jpg;*.gif;*.png"
        dlg = wxFileDialog(self, "Choose an image file", "", "", wildcard, wxOPEN)
        dlg.Center(wxBOTH)
        if dlg.ShowModal() == wxID_OK:
            # get the file name
            self.imageFileName=dlg.GetPath()
            self.fileTextCtrl.SetValue(self.imageFileName)
            debug.debug_info("imageFileName = " + self.imageFileName)
    def OnOkButton(self,event):
        """ Change the size of the avatars in the 2D view """
        debug.debug_info("avatarSizeDialog.OnOkButton()")
        size = self.sizeSlider.GetValue()

        # generate the avatars of the neighbors with the size value
        self.resizeAvatars(size)

        # save the new value in the conf file
        configuration.writeConfParameterValue("avatarSize", size)

        # close the dialog box
        self.Close(FALSE)
    def drawMyNode(self, pseudo, ar):
        debug.debug_info("ihm.drawMyNode")
        self.myNode_pseudo = pseudo
        self.myNode_ar = ar

        # default avatar
        avatarFile = commun.AVATAR_DIR_NAME + os.sep + pseudo + "_default.png"
        shutil.copyfile("Img//avat_gh.png", avatarFile)
        # resize the avatar file
        self.myNode_avatar = commun.chgSize(avatarFile)

        # refresh the drawing
        self.toRefresh = TRUE
    def sendImage(self, avatarFile, resizeFile):

        #self.mutex.acquire()
        debug.debug_info("navigator.sendImage()")

        # check if the Display2d is active
        if (self.isDisplay2dActive == 1):

            # send my avatar to the neighbors
            self.display2d.sendImage(avatarFile)

            # display my avatar in the 2D View
            self.ihm.drawMyAvatar(resizeFile)
    def initNodesList(self):
        """ Nodes List initialisation : start the nodes dead in the list """

        #self.mutex.acquire()
        debug.debug_info("navigator.initNodesList()")

        # last connected node
        lastConnectedHost = ""
        lastConnectedPort = ""

        # open the nodes file
        self.nodesFile = str("Nodes") + os.sep + "Nodes.txt"
        try:
            f = file(self.nodesFile, 'r')
        except:
            #self.mutex.release()
            return 0

        # read file and close
        list = f.readlines()
        f.close()

        for line in list:
            pseudo, host, port, posX, posY, isDistant, isConnected = line[:len(line) -1].split(';')
            #print "read node file pseudo=[%s]" %pseudo
            #print "read node file port=[%s]" %port
            if (isConnected == "1"):
                # save the host and the port of the last node connected
                lastConnectedHost = host
                lastConnectedPort = port

            #try:
                # try to establish the connection with the node
                #my_node = MyNode(host, port, self)
                #my_node.launchConnection()
                #my_node.closeConnection()

            if not self.isNodeConnected(host, port):
                # start the node if the connection failed an the node is a local one
                if isDistant == "0":
                    self.startNode(pseudo, port, posX, posY)
                    commun.displayMessage(self.ihm, "The node " + pseudo + " was restarted !")
                else:
                    # print a message if a distant node is dead
                    commun.displayMessage(self.ihm, "The distant node " + pseudo + " is dead. You can delete it from your nodes list.")

        # connect the navigator to the last node connected
        # connect the navigator to the last node connected
        if ((lastConnectedHost != "") and (lastConnectedPort != "")):
            #self.connectNode(socket.gethostbyname(socket.gethostname()), lastConnectedPort)
            self.connectNode(lastConnectedHost, lastConnectedPort)
    def closeDisplay2dService(self):
        """ Close the display2d service """

        debug.debug_info("navigator.closeDisplay2dService()")

        if self.isDisplay2dActive == 1:
            # close the display2d thread
            self.display2d.close()
            # we delete the display 2D service from the dictionary of my services
            del self.my_node.services[self.display2d.id_service]

            # we inform the node we have no longer the display2d service
            self.my_node.closeDisplay2dService()
            self.isDisplay2dActive = 0