<commit_before>package main

import (
	"image"
	"io"
	"log"
	"os"

	"github.com/lucasb-eyer/go-colorful"
	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/model"
	"github.com/ninjasphere/sphere-go-led-controller/ui"
	"github.com/tarm/goserial"
)

type LedController struct {
	controlEnabled bool
	controlLayout  *ui.PaneLayout
	pairingLayout  *ui.PairingLayout
	conn           *ninja.Connection
	serial         io.ReadWriteCloser
	waiting        chan bool
}

func NewLedController(conn *ninja.Connection) (*LedController, error) {

	c := &serial.Config{Name: "/dev/tty.ledmatrix", Baud: 115200}
	s, err := serial.OpenPort(c)
	if err != nil {
		return nil, err
	}

	// Send a blank image to the led matrix
	write(image.NewRGBA(image.Rect(0, 0, 16, 16)), s)

	controller := &LedController{
		conn:          conn,
		pairingLayout: ui.NewPairingLayout(conn),
		serial:        s,
		waiting:       make(chan bool),
	}

	conn.MustExportService(controller, "$node/"+config.Serial()+"/led-controller", &model.ServiceAnnouncement{
		Schema: "/service/led-controller",
	})

	return controller, nil
}

func (c *LedController) start(enableControl bool) {
	c.controlEnabled = enableControl

	go func() {
		for {
			if c.controlEnabled {

				if c.controlLayout == nil {

					log.Println("before layout get")
					c.controlLayout = getPaneLayout(c.conn)
					log.Println("after layout get")
				}

				image, wake, err := c.controlLayout.Render()
				if err != nil {
					log.Fatal(err)
				}

				write(image, c.serial)

				if wake != nil {
					log.Println("Waiting as the UI is asleep")
					select {
					case <-wake:
						log.Println("UI woke up!")
					case <-c.waiting:
						log.Println("Got a command from rpc...")
					}
				}

			} else {

				image, err := c.pairingLayout.Render()
				if err != nil {
					log.Fatal(err)
				}
				write(image, c.serial)

				<-c.waiting

			}
		}
	}()
}

func (c *LedController) EnableControl() error {
	c.controlEnabled = true
	c.gotCommand()
	return nil
}

func (c *LedController) DisableControl() error {
	c.controlEnabled = false
	c.gotCommand()
	return nil
}

type PairingCodeRequest struct {
	Code        string `json:"code"`
	DisplayTime int    `json:"displayTime"`
}

func (c *LedController) DisplayPairingCode(req *PairingCodeRequest) error {
	c.controlEnabled = false
	c.pairingLayout.ShowCode(req.Code)
	c.gotCommand()
	return nil
}

type ColorRequest struct {<commit_msg>Fix to make animated icons work in pairing more<commit_after>package main

import (
	"image"
	"io"
	"log"
	"os"

	"github.com/lucasb-eyer/go-colorful"
	"github.com/ninjasphere/go-ninja/api"
	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/go-ninja/model"
	"github.com/ninjasphere/sphere-go-led-controller/ui"
	"github.com/tarm/goserial"
)

type LedController struct {
	controlEnabled bool
	controlLayout  *ui.PaneLayout
	pairingLayout  *ui.PairingLayout
	conn           *ninja.Connection
	serial         io.ReadWriteCloser
	waiting        chan bool
}

func NewLedController(conn *ninja.Connection) (*LedController, error) {

	c := &serial.Config{Name: "/dev/tty.ledmatrix", Baud: 115200}
	s, err := serial.OpenPort(c)
	if err != nil {
		return nil, err
	}

	// Send a blank image to the led matrix
	write(image.NewRGBA(image.Rect(0, 0, 16, 16)), s)

	controller := &LedController{
		conn:          conn,
		pairingLayout: ui.NewPairingLayout(conn),
		serial:        s,
		waiting:       make(chan bool),
	}

	conn.MustExportService(controller, "$node/"+config.Serial()+"/led-controller", &model.ServiceAnnouncement{
		Schema: "/service/led-controller",
	})

	return controller, nil
}

func (c *LedController) start(enableControl bool) {
	c.controlEnabled = enableControl

	go func() {
		for {
			if c.controlEnabled {

				if c.controlLayout == nil {

					log.Println("before layout get")
					c.controlLayout = getPaneLayout(c.conn)
					log.Println("after layout get")
				}

				image, wake, err := c.controlLayout.Render()
				if err != nil {
					log.Fatal(err)
				}

				write(image, c.serial)

				if wake != nil {
					log.Println("Waiting as the UI is asleep")
					select {
					case <-wake:
						log.Println("UI woke up!")
					case <-c.waiting:
						log.Println("Got a command from rpc...")
					}
				}

			} else {

				image, err := c.pairingLayout.Render()
				if err != nil {
					log.Fatal(err)
				}
				write(image, c.serial)

			}
		}
	}()
}

func (c *LedController) EnableControl() error {
	c.controlEnabled = true
	c.gotCommand()
	return nil
}

func (c *LedController) DisableControl() error {
	c.controlEnabled = false
	c.gotCommand()
	return nil
}

type PairingCodeRequest struct {
	Code        string `json:"code"`
	DisplayTime int    `json:"displayTime"`
}

func (c *LedController) DisplayPairingCode(req *PairingCodeRequest) error {
	c.controlEnabled = false
	c.pairingLayout.ShowCode(req.Code)
	c.gotCommand()
	return nil
}

type ColorRequest struct {
{'fraction_non_alphanumeric': 0.13184828416616495, 'fraction_numerical': 0.00481637567730283, 'mean_word_length': 3.1637426900584797, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6134567', 'n_tokens_mistral': 2041, 'n_tokens_neox': 1757, 'n_words': 387}