import logging

import cv2
import numpy as np
import zmq

from flandre.config import C
from flandre.nodes.Node import Node
from flandre.utils.Msg import BMMsg, SetWindowVisibleMsg, RfMatMsg
from flandre.utils.RfMat import RfMat

logger = logging.getLogger(__name__)


class ImageCV(Node):
    topics = [BMMsg, SetWindowVisibleMsg, RfMatMsg]

    def __init__(self, level=logging.INFO):
        super().__init__(level=level)
        self.show = True
        self.buffer = np.zeros((C.video_height, C.video_width, 3), dtype=np.uint8) + 128

    def loop(self):
        cv2.namedWindow('image', cv2.WINDOW_NORMAL)
        while True:
            socks = dict(self.c.poller.poll(0.001))
            if self.c.sub in socks and socks[self.c.sub] == zmq.POLLIN:
                msg = self.recv()
                if isinstance(msg, BMMsg):
                    b = np.frombuffer(msg.data, dtype=np.uint8)
                    b = np.reshape(b, (C.video_height, C.video_width, 4))
                    self.buffer = b
                elif isinstance(msg, RfMatMsg):
                    rfmat: RfMat = msg.rfmat
                    b = rfmat.pseudo_color().m
                    self.buffer = b
                elif isinstance(msg, SetWindowVisibleMsg):
                    if msg.name == 'bscan' and msg.sender != 'cv':
                        self.show = msg.value
                        if msg.value:
                            cv2.namedWindow('image', cv2.WINDOW_NORMAL)
                        else:
                            cv2.destroyWindow('image')
            if self.show:
                if cv2.getWindowProperty('image', cv2.WND_PROP_VISIBLE) < 1:
                    self.show = False
                    self.send(SetWindowVisibleMsg('cv', 'bscan', False))
                    cv2.destroyWindow('image')
                    continue
                cv2.imshow('image', self.buffer)
                cv2.waitKey(1)
