from tkinter import *
from tkinter import simpledialog
from tkinter import filedialog
import threading
import socket
import datetime
from openpyxl import Workbook,load_workbook


class Socketclient:
        port = 9999
        #port = 23
        timeserver = datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S")
        times = datetime.datetime.now().strftime("%H:%M:%S")
       
        def __init__ ( self , ip = 0 ,stip = False,):
                self.ip = ip
                self.stip = stip
                
        def chk_allclient(self):
                global runstatus_on               
                while runstatus_on == 1:
                        for lclient in range(start_Cn if int(start_Cn) > int(start_n) else start_n ,end_Cn+1 if int(end_Cn) < int(nclient) else nclient):
                                if runstatus_on == 0:
                                        break
                                else:
                                        self.chk_numclient(lclient)
                                        
        def chk_numclient(self,numberclient):    
                if self.chk_ip(get_ip2[0][numberclient]) == True:      
                        Get_BT[numberclient].config(bg="green")
                else:              
                        Get_BT[numberclient].config(bg="red")


        def chk_numclient2(self,numberclient):
                times = datetime.datetime.now().strftime("%H:%M:%S")
                if self.chk_ip(get_ip2[0][numberclient]) == True:      
                        Get_BT[numberclient].config(bg="green")
                        entry.insert(END,f'{int(get_ip2[1][numberclient])}.  {get_ip2[0][numberclient]} online {times}\n')
                else:              
                        Get_BT[numberclient].config(bg="red")
                        entry.insert(END,f'{int(get_ip2[1][numberclient])}.  {get_ip2[0][numberclient]} offline {times}\n')
                        
        def chk_ip(self,ip):
                try:
                        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                                s.settimeout(Speedtest.get())
                                s.connect((ip,Socketclient.port))
                                s.close()
                                return True
                except socket.error as msg:
                    s.close()                    
                 
                    return False
               
## GOLDBLE ######
## add class                
s = Socketclient() 

runstatus_on = 1


def on_select(e):      
    status = e.widget["text"]
    global runstatus_on
    if status == "RUN":
            e.widget["bg"]= "red"
            e.widget["text"]= "STOP"
            runstatus_on = 1
    else:
        e.widget["bg"]= "green"
        e.widget["text"]= "RUN"
        runstatus_on = 0

def On_reset():
    for lclient in range(start_n,nclient):
            Get_BT[lclient].config(bg="black")


############################################# Frame main ############################################# 
Check_cliet_App = Tk()
Check_cliet_App.option_add('*font','tahoma 10')
Check_cliet_App.title('Display resolution 1280 X 1024 (Recommended)')

f1 = Frame(Check_cliet_App)
f1.grid(row=0,column=0,columnspan=3)




####################################################################################################### 


############################################# Frame NW #############################################
f2 = Frame(Check_cliet_App)
f2.grid(row=1,column=0,pady=10,padx=5,stick=NE)

lbf0 = LabelFrame(f2,text="Client")
lbf0.pack(side=RIGHT)




############################################# Frame NW #############################################
f3 = Frame(Check_cliet_App)
f3.grid(row=1,column=1,pady=10,padx=5,stick=NE)

lbf1 = LabelFrame(f3,text="Network Speed")
lbf1.pack(side=TOP,fill=X)
lbf2 = LabelFrame(f3,text="start and end")
lbf2.pack(side=TOP,fill=X)

lbf5 = LabelFrame(f3,)
lbf5.pack(side=TOP,fill=X)

lbf3 = LabelFrame(f3,text="FILE EXCEL")
lbf3.pack(side=TOP,fill=X)

lbf4 = LabelFrame(f3,text="Status Check")
lbf4.pack(side=TOP,fill=X)
entry = Text(lbf4, width=35, height=20)
entry.grid(row=0, column=0)

scl = Scrollbar(lbf4,orient=VERTICAL,command=entry.yview)
scl.grid(row=0, column=1,sticky=N+S)
entry.config(yscrollcommand=scl.set)


########################################## Scrollbar##################################################### 


canvas = Canvas(lbf0,width=810, height=670)
canvas.grid(column=0, row=0, sticky=N+S+E+W)
#Add a scrollbar that will scroll the canvas vertically
vscrollbar = Scrollbar(lbf0,orient=VERTICAL)
vscrollbar.grid(column=1, row=0, sticky=N+S)
#Link the scrollbar to the canvas
canvas.config(yscrollcommand=vscrollbar.set)
vscrollbar.config(command=canvas.yview)

