#<Lib>#

import socket, time, threading, datetime
from tkinter import *                                                                                                                               #Import Lib

#</Lib>#
    


#<Pop-Up>#

class PopUp(object):                                                                                                                                #Pop-Up Klasse
    def __init__(self):                                                                                                                             #Pop-Up Bedienungsanleitung
        self.username = ''                                                                                                                          #zur Namensgebung
        self.message = '''Willkommen User!


Bitte gebe einen Namen ein und bestÃ¤tige
die Eingabemit einem Klick auf
die OK-Taste! Vielen Dank!'''
        self.gui(self.message)
        
        
    def destroy(self):
        if self.entryName.get() != None and self.entryName.get() != '\n':
            self.username = self.entryName.get()
        self.fenster.quit()                                                                                                                         #Destroy Pop-Up
        self.fenster.destroy()
        c = Client(self.username)
        c.gui()
        
        
    def gui(self,message):                                                                                                                          #Create Pop-Up GUI
        self.fenster = Tk()
        self.fenster.geometry('300x205')
        self.fenster.title('Namensgebung')
        self.fenster.config(background='#FF3333')
        
        self.frameInfo = Frame(master=self.fenster, background="#36648B")
        self.frameInfo.place(x=5, y=5, width=290, height=195)
        
        self.labelInfo = Label(master=self.frameInfo, background="#CC3333", justify=CENTER, padx=10 , text=self.message, font=('Arial', 10))        #Nachricht
        self.labelInfo.place(x=5, y=5, width=280, height=110)

        self.entryName = Entry(master=self.frameInfo , justify=CENTER , font = ('Arial',15), background="#FFFFCC")                                  #Eingabefeld Name
        self.entryName.place(x=5, y=125, width=280, height=35)
        
        self.buttonServer = Button(master=self.fenster, text="OK", command=self.destroy, background='#CC3333')                                      #Kill-Button
        self.buttonServer.place(x=125, y=170, width=50, height=25)
        
        self.fenster.mainloop()
        
#</Pop-Up>#


#<Client>#
        
