# -*-coding:Latin-1 -*
"""client chat"""
import socket
import threading
import time
import os

#modules complémentaires
import pymedia.audio.sound as sound
import pymedia.audio.acodec as acodec
import pyaudio

#modules perso
import lancer
from clientvoc import ClientVoc
from anason import AnaSon
from lecture import Lecture

#### initialisation des variables ####
port = 6660
taille_paquets = 1024


#### fils secondaires ####
class EnvoiFichier(threading.Thread):
    """fil d'emission"""
    def __init__(self, cnn, nomFichier, pseudo):
        """initialisation du fil"""
        threading.Thread.__init__(self)
        self.cnn = cnn
        self.nomFichier = nomFichier
        self.pseudo = pseudo
        
    def run(self):
       """envoi du fichier""" 
       if self.nomFichier != "":
           envoi = True
           try:
               self.fichier = open(self.nomFichier, "rb") # test si le fichier existe
           except:
               print("Le fichier '{}' est introuvable.".format(self.nomFichier))
               envoi = False

           if envoi:
               try:
                   self.cnn.send("{}{}{}".format("fi", self.pseudo, self.nomFichier))
                   envoi = True
               except:
                   time.sleep(0.1)
                   envoi = False
               time.sleep(0.5)
               
           if envoi:    
               taille = os.path.getsize(self.nomFichier)
               print("Envoi : '{}' [{} Ko]\n".format(self.nomFichier, (taille/1024)))
           
               # Si le fichier est plus lourd que 512o, on l'envoie par paquet
               num = 0
               if taille > 512:	
                    while envoi:
                        time.sleep(0.05)  #on veut un debit de 20ko/s max
                        donnees = self.fichier.read(512) # Lecture du fichier 512 par 512 octets                        
                        #print(len(donnees))
                        self.cnn.send("{}{}{}".format("fd", self.pseudo, donnees)) # Envoi du fichier par paquet de 512 octets +les 6car des infos
                        if donnees == "":
                            envoi = False
               else:
                    self.cnn.send("{}{}{}".format("fd", self.pseudo, self.fichier.read()))
                    
               self.cnn.send("{}{}{}".format("fd", self.pseudo, ""))         
               print("\n- Fichier envoye -")
               self.stop()
           else:
               print("\n- Envoi annule -")
           
    def stop(self):
        """fin de l'emission"""
        #print("Fin  de l'envoi de fichier")
        try: 
           self.fichier.close()
        except:
           pass 


class ReceptionFichier(threading.Thread):
    """fil d'emission"""
    def __init__(self, cnn, fichier):
        """initialisation du fil"""
        threading.Thread.__init__(self)
        self.cnn = cnn
        self.fichier = fichier
        
    def run(self):
       """envoi du fichier"""
       reception = False

       rep = "C:\\python_tmp\\chat complet\\"  
       k = 1
       tmp = self.fichier
       while os.path.isfile(rep+tmp):     
            k += 1
            tmp = self.fichier.split(".")[0]+str(k)+"."+self.fichier.split(".")[1]
            if k == 100:
                fichier = ""
                break
       self.fichier = tmp
       
       if self.fichier != "":
           print("Reception de : '{}'\n".format(self.fichier))
           self.fichier = open(self.fichier, "wb")
           reception = True
           k = 0
           while reception:
                recu = self.cnn.recv(1024)
                if recu[0:2] == "fd":
                    donnees = recu[6:]
                    #print(len(donnees))
                    if donnees == "":
                        reception = False
                        break
                    else:
                        self.fichier.write(donnees) 
                else:
                    pass 
           print("\n- Fichier recu -")
       else:
           print("\n- Erreur de reception du fichier -")
       self.stop()
           
    def stop(self):
        """fin de la reception"""
        #print("Fin  de la reception de fichier")
        try: 
           self.fichier.close()
        except:
           pass 



