import ugfx
import time
import badge
import wifi
import appglue
from hashlib import sha1
#import woezel

import uos
import ubinascii

from umqtt.simple import MQTTClient

class WinkeKatze:
    #   |\_/|
    #   (. .)
    #    =w=  (\
    #  /  ^  \//
    #  (|| ||)
    #  ,""_""_ .

    #   |\_/|
    #   (. .)
    #    =w=  
    #  /  ^  \\
    #  (|| ||)\\
    #  ,""_""_(/.

    def draw_cat(self,cat='up',footer="https://devlol.org - press A to wink all other cats"):
        i=2
        if (cat == 'up'):
            drawcat = self.cat
        elif (cat == 'down'):
            drawcat = self.catdown

        ugfx.clear(ugfx.WHITE)
        for line in drawcat:
           i += 1
           j=0
           for char in line:
               j +=1
               ugfx.string(8*j, 12*i,char, self.font, ugfx.BLACK)
           print (line)
        if footer:
            i +=1
            ugfx.string(8,12*i,footer,self.font,ugfx.BLACK)
        if self.clients > 0:
            ugfx.string(0,12,("%d online now" % (self.clients)),self.font,ugfx.BLACK)
        if self.nick:
            ugfx.string(110,90,("%s winks" % (str(self.nick))),self.font,ugfx.BLACK)
        if self.nick1:
            ugfx.string(110,80,("%s winks" % (str(self.nick1))),self.font,ugfx.BLACK)
        if self.nick2:
            ugfx.string(110,70,("%s winks" % (str(self.nick2))),self.font,ugfx.BLACK)
        if self.nick3:
            ugfx.string(110,60,("%s winks" % (str(self.nick3))),self.font,ugfx.BLACK)
        if self.nick4:
            ugfx.string(110,50,("%s winks" % (str(self.nick4))),self.font,ugfx.BLACK)
        ugfx.string(90,10,self.owner,"PermanentMarker36",ugfx.BLACK)
        ugfx.string(0,0,str(self.motd),self.font,ugfx.BLACK)
        ugfx.flush()

    def new_wink(self,msg):
        self.nick4 = self.nick3
        self.nick3 = self.nick2
        self.nick2 = self.nick1
        self.nick1 = self.nick
        self.nick = msg.decode("utf-8")

    def sub_cb(self,topic,msg):
        print ("received mqtt message topic: %s, payload: %s" % (topic,msg))
        if topic.endswith('/nick'):
            if msg.decode("utf-8") == self.nick:
                pass
            else:
                print ("setting received nick to %s" % msg.decode("utf-8"))
                self.new_wink(msg)
                list = []
                hash = ubinascii.hexlify(sha1(self.nick).digest())
                for i in range(6):
                    # reverse because of reverse()
                    list.append(0)
                    list.append(int(int(hash[i*6+4:i*6+6], 16)/7))
                    list.append(int(int(hash[i*6+2:i*6+4], 16)/7))
                    list.append(int(int(hash[i*6:i*6+2], 16)/7))

                list.reverse()
                colors = bytes(list)
                self.wink(colors)
        if topic.endswith('/motd'):
          self.motd = msg.decode("utf-8")
          self.draw_cat()
          for i in range(2):
          		badge.leds_send_data(''.join(['\50\0\0\0' for i in range(6)]))
          		time.sleep(0.1)
          		badge.leds_send_data(''.join(['\0\0\0\0' for i in range(6)]))
          		time.sleep(0.1)
        #if topic.endswith('/version'):
        #  nv = int(msg.decode("utf-8"))
        #  if nv > self.version:
        #    woezel.install("Winkekatze")
        #    appglue.start_app("Winkekatze")
        if topic.endswith('/num_clients'):
            self.clients = int(msg.decode("utf-8"))
            self.draw_cat()
    
    def wink(self, colors):
        for count in range(2):
            self.draw_cat(cat="down")
            badge.leds_send_data(colors)
            badge.vibrator_activate(127)
            time.sleep(0.5)
            self.draw_cat()
            badge.leds_send_data(''.join(['\0\0\0\0' for i in range(6)]))
            time.sleep(0.5) 
        
    def btn_select(self,pressed):
        if pressed:
            print("Returning to homescreen")
            badge.leds_disable()
            appglue.start_app("")
            return 0

    def btn_a(self,pressed):
        if pressed:
            print ("publish nick %s to topic %s/nick" % ( self.owner,  self.topic))
            self.c.publish(("%s/nick" % self.topic), self.owner)
            print ("publish WINK3 to topic %s" % ( self.topic))
            self.c.publish(("%s" % self.topic), "WINK3")

    def btn_b(self,pressed):
        pass
    def btn_up(self,pressed):
        pass
    def btn_down(self,pressed):
        pass
    def btn_left(self,pressed):
        pass
    def btn_right(self,pressed):
        pass
    def btn_start(self,pressed):
        pass

    def __init__(self, font="fixed_10x20",server='mqtt.devlol.org',topic='devlol/h19/mainroom/winkekatze'):
        self.cat =    ['   |\_/|   ', '   (. .)   ', '    =w=  (\ ', '  /  ^  \// ', '  (|| ||)  ', '  ,""_""_ .']
        self.catdown =['   |\_/|   ', '   (. .)   ', '    =w=    ', '  /  ^  \\\\  ', '  (|| ||)\\', '  ,""_""_(/.']
        self.font = font
        self.clientname = 'SHA2017Badge' + str(ubinascii.hexlify(uos.urandom(5)))
        self.server = server
        self.topic = topic
        self.clients = 0
        self.version = 32
        self.nick = ''
        self.nick1 = ''
        self.nick2 = ''
        self.nick3 = ''
        self.nick4 = ''
        self.motd = 'Alle 5 Minuten verliebt sich ein Hacker ueber die WinkekatzenApp'

        badge.init()
        badge.leds_enable()
        #workaround for emulator
        try:
            self.owner = badge.nvs_get_str("owner","name","anonycat")
        except:
            self.owner ="anonycat"
            
        self.statustopic = ("%s/%s/%s" %(self.topic, 'clientstatus', self.owner))

        ugfx.init()
        wifi.init()
        while not wifi.sta_if.isconnected():
            time.sleep(1)
            print ("waiting for wifi")
            pass

        print ("connecting to mqtt server:%s  clientname:%s" %(self.server,self.clientname))
        self.c = MQTTClient(self.clientname,self.server)
        self.c.set_callback(self.sub_cb)
        self.c.set_last_will(self.statustopic, 'OFFLINE')
        self.c.connect()
        self.c.subscribe("%s/nick" % self.topic)
        self.c.subscribe("%s/motd" % self.topic)
        self.c.subscribe("%s/num_clients" % self.topic)
        self.c.publish(self.statustopic, str(self.version), retain=True)

        ugfx.clear(ugfx.BLACK)
        ugfx.flush
        ugfx.clear(ugfx.WHITE)
        ugfx.flush

        ugfx.input_init()
        ugfx.input_attach(ugfx.JOY_UP,lambda pressed: self.btn_up(pressed))
        ugfx.input_attach(ugfx.JOY_DOWN,lambda pressed: self.btn_down(pressed))
        ugfx.input_attach(ugfx.JOY_LEFT,lambda pressed: self.btn_left(pressed))
        ugfx.input_attach(ugfx.JOY_RIGHT,lambda pressed: self.btn_right(pressed))
        ugfx.input_attach(ugfx.BTN_SELECT,lambda pressed: self.btn_select(pressed))
        ugfx.input_attach(ugfx.BTN_START,lambda pressed: self.btn_start(pressed))
        ugfx.input_attach(ugfx.BTN_A,lambda pressed: self.btn_a(pressed))
        ugfx.input_attach(ugfx.BTN_B,lambda pressed: self.btn_b(pressed))

        self.draw_cat()
        last_status_update = time.time()
        status_update_interval = 60 
        while True:
            time.sleep(0.5)
            self.c.check_msg()
            if (time.time() > last_status_update + status_update_interval):
              last_status_update = time.time()
              self.c.publish(self.statustopic, str(self.version), retain=True)

wk = WinkeKatze()