class Client(object):                                                                                                                               #Client-Klasse
    def __init__(self,name):
        self.username = None
        if name == '' :
            self.username = 'DAU'
        else:
            self.username = str(name)
        self.address = None
        self.port = None                                                                                                                  #Client-Attribute
        self.verbindung = False
        self.durchlauf = True
        self.message = """Willkommen User!



Das hier ist das Informationsfenster fÃ¼r
den Client. Bevor du deine Schreiblust
ausleben kannst, stelle sicher dass du
eine IP-Adresse und einen Port von einem
Chatserver besitzt, um ihm beizutreten.


Das Entwicklerteam,Brian, wÃ¼nscht dir
viel SpaÃŸ beim schreiben!"""


    def checkUp(self):
        if self.port != None and self.address != None:                                                                                              #Check Up vor Sende-/AktualisierungsmÃ¶glichkeit
            self.buttonSend.config(state='active')
            self.buttonAkt.config(state='active')

            
    def endlessAktualisieren(self):                                                                                                                 # Aktualisieren
        while True:
            time.sleep(5)
            self.durchlauf = False
            self.aktualisieren()                                                                                                                    #Durchlauf => Keine Ãœberkreuzung
            self.durchlauf = True
            
            
    def senden(self):
        if self.durchlauf == True:
            c = socket.socket()
            now = datetime.datetime.now()
            c.connect((self.address,self.port))                                                                                                     #Verbindung&Sendemethode
            c.send(bytes(('SET ' + self.username + ' ('+str(now)[11:19]+') ' + ': '+ self.sendeText.get("1.0",END)),encoding='utf8'))
            for i in range(0,5):
                text = str(c.recv(4096))
            self.sendeText.delete(0.0, END)                                                                                                         #Delete Sendetext
            self.aktualisieren()
            if self.verbindung == False:
                self.verbindung = True
                self.routine = threading.Thread(target = self.endlessAktualisieren)                                                                 #Threading if False
                self.routine.start()
            c.close()
        else:
            time.sleep(0.5)
            self.senden


    def aktualisieren(self):
        c = socket.socket()
        self.empfangen.delete(0.0, END)
        emptext = ['','','','','','','','','','','','','','','','','','','','','','','','','','','','']
        text = ['','','','','','','','','','','','','','','','','','','','','','','','','','','','']
        c.connect((self.address,self.port))                                                                                                         #Verbindung&Sendemethode
        c.send(bytes(('GET'),encoding='utf8'))
        check = 0
        for i in range(0,28):
            emptext[i] = str(c.recv(4096))
        for i in range(0,28):
            for j in range(0,len(emptext[i])):
                if check == 0 or check == 6:
                    check = 0
                    if emptext[i][j] == '\\':
                            text[i] = text[i] + '\n'                                                                                                #Scan Message
                            check = check + 1
                    else:
                        text[i] = text[i] + emptext[i][j]
                else:
                    check = check + 1
        for i in range(0,28):
            if i == 0:
                self.empfangen.insert(END, text[i][4:])                                                                                             #Insert Message
                self.empfangen.see(END)
            else:
                self.empfangen.insert(END, text[i][3:])                                                                                             #Insert Message
                self.empfangen.see(END)
        if self.verbindung == False:
            self.verbindung = True
            self.routine = threading.Thread(target = self.endlessAktualisieren)                                                                     #Threading if False
            self.routine.start()
        c.close()        

        
    def setIp(self):
        self.address = self.entryIp.get()
        self.empfangen.insert(END, 'IP-Adresse festelegt.\n')                                                                                       #SET IP
        self.empfangen.see(END)
        self.buttonIp.config(background = 'grey')
        self.checkUp()


    def setPort(self):
        self.port = int(self.entryPort.get())                                                                                                       #SET PORT
        self.empfangen.insert(END, 'Port festelegt.\n')
        self.empfangen.see(END)
        self.buttonPort.config(background = 'grey')
        self.checkUp()

        
    def gui(self):
        self.root = Tk()
        self.root.geometry('800x600')                                                                                                               #Erzeugung Tkinter
        self.root.title('Chatroom "Informatik-Saal RBG" - Client v1.0')
        self.root.config(background='#FF3333')
        
        self.frameMain = Frame(master=self.root, background="#36648B")                                                                              #Haupt-Frame        
        self.frameMain.place(x=10, y=10, width=780, height=580)
        
        self.frameHead = Frame(master=self.frameMain, background="#FF3333")  
        self.frameHead.place(x=290, y=10, width=200, height=40)                                                                                     #Ãœberschrift_Main
        
        self.labelHead = Label(master=self.frameHead,background="white", text="Client-Chatroom", font = ('Arial',15))
        self.labelHead.place(x=5, y=5, width=190, height=30)
        
        self.frameSendeText = Frame(master=self.frameMain, background="#FF3333")
        self.frameSendeText.place(x=5, y=520, width=370, height=50)                                                                                 #Eingabefeld Chat
        
        self.sendeText = Text(master=self.frameSendeText, background="#FFFFCC")                                
        self.sendeText.place(x=5, y=5, width=360, height=40)
        
        self.buttonSend = Button(master=self.frameMain,text="Senden", command=self.senden, state='disabled',background = 'grey')                                        #Button Senden
        self.buttonSend.place(x=385, y=520, width=190, height=50)
        
        self.buttonAkt = Button(master=self.frameMain, text="Manuelles Aktualisieren", command=self.aktualisieren, state='disabled',background = 'grey')               #Button Aktualisierung
        self.buttonAkt.place(x=585, y=520, width=190, height=50)
        
        self.entryIp = Entry(master=self.frameMain, justify=CENTER, background="#FFFFCC")                                                           #Eingabefeld IP
        self.entryIp.place(x=385, y=60, width=190, height=50)
        
        self.buttonIp = Button(master=self.frameMain, text="IP-Adresse festlegen", command=self.setIp, background ='#FF3333')                                              #Button IP-Festlegung
        self.buttonIp.place(x=585, y=60, width=190, height=50)

        self.entryPort = Entry(master=self.frameMain, justify=CENTER, background="#FFFFCC")                                                         #Eingabefeld Port
        self.entryPort.place(x=385, y=120, width=190, height=50)
        
        self.buttonPort = Button(master=self.frameMain, text="Port festlegen", command=self.setPort, background ='#FF3333')                                                #Button Port-Festlegung
        self.buttonPort.place(x=585, y=120, width=190, height=50)

        self.frameInfo = Frame(master=self.frameMain, background="#FF3333")
        self.frameInfo.place(x=385, y=180, width=390, height=330)

        self.labelInfo = Label(master=self.frameInfo, background="white", justify=CENTER, text=self.message, font=('Arial', 15))
        self.labelInfo.place(x=5, y=5, width=380, height=320)

        self.frameEmpfangen = Frame(master=self.frameMain, background="#FF3333")
        self.frameEmpfangen.place(x=5, y=60, width=370, height=450)                                                                                 #Chattext
        
        self.empfangen = Text(master=self.frameEmpfangen, background="#FFFFCC")
        self.empfangen.place(x=5, y=5, width=345, height=440)

        self.scrollbar = Scrollbar(master=self.frameEmpfangen, orient=VERTICAL)
        self.scrollbar.place(x=351, y=6, width=15, height=440)                                                                                                              #Scrollbar
        self.empfangen.config(yscrollcommand=self.scrollbar.set)
        self.scrollbar.config(command=self.empfangen.yview)

        self.root.mainloop()
        
