#!/usr/bin/python
from tkinter import *
import requests
import re

st=0

# Get the IP address from input box.
# U is a shortcut for the 201.234.3.1 address (USB connection)
def get_destination_ip():
    ip=M1_ip.get()
    if (ip=="U") :
        ip="201.234.3.1"
    pattern=re.compile("^(\d+\.){3}\d+$")
    if bool(pattern.match(ip)) == False:
        ip=""
    return ip

# 50 procedurally created buttons. Use an object to encapsulate the calibration value to send when clicked.
class calib_btn:
    def __init__(self,frm,r,c,val):
        txt=chr(65+c)+str(r+1)
        self.calib_val=val
        self.btn=Button(frm,text=txt,command=self.sendGCode,width=5)
        self.btn.grid(row=r,column=c)

    def sendGCode(self):
        global st
        if st == 0:
            try:
                r=requests.get("http://{}:8080/cnc/cmd?cmd=M105V{:.1f}".format(get_destination_ip(),self.calib_val),headers={"User-Agent" : "Mozilla/5.0"})
            except:
                statusvar.set("Unable to send.")

# Generate the Calibration GCode
def sendCalibGCode():
    global st
    GCode = """G0 V-5.0\r
    M3 S0\r
    G0 F12000\r
    G1 F12000\r
    G90\r
    G0 X-230.0Y-170.0\r
    \r
    """

    for l in range(10):
        for c in range(5):
            v = -1.9 + 0.5 * l + 0.1 * c
            GCode = GCode + "G0 V{:.1f}\r\nG91 X-10.0\r\n".format(v)
# Don't know if extraneous G0 V-5 and G91 X-2.5 would be a problem so mimicking gcode sniffed as is.
            if (l < 9 or c < 4):
                GCode = GCode + "G0 V-5\r\n"
            if (c != 4):
                GCode = GCode + "G91 X-2.5\r\n"
        if (l < 9):
            GCode = GCode + "\r\nG0 X-230.0\r\nG91 Y-5.0\r\n\r\n"

    GCode = GCode + """\r
    G0 V-5\r
    G91 X-5\r
    G0 V3.0\r
    G91 X-5\r
    G91 Y-5\r
    G91 X5\r
    G91 Y5\r
    G0 V3.0\r
    \r
    M6\r"""

    if st == 0:
        try:
            st=1
            r=requests.post("http://{}:8080/cnc/data?action=upload&id=-1&zip=false&mac=d6:15:0a:40:c6:c1".format(get_destination_ip()),headers= { "Content-Type" : "application/json", "User-Agent" : "Mozilla/5.0" },data=GCode)
            st=2
        except:
            statusvar.set("Unable to send GCode")
            st=0

def get_status():
    global st
    destip=get_destination_ip()
    if (destip != ""):
        if st != 1:
            try:
                r=requests.get("http://{}:8080/get_status".format(destip),headers={"User-Agent" : "Mozilla/5.0"})
                rst=r.text
                if rst == "RunStatus = P_ONLINE_READY_WORK":
                    rst="Press button on device"
                elif rst == "RunStatus = P_WORKING":
                    rst="Work in Progress"
                else:
                    rst="Ready"
                    st=0
                statusvar.set(rst)
            except:
                statusvar.set("Unable to get status")
                st=0

    root.after(2000,get_status)

root=Tk()
root.title("M1 Blade Calibration Tool")

frmctrl=Frame(root,padx=10,pady=10)
frmctrl.pack()

lblip=Label(frmctrl,text="Adresse IP (U pour USB) :")
lblip.grid(row=0,column=0)

M1_ip=StringVar()
ipinput=Entry(frmctrl,textvariable=M1_ip,width=16)
ipinput.grid(row=0,column=1)

sendfile=Button(frmctrl,text="Send Calibration File",command=sendCalibGCode)
sendfile.grid(row=1,column=0)

quitbutton=Button(frmctrl,text="Quit",command=root.destroy)
quitbutton.grid(row=1,column=1)

frmcalib=Frame(root,padx=10,pady=10)
frmcalib.pack()

for r in range(10):
    for c in range(5):
        tmp=calib_btn(frmcalib,r,c,24-(r*0.5)-(c*0.1))

frmstatus=Frame(root,padx=10,pady=10)
frmstatus.pack(fill="x")

statusvar=StringVar()
statuslabel=Label(frmstatus,textvariable=statusvar,relief=RIDGE,borderwidth=2)
statuslabel.pack(expand=True,fill="x")

statusvar.set("(c) D.Moreaux 2021")
root.after(2000,get_status)

root.mainloop()
