import usocket as socket
import wifi
import time
import badge
import ugfx
import dialogs
import appglue
import easydraw
import tasks.powermanagement as pm
import ure

badge.init()
ugfx.init()
wifi.init()

# only 9 lines; reserve line 1 for status
messages = ['','','','','','','','','']

while not wifi.sta_if.isconnected():
    time.sleep(0.1)

HOST = "chat.freenode.net"
PORT = 6667

NICK = badge.nvs_get_str('owner', 'name', 'Hacker1337')+"_badge"
REALNAME = "IRC slacker"

CHANNEL = badge.nvs_get_str("irc", "channel", "ACKspaceBots")

ugfx.clear(ugfx.WHITE)
ugfx.string(0,0,REALNAME,"Roboto_BlackItalic24",ugfx.BLACK)
ugfx.flush()

time.sleep(2)

chan_change = 0
def select_button(pressed):
    global chan_change
    if not pressed:
        print( "change channel" )
        chan_change = 1

def changechan():
    global CHANNEL
    chan = False
    try:
        chan = dialogs.prompt_text("Enter channel", CHANNEL)
    except:
        chan = False
    if chan is not False and chan != CHANNEL:
        badge.nvs_set_str("irc", "channel", chan)
        CHANNEL = chan  
        return 1
    return 0

def exit_app():
    global s
    # Ignore closed connection
    try:
        # Note: some IRC servers only will display your message after being connected for about 5 minutes
        s.send(bytes("QUIT :%s \r\n" % "Pressed Start", "UTF-8"))
        s.close()
    except:
        pass
    appglue.home()

def press_a(pressed):
    global s
    if pressed:
        s.send(bytes("PRIVMSG #%s :%s\r\n" % (CHANNEL, "button A: affirmative"), "UTF-8"))
        addMessage( "%s: button A: affirmative" % NICK )

def press_b(pressed):
    global s
    if pressed:
        s.send(bytes("PRIVMSG #%s :%s\r\n" % (CHANNEL, "button B: negative"), "UTF-8"))
        addMessage( "%s: button B: negative" % NICK )

def alert(repeat):
    for r in range(repeat):
        badge.leds_send_data(''.join(['\0\0\0\50' for i in range(6)]))
        badge.vibrator_activate(0b11)
        badge.leds_send_data(''.join(['\0\0\0\0' for i in range(6)]))
        time.sleep(0.5)

def addMessage( message=False ):
    global messages
    global ugfx
    if ( message ):
        messages = messages[1:] + [message]

    ugfx.clear(ugfx.WHITE)
    for i, m in enumerate(messages):
        ugfx.string(0,20+i*12,m,"Roboto_Regular12",ugfx.BLACK)

    # Stolen from Show Nickname 
    enabled = badge.nvs_get_u8("shownick","enable", 0)
    if enabled:
        #nick = badge.nvs_get_str("owner", "name", '')
        #ugfx.string_box(0,45,296,38, nick, "PermanentMarker36", ugfx.BLACK, ugfx.justifyCenter)
        easydraw.nickname()

    # TODO: use virtualtimers to update the battery symbol more regularly
    # TODO: blank part where battery and voltage are shown
    # Calibrate battery voltage drop
    if badge.battery_charge_status() == False and pm.usb_attached() and badge.battery_volt_sense() > 2500:
        badge.nvs_set_u16('splash', 'bat.volt.drop', 5200 - badge.battery_volt_sense()) # mV
        print('Set vDrop to: ' + str(4200 - badge.battery_volt_sense()))
    vDrop = badge.nvs_get_u16('splash', 'bat.volt.drop', 1000) - 1000 # mV

    on_usb = pm.usb_attached()
    vBatt = badge.battery_volt_sense()
    vBatt += vDrop
    charging = badge.battery_charge_status()

    easydraw.battery(on_usb, vBatt, charging)
    if vBatt>500:
        ugfx.string(52, 0, str(round(vBatt/1000, 1)) + 'v','Roboto_Regular12',ugfx.BLACK)

    ugfx.flush()

if CHANNEL != "":
    changechan()

ugfx.input_init()

# TODO: make function for attaching events
ugfx.input_attach(ugfx.BTN_SELECT, lambda pressed: select_button(pressed))
ugfx.input_attach(ugfx.BTN_START, lambda pressed: exit_app())
ugfx.input_attach(ugfx.BTN_A, lambda pressed: press_a(pressed))
ugfx.input_attach(ugfx.BTN_B, lambda pressed: press_b(pressed))

addMessage( "Connecting to %s:%s #%s" % (HOST,PORT,CHANNEL) )

s = socket.socket()
s.connect((HOST, PORT))

s.send(bytes("NICK %s\r\n" % NICK, "UTF-8"))
s.send(bytes("USER %s 0 * :%s\r\n" % (NICK, REALNAME), "UTF-8"))
s.send(bytes("JOIN #%s\r\n" % CHANNEL, "UTF-8"));
s.setblocking(False)

while 1:
    if chan_change:
        print( "change channel in loop" )
        chan_change = 0
        chan = CHANNEL
        if changechan():
            s.send(bytes("JOIN #%s\r\n" % CHANNEL, "UTF-8"));
            s.send(bytes("PART #%s\r\n" % chan, "UTF-8"));
        addMessage()
        # Reapply button binding (they get lost by calling dialog logic?)
        ugfx.input_attach(ugfx.BTN_SELECT, lambda pressed: select_button(pressed))
        ugfx.input_attach(ugfx.BTN_START, lambda pressed: exit_app())
        ugfx.input_attach(ugfx.BTN_A, lambda pressed: press_a(pressed))
        ugfx.input_attach(ugfx.BTN_B, lambda pressed: press_b(pressed))

    line = s.readline()
    if line is not None:
        parts = line.rstrip().split()
        
        if parts:
            if(parts[0] == b"PING"):
                s.send(bytes("PONG %s\r\n" % line[1], "UTF-8"))

            if(parts[1] == b"PRIVMSG"):

                # Remove heading colon
                msg = b' '.join(parts[3:])
                rnick = line.split(b'!')[0][1:]
                command = ure.match(":\x01([^ ]+) (.*)\x01[\r\n]*", msg)
                if not command:
                    addMessage( rnick + b": " + msg[1:] )
                else:
                    ctcp = command.group(1).split()
                    if ctcp[0] == b"ACTION":
                        addMessage( b" * " + rnick + b" " + command.group(2) )
                    #elif ctcp[0] == b"VERSION":
                    #TIME PING DCC

                if NICK in msg:
                    alert(2)

            if(parts[1] == b"JOIN"):
                rnick = line.split(b'!')[0][1:]

                if NICK in rnick:
                    addMessage( b"Joined " + parts[2] )

            # End of MOTD
            if(parts[1] == b"376"):
                    addMessage( "Connected" )

            # Nickname already in use
            if(parts[1] == b"433"):
                NICK = NICK + "^"
                s.send(bytes("NICK %s\r\n" % NICK, "UTF-8"))
                s.send(bytes("USER %s 0 * :%s\r\n" % (NICK, REALNAME), "UTF-8"))
                s.send(bytes("JOIN #%s\r\n" % CHANNEL, "UTF-8"));

            print(line)