from __future__ import print_function, absolute_import, division

print('receiver start')
import sys

import socket
import traceback

from path import Path

from rgbmatrix import RGBMatrix, RGBMatrixOptions
from rgbmatrix import graphics

class Renderer(object):
    def __init__(self):
        o = RGBMatrixOptions()
        o.chain_length = 4
        self.matrix = RGBMatrix(options=o)
        self.canvas = self.matrix.CreateFrameCanvas()

    def swap(self):
        self.canvas = self.matrix.SwapOnVSync(self.canvas)
        self.canvas.Clear()

    def print_text(self, text):
        graphics.DrawText(self.canvas, fonts['10x20'], 0, 20, textColor, text)
        self.swap()

    def scroll_text(self, text, loop=1):
        pos = self.canvas.width
        i = 1
        while True:
            len = graphics.DrawText(self.canvas, fonts['10x20'], pos, 20, textColor, text)
            pos -= 1
            if (pos + len < 0):
                pos = self.canvas.width
                i += 1
            if i > loop:
                break

            time.sleep(0.02)
            self.swap()


    def fit_text(self, text, width=128):
        ff = reversed(sorted(fonts.items(), key=lambda e: int(e[0].split('x')[0])))
        temp_canvas = self.matrix.CreateFrameCanvas()
        for name, font in ff:
            w = graphics.DrawText(temp_canvas, font, 0, -100, textColor, text)
            if w < width:
                break
        else:
            print('str len %s exceeds space' % w)

        graphics.DrawText(self.canvas, font, 0, 20, textColor, text)
        self.swap()


try:
    fonts = {}
    for f in Path('/matrix/fonts').files('*.bdf'):
        if not f.namebase.split('x')[0].isdigit() or not f.namebase[-1].isdigit():
            continue
        fo = graphics.Font()
        fo.LoadFont(f)
        fonts[f.namebase] = fo

    textColor = graphics.Color(96, 128, 255)
    r = Renderer()

    # Create a TCP/IP socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # Bind the socket to the port
    server_address = ('0.0.0.0', 10000)
    print('starting up on %s port %s' % server_address)
    sock.bind(server_address)
    r.fit_text('Matrix ready.')

    r.fit_text('111')


    while True:
        print('waiting to receive message')
        data, address = sock.recvfrom(4096)

        print('received %s bytes from %s' % (len(data), address))
        method = ord(data[0])
        data = data[1:]

        if method == 0:
            r.print_text(data.decode('utf-8'))
        elif method == 1:
            r.scroll_text(data.decode('utf-8'))
        elif method == 2:
            r.fit_text(data.decode('utf-8'))

except Exception:
    print(traceback.format_exc())

finally:
    print('receiver exit')