#Add a scrollbar that will scroll the canvas horizontally
hscrollbar = Scrollbar(lbf0, orient=HORIZONTAL)
hscrollbar.grid(column=0,row=1, sticky=E+W)
canvas.config(xscrollcommand=hscrollbar.set)
hscrollbar.config(command=canvas.xview)
f = Frame(canvas)

####################################################################################################### 


############################################# Frame NE #############################################





#####################################################################################################



##Check_cliet_App2 = Tk()
##f5 = Frame(Check_cliet_App2)
##f5.grid(row=0, column=0,)



############################################# Frame tkinter #############################################
start_n = 1
nclient = 1600
Row_button = 2 ## ROW
Column_button = 0 ## Column
def BT_n():
        btn_n = []
        for n in range(0,1600):
                btn_n.append(n)
        return btn_n
Get_BT = BT_n()
############################################# Button client ############################################# 
for button in range(start_n,nclient):    
##command1 = lambda x = button : s.chk_numclient2(x)
        command1 = lambda x = button : threading.Thread(target=s.chk_numclient2(x)).start()
        if button != "1999":
                Get_BT[button] = Button(f, text=button, width=2,height=0, bg="black", fg="white",
                                   activeforeground="white", relief="ridge", padx=5,
                                   pady=1.5, bd=2,command=command1)
                Get_BT[button].grid(row=Row_button, column=Column_button)
                Get_BT[button].grid_forget()


        Column_button += 1
        if Column_button > 24:
                Column_button = 0
                Row_button += 1
                
        
########################################################################################################


############################################ Button RUN #############################################
command2 = lambda : threading.Thread(target=s.chk_allclient).start()
btn_start = Button(f3,text="RUN", width=15,height=2, bg="green", fg="#ffffff",
                   activebackground="#ffffff", activeforeground="#000000", relief="raised", padx=5,
                   pady=1.5, bd=1.5,command=command2)
btn_start.pack(side=BOTTOM,pady=5,padx=2,fill=X)
btn_start.bind("<Button-1>", on_select)

############################################# Button reset #############################################
command3 = lambda : threading.Thread(target=On_reset).start()
btn_reset = Button(f3, text="RESET", width=1,height=2, bg="blue", fg="white",
                  activebackground="gray", activeforeground="#000000",relief="raised",
                   bd=1.5,command=command3,)
btn_reset.pack(side=TOP,pady=5,padx=2,fill=X)

############################################# Radio Button #############################################


Network_Speedtest = [
        ("1","0.1"),
        ("2","0.2"),
        ("3","0.3"),
        ("4","0.4"),
        ("5","0.5"),
        ]
Speedtest = DoubleVar()
Speedtest.set(0.1)
for speed , vv in Network_Speedtest:
        Radiobutton(lbf1,text=speed,padx=5,pady=1.5,variable=Speedtest,value=vv).pack(side=LEFT,expand=YES)

start_Cn = 1
end_Cn = 1

########################################################################################################
rang_start = StringVar()
rang_end = StringVar()

def ask_intstart():
        p = simpledialog.askinteger("START CLIENT","ใส่ค่า CLIENT เริ่มต้น")
        global nclient
        global start_Cn
        if p!= None:
                if 0 >= p or nclient <= p:    
                        rang_start.set(1)
                        start_Cn = 1
##                        print(start_Cn)
                else:
                        rang_start.set(p)
                        start_Cn = p
##                        print(start_Cn)
                        

def ask_intend():    
        p = simpledialog.askinteger("END CLIENT","ใส่ค่า CLIENT สิ้นสุด")
        global nclient
        global end_Cn
        
        if p!= None:          
                if 0 >= p or nclient-1 <= p:                         
                        rang_end.set(nclient-1)
                        end_Cn = nclient-1
##                        print(end_Cn)
                else:                        
                        rang_end.set(p)
                        end_Cn = p
##                        print(end_Cn)



def get_setrange():
        global start_Cn
        global end_Cn
        tt=(start_Cn,end_Cn)
        start_Cn = min(tt)
        end_Cn = max(tt)
        entry.insert(END,f'SET Client Range {start_Cn} - {end_Cn}\n')
        