#</Client>#            

        
#<Server>#
class Server(object):                                                                                                                               #Server-Klasse
    def __init__(self):
        self.l = ['','','','','','','','','','','','','','','','','','','','','','','','','','','','']
        self.k = []
        self.port = None
        p = socket.gethostname()                                                                                                                    #Server-Attribute
        self.ip = 'Eigene IP-Adresse: ' + socket.gethostbyname(p)
        self.s = socket.socket()
        self.message = "Bedienungsanleitung\n\n"+"""Willkommen Administrator!\n Es gibt ein paar Dinge die du wissen solltest:\n
Wenn du den Server starten solltest,\ndann erschreck nicht!Das Fenster erhÃ¤ngt sich!\n
Achte darauf, dass du deine IP-Adresse\n und Port richtig weitergibst!\n
Achte darauf, dass du sie an\n die Richtigen weitergibst!\n
Have Fun!"""
        


    def threadStarten(self):
        self.abhoeren = threading.Thread(target = self.starten)                                                                                      #Thread zum abhÃ¶ren
        self.abhoeren.start()
        self.buttonStart.config(state='disabled')
        self.buttonPort.config(state='disabled') 


    def startenButton(self):
        self.textLog.delete(0.0, END)
        self.textLog.insert(END, '---------------------------------\n')
        self.textLog.insert(END, '-----Server wurde gestartet!-----\n')
        self.textLog.insert(END, '---------------------------------\n')
        self.textLog.see(END)
        self.threadStarten()
        

        
    def starten(self):                                                                                                                              #Warten,Verbindung und Senden/Annahme
        self.s.listen(1)
        (k, adr) = self.s.accept()
        text = k.recv(4096)                                                                                                                         #Empfangen, Fallunterscheidung
        if (chr(text[0]) == 'S') and (chr(text[1]) == 'E') and (chr(text[2]) == 'T'):                                                               #Einschreiben, Senden
            for i in range(0,27):
                self.l[i] = self.l[i+1]
            self.l[27] = str(text[4:])
            self.textLog.insert(END, (self.l[27][2:len(self.l[27])-3]+'\n'))
            self.textLog.see(END)
        elif (chr(text[0]) == 'G') and (chr(text[1]) == 'E') and (chr(text[2]) == 'T'):                                                             #Senden
            for i in range(0,28):
                k.send(bytes(self.l[i],encoding='utf8'))
        k.close()
        self.starten()


    def setPort(self):
        self.port = int(self.entryPort.get())
        self.buttonStart.config(state='active')                                                                                                     #Set Port
        self.textLog.insert(END, 'Port festelegt.\n')
        self.textLog.insert(END, 'Server kann nun gestartet werden.\n')
        self.textLog.insert(END, '---------------------------------\n')
        self.textLog.see(END)
        self.s.bind(('',self.port))                                                                                                                 #Bind Port


    def gui(self):
        self.root = Tk()
        self.root.geometry('800x600')                                                                                                               #Erzeugung Tkinter
        self.root.title('Chatroom "Informatik-Saal RBG" - Server v1.0')
        self.root.config(background='#FF3333')
        
        self.frameMain = Frame(master=self.root, background="#36648B")                                                                              #Haupt-Frame
        self.frameMain.place(x=10, y=10, width=780, height=580)
        
        self.frameHead = Frame(master=self.frameMain, background="#FF3333")
        self.frameHead.place(x=290, y=10, width=200, height=40)                                                                                     #Ãœberschrift_Main
        
        self.labelHead = Label(master=self.frameHead, background="white", text="Server-KonfigurationsmenÃ¼")
        self.labelHead.place(x=5, y=5, width=190, height=30)
        
        self.frameHeadLog = Frame(master=self.frameMain, background="#FF3333")
        self.frameHeadLog.place(x=400, y=60, width=370, height=40)                                                                                  #Ãœberschrift_Chatprotokoll
        
        self.labelHeadLog = Label(master=self.frameHeadLog, background="white", text="Chatprotokoll")
        self.labelHeadLog.place(x=5, y=5, width=360, height=30)
        
        self.frameLog = Label(master=self.frameMain, background="#FF3333")
        self.frameLog.place(x=400, y=110, width=370, height=460)                                                                                    #Chatprotokoll
        
        self.textLog = Text(master=self.frameLog, background="#FFFFCC")
        self.textLog.place(x=5, y=5, width=340, height=445)

        self.frameConfig = Label(master=self.frameMain, background="#FF3333")
        self.frameConfig.place(x=5, y=60, width=370, height=40)                                                                                     #Ãœberschrift_Administrationsbereich
        
        self.labelConfig = Label(master=self.frameConfig, background="white", text="Administrationsbereich")
        self.labelConfig.place(x=5, y=5, width=355, height=25)

        self.frameIp = Frame(master=self.frameMain, background="#FF3333")
        self.frameIp.place(x=5, y=110, width=370, height=40)                                                                                        #Eigene IP - Anzeige
        
        self.labelIp = Label(master=self.frameIp, background="white", text=self.ip)
        self.labelIp.place(x=5, y=5, width=360, height=30)
        
        self.frameButton = Frame(master=self.frameMain, background="#FF3333")                                                                       #Port Bereich
        self.frameButton.place(x=5, y=160, width=370, height=40)
        
        self.frameButton2 = Frame(master=self.frameButton, background="white")
        self.frameButton2.place(x=100, y=5, width=265, height=30)
        
        self.buttonPort = Button(master=self.frameButton2, text="Port festlegen", command=self.setPort)                                             #Button Port
        self.buttonPort.place(x=5, y=5, width=125, height=20)
        
        self.buttonStart = Button(master=self.frameButton2,state='disabled', text="Server starten", command=self.startenButton)                     #Button Server starten
        self.buttonStart.place(x=135, y=5, width=125, height=20)
        
        self.entryPort = Entry(master=self.frameButton, justify=CENTER, background="#FFFFCC")                                                       #Eingabefeld Port
        self.entryPort.place(x=5, y=5, width=90, height=30)

        self.frameBedien = Frame(master=self.frameMain, background="#FF3333")
        self.frameBedien.place(x=5, y=210, width=370, height=360)

        self.labelBedien = Label(master=self.frameBedien, background="white", text=self.message, font=('Arial', 13))                                #Bedienungsanleitung
        self.labelBedien.place(x=5, y=5, width=360, height=350)

        self.scrollbar = Scrollbar(master=self.frameLog, orient=VERTICAL)
        self.scrollbar.place(x=346, y=6, width=15, height=445)                                                                                                              #Scrollbar
        self.textLog.config(yscrollcommand=self.scrollbar.set)
        self.scrollbar.config(command=self.textLog.yview)
             
        self.root.mainloop()        