class Reception(threading.Thread):
    """fil de reception"""
    def __init__(self, cnn):
        """initialisation du fil"""
        threading.Thread.__init__(self)
        self.cnn = cnn
        self.connecte = True
        
    def run(self):
        """reception et d'affichage des messages"""
        while self.connecte:
           try:
               message_recu = self.cnn.recv(1024)
               if message_recu[:2] == "m ":
                   try:
                      pseudo = message_recu[2:6]
                      print("{}: {}".format(pseudo, message_recu[6:]))
                   except:
                      print("recu message illisible") 
               elif message_recu[:2] == "i ":
                   print("{}".format(message_recu[6:]))
               elif message_recu[:2] == "fi":
                   pseudo = message_recu[2:6]
                   fichier = message_recu[6:]
                   #if raw_input("{} veut vous envoyer le fichier {} (o/n)"\
                   #             "".format(pseudo, fichier)) == "o":
                   rf = ReceptionFichier(self.cnn, fichier)
                   rf.start()
                   rf.join()
           except:
              self.stop()

    def stop(self):
        """fin de la reception"""
        print("Reception TCP interrompue.")
        self.connecte = False     

            

class Client(threading.Thread):
    """client pour chat tcp"""
    def __init__(self):
        """initialisation du client"""
        threading.Thread.__init__(self)
        self.connecte = False
        self.pseudo = ""
        self.hote = ""

    def idClient(self):
        """recupere et met en forme l'identifiant du client"""
        while True:
            pseudo = raw_input("Pseudo (4 car. maximum) > ")
            if len(pseudo) > 0 and len(pseudo) <= 4:
                break                      
        while len(pseudo) < 4:
            pseudo += " " 
        self.pseudo = pseudo    

    def ipServeur(self):
        """recupere l'ip du destinataire"""
        hote = raw_input("Ip du serveur > ")
        if len(hote) == 0:
            hote = "localhost"
        self.hote = hote
          
    def creer(self):
        """cree le client"""
        self.idClient()
        self.ipServeur()
        print("En attente du serveur...")

        while self.connecte==False:
        #en attente de la connexion    
            try:
               self.cnn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
               self.cnn.connect((self.hote, port))
               self.connecte = True
               print("Connexion etablie avec le serveur sur le port {}\n".format(port))
            except KeyboardInterrupt:
               break
            except:
               pass

        if self.connecte:    
            self.R = Reception(self.cnn)
            self.R.start()
            self.start()

    def demarChatVocal(self):
           """demarre une instance client du chat vocal"""
        #try:
           self.cv = ClientVoc()
           self.cv.pseudo= self.pseudo
           self.cv.hote = self.hote
           self.cv.creer()
        #except: 
        #   print("Erreur: impossible de demarrer le chat vocal")

    def envoi(self, msg):
        """envoie un message au serveur TCP"""
        if self.connecte:
            try:
               if len(msg) <= 1024:
                  self.cnn.sendall(msg)
                  retour = len(msg)
               else:
                  retour = 0 
            except:
                print("Envoi impossible")
        else:
            print("Le client n'est pas connecte au serveur")
     
        return retour
    
    def run(self):
        """boucle de fonctionnement"""
        saisie = ""
        self.envoi("{}{}{} s'est connecte".format("i ", self.pseudo, self.pseudo))
        print(" 'f-xxxx.xxx' -> envoi de fichier \n 'vocal' -> lance le chat vocal "\
              "\n 'quit' -> quitte")
        while self.connecte:
            saisie = raw_input("")
            if saisie == "quit":
               saisie = "{} s'est deconnecte".format(self.pseudo) 
               self.envoi("{}{}{}".format("i ", self.pseudo, saisie))
               time.sleep(0.1)
               break
            elif saisie == "vocal":
               if raw_input("Voulez-vous demarrer le chat vocal? (o/n)") == "o":
                   self.demarChatVocal()
            elif saisie[:2] == "f-":
               fichier = saisie[2:]
               self.eF = EnvoiFichier(self.cnn, fichier, self.pseudo)
               self.eF.start()
               print("Envoi en cours, veuillez patienter")
               self.eF.join()
            else:
               self.envoi("{}{}{}".format("m ", self.pseudo, saisie))

        self.stop()
        
    def stop(self):
        """fermeture du client"""
        self.connecte = False
        self.R.stop()        
        self.cnn.close()
        if self.cv:
            self.cv.stop()
        time.sleep(0.1)
        print("Client ferme")
              

#### fil principal ####  
if __name__ == "__main__":
    # si lancement direct:
    c = Client().creer()
    


   