bt_nstart = Button(lbf2, text="START", width=10,height=1, bg="blue", fg="white",
                  activebackground="gray", activeforeground="#000000",relief="raised",
                   bd=1.5,command=ask_intstart)
bt_nstart.pack(side=LEFT,pady=10,padx=2,expand=YES)


rangs1 = Entry(lbf2,bd=2,width=5,textvariable=rang_start,state=DISABLED ).pack(side=LEFT,expand=YES)


rangs2 = Entry(lbf2,bd=2,width=5,textvariable=rang_end,state=DISABLED).pack( side=LEFT,expand=YES)


bt_nend = Button(lbf2, text="END", width=10,height=1, bg="blue", fg="white",
                  activebackground="gray", activeforeground="#000000",relief="raised",
                   bd=1.5,command=ask_intend)
bt_nend.pack(side=LEFT,pady=10,padx=2,expand=YES)

bt_setloop = Button(lbf5, text="SET RANGE", width=1,height=2, bg="blue", fg="white",
                  activebackground="gray", activeforeground="#000000",relief="raised",
                   bd=1.5,command=get_setrange)
bt_setloop .pack(side=TOP,pady=5,padx=2,fill=X) 
########################################################################################################

lb_openfile = StringVar()
def ask_openfile():
        type = [('Excel file *.xlsx','*.xlsx')]
        of = filedialog.askopenfile(title = "Select file",mode="r+",filetype=type,initialdir='c:\\')
        if of!= None :
                entry.insert(END,f'Open File \n{of.name}\n')
                lb_openfile.set(of.name)
                try:
                        get_clientip(of.name) 
                        global get_ip2
                        global nclient
                        global end_Cn
                        get_ip2 = get_clientip(of.name)                       
                        bt_nstart.config(state=NORMAL)
                        bt_nend.config(state=NORMAL)
                        btn_start.config(state=NORMAL)
                        btn_reset.config(state=NORMAL)
                        bt_setloop.config(state=NORMAL)
                        nclient = len(get_ip2[0])
                        BTN_show()
                        rang_start.set(1)
                        rang_end.set(nclient-1)
                        end_Cn = nclient-1
                        
                        canvas.create_window((0,0), anchor=NW, window=f)
                        f.update_idletasks()
                        canvas.config(scrollregion= f.bbox("all"))
                except :
                        entry.insert(END,'กรุณานำเข้าไฟล์ EXCEL ก่อนการใช้งาน')
                        
label_openfile = Entry(lbf3,bd=2,width=28,textvariable=lb_openfile,state=DISABLED).pack( side=LEFT,expand=YES)
btn_openfile = Button(lbf3, text="Open File", width=10,height=1, bg="blue", fg="white",
                  activebackground="gray", activeforeground="#000000",relief="raised",
                   bd=1.5,command=ask_openfile).pack(side=LEFT,pady=10,padx=2,expand=YES)
get_ip2 = []

                 
def get_clientip(excel):
        clientnum_excel_01 = [0]
        clientnum_ip_02 = [0]
        count_loop = [0]
        loc = (excel)
        workbook = load_workbook(loc)
        sheet_ranges = workbook.active
        client_count_03 = sheet_ranges['B1'].value
        for i in range(4,client_count_03 + 4): 
                clientnum_excel_01.append(sheet_ranges.cell(row = i, column = 1).value)
                n = 0
                count_loop.append(n)
        for i in range(4,client_count_03 + 4): 
                clientnum_ip_02.append(sheet_ranges.cell(row = i, column = 2).value)
        return   clientnum_ip_02,clientnum_excel_01,count_loop

def BTN_show():
        
        Row_button = 2 ## ROW
        Column_button = 0 ## Column
##        print(nclient)
        for n in range(start_n,nclient):
                Get_BT[n].config(state=NORMAL)
                conversion_num =  get_ip2[1][n]
                Get_BT[n].config(text=int(conversion_num))
                Get_BT[n].grid()
                Get_BT[n].grid(row=Row_button, column=Column_button)
                Column_button += 1
                if Column_button > 24:
                        Column_button = 0
                        Row_button += 1

                
                        
bt_nstart.config(state=DISABLED)
bt_nend.config(state=DISABLED)
btn_start.config(state=DISABLED)
btn_reset.config(state=DISABLED)
bt_setloop.config(state=DISABLED)





Check_cliet_App.mainloop()



