from http.server import BaseHTTPRequestHandler,HTTPServer
import json
from urllib.parse import urlparse,  parse_qs
import os
import paho.mqtt.client as mqtt
import time

class ServHandler(BaseHTTPRequestHandler):
    
    def __init__(self,  request, client_address, server):
        mhtml = open("sdmain1.htmgui", "r") 
        self.mainhtml = mhtml.read()
        mhtml.close()
        
        errorimgfile = open(os.getcwd() + "/deckimgs/error.png", "rb")
        self.errorimg = errorimgfile.read()
        errorimgfile.close()
        
        super(ServHandler,  self).__init__(request, client_address, server)
            
    def buildvirtdeck(self,  deckser):
        decktable = ''
        decktable += '<tr>'
        for i in range(0, 7):
            decktable += '<td>&nbsp;</td>'
        decktable += '</tr>'
        
        knum = 0
        for row in range(0, 3):
            decktable += '<tr>'
            decktable += '<td>&nbsp;</td>'
            for col in range(0, 5):
                kimg = config.jsonarr[deckser][knum]['image']
                ktxt = config.jsonarr[deckser][knum]['text']
                decktable += '<td align="center" onclick="loadpart({0});"><img src="{1}"width="32" height="32"  alt="" />'.format(knum,  kimg)
                decktable += '<br><font color="white">{0}</font></td>'.format(ktxt)
                knum += 1
            decktable += '<td>&nbsp;</td>'
            decktable += '</tr>'
            
        decktable += '<tr>'
        for i in range(0, 7):
            decktable += '<td>&nbsp;</td>'
        decktable += '</tr>'    
            
        return decktable
        
        
    def buildcfgform(self,  keynum,  deckser):
        form = '<form action="sendcfg.set">'
        
        form += '<label for="keytext">Key Number:</label>'
        form += '<input type="number" min="0" max="14" value={} name="keynum" id="keynumber"><br>'.format(keynum)
        
        form += '<label for="keytext">Key Text:</label>  '
        form += '<input type="text" name="keytxt" id="keytext" value="{}"><br>'.format(config.jsonarr[deckser][int(keynum)]['text'])
        
        form += self.buildimglist()
        
        form += '<label for="keytext">Key Image:</label>'
        form += '<input name="deckserial" type="hidden" value="{}"></input>'.format(deckser)
        form += '<input type="text" name="keyimg" id="keyimg" value="{}" readonly><br><br>'.format(config.jsonarr[deckser][int(keynum)]['image'])
        
        form += '<button type="submit">Set Key</button>'
        
        form += '</form>'
        return form

    def buildimglist(self):
            imglist = '<h2>Select Icon</h2><br><table border="1px" bgcolor="black"><tr>'
            colcnt = 0
            
            for file in os.listdir(os.getcwd() + "/deckimgs"):
                if file.endswith(".png"):
                    if colcnt < 5:
                        imglist += '<td><img src="{0}" height=32 width=32 alt="" onclick=changeimgfile("{0}");></td>'.format(file)
                        colcnt += 1
                    else:
                        imglist += '<td><img src="{0}" height=32 width=32 alt="" onclick=changeimgfile("{0}");></td>'.format(file)
                        imglist += '</tr><tr>'
                        colcnt = 0
                        
            imglist += '</tr></table>'
            return imglist

    def do_GET(self):
        
        vfile = urlparse(self.path).path
        #print(vfile)

        if vfile == '/':
            self.send_response(200)
            self.send_header('Content-type','text/html')
            self.end_headers()
            self.wfile.write(self.mainhtml.encode())
            return
      
        if vfile.endswith('.png'):
            self.send_response(200)
            self.send_header('Content-type', 'image/png')
            self.end_headers()
            try:
                imgfile = open(os.getcwd() + '/deckimgs'+ vfile, "rb")
                imgblob = imgfile.read()
                imgfile.close()
                self.wfile.write(imgblob)
            except:
                self.wfile.write(self.errorimg)
            return
            
        if vfile == '/cfg.part':    
            self.send_response(200)
            self.send_header('Content-type','text/html')
            self.end_headers()
            numclick = parse_qs(urlparse(self.path).query).get('num', 0)
            deckserclick = parse_qs(urlparse(self.path).query).get('deckserial', '')
            
            cfgform = self.buildcfgform(numclick[0],  deckserclick[0])
            self.wfile.write(cfgform.encode())
            return
            
        if vfile == '/virtdeck.part':    
            self.send_response(200)
            self.send_header('Content-type','text/html')
            self.end_headers()
            deckserial = parse_qs(urlparse(self.path).query).get('deckserial', '')
            
            vdeck = self.buildvirtdeck(deckserial[0])
            self.wfile.write(vdeck.encode())
            return
            
        if vfile == '/sendcfg.set':
            keynum = parse_qs(urlparse(self.path).query).get('keynum', -1)
            keytext = parse_qs(urlparse(self.path).query).get('keytxt', '')
            keyimg = parse_qs(urlparse(self.path).query).get('keyimg', '')
            deckserial = parse_qs(urlparse(self.path).query).get('deckserial', '')
            
            self.send_response(303)
            self.send_header('location','/')
            self.end_headers()
            
            try:
                deckserial = deckserial[0]
                keynum = int(keynum[0])
                keytext = keytext[0]
                keyimg = keyimg[0]
                    
                print(deckserial,  keynum,  keytext,  keyimg)
                    
                config.jsonarr[deckserial][keynum]["text"] = keytext
                config.jsonarr[deckserial][keynum]["image"] = keyimg
                
                config.sendcfgtomqtt()
                
            except:
                print("Setting data failed!")

            return
            
        if vfile == '/getdecks.get':
            self.send_response(200)
            self.send_header('Content-type','text/html')
            self.end_headers()
            
            deckselector = '<form>'
            #deckselector += '<select name="dlist" id="decklist" size="1">'
            deckselector += '<select name="dlist" id="decklist" onclick="loaddeck(value)" size="1">'
            
            for serialnum in config.jsonarr:
                deckselector += '<option value={0}>{0}</option>'.format(serialnum)
                #deckselector += '<option onclick="loaddeck("' + serialnum + '")">' + serialnum + '</option>'
                #onclickfunc = "loaddeck('{}')".format(serialnum)
                #deckselector += '<option onclick="{0}">{1}</option>'.format(onclickfunc, serialnum)
            
            #print(deckselector)
            
            deckselector += '</select>'
            deckselector += '</label>'
            deckselector += '</form>'
            
            self.wfile.write(deckselector.encode())
            return

class deckconfig():
    
    def __init__(self):
        self.jsonarr = None
        self.cfgloaded = False
        self.client = mqtt.Client()
        #self.client.username_pw_set(username='user',password='passwort')
        self.client.connect_async("localhost", 1883, 60)
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        self.client.loop_start()
        
    def on_connect(self,  client, userdata, flags, rc):
        print("Connected to mqtt server with result code " + str(rc))
        client.subscribe("homeauto/streamdeck/currentcfg")

    def on_message(self,  client, userdata, msg):
        if msg.topic == "homeauto/streamdeck/currentcfg":
            self.jsonarr = json.loads(msg.payload.decode())
            self.cfgloaded = True
        
    def sendcfgtomqtt(self):
        senddat = json.dumps(self.jsonarr)
        self.client.publish("homeauto/streamdeck/control/config/write",  senddat.encode())

if __name__ == "__main__":

    config = deckconfig()
    print("Waiting for config data...")

    while config.cfgloaded is False:
        config.client.publish("homeauto/streamdeck/control/config/read",  "GET".encode())
        time.sleep(1)
    
    print("Got it! Starting Webservice...")
    server = HTTPServer(('0.0.0.0', 8080), ServHandler)
    print("server started")
    server.serve_forever()