#</Server>#    


#<Startprozess>#

class StartGui(object):                                                                                                                             #AnfangsGui zur Fallunterscheidung
    def __init__(self):
        self.root = None

        
    def createClient(self):                                                                                                                         #Erstelle Client-Objekt
        self.root.quit()
        self.root.destroy()
        p = PopUp()

        
    def createServer(self):                                                                                                                         #Erstelle Server-Objekt
        self.root.quit()
        self.root.destroy()
        s = Server()
        s.gui()


    def rootProcess(self):                                                                                                                          #Startprozess(Klasse) 
        self.root = Tk()
        self.root.geometry('350x150')                                                                                                               #Erzeugung Tkinter
        self.root.title('Chatroom "Informatik-Saal RBG" v1.0')
        self.root.config(background='#FF3333')

        self.frameInfo = Frame(master=self.root, background="#36648B")
        self.frameInfo.place(x=5, y=5, width=340, height=140)
        
        buttonClient = Button(master=self.frameInfo, text="Client", font=('Arial', 13), command=self.createClient, background='#FF3333')            #Button Client
        buttonClient.place(x=50, y=50, width=100, height=50)
        
        buttonServer = Button(master=self.frameInfo, text="Server", font=('Arial', 13), command=self.createServer, background='#FF3333')            #Button Server
        buttonServer.place(x=200, y=50, width=100, height=50)
        
        labelComment = Label(master=self.frameInfo, background="#FF3333", text="WÃ¤hle einen Dienst aus:", font=('Arial', 13))                       #Kommentar
        labelComment.place(x=50, y=10, width=250, height=20)
        
        self.root.mainloop()


root = StartGui()                                                                                                                                   #Startinitialisierung
root.rootProcess()

#</Startprozess>#


        
        
    
