import multiprocessing
import cv2
import pathlib
import numpy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.behaviors.button import ButtonBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.graphics.texture import Texture

bg = numpy.array([27, 27, 27])

colors = [
    (numpy.array([213, 182,  93]), numpy.array([255, 255, 255])),
    (numpy.array([ 78, 189, 207]), numpy.array([255, 255, 255])),
    (numpy.array([ 83, 131,  63]), numpy.array([255, 255, 255])),
    (numpy.array([203,  76,  62]), numpy.array([255, 255, 255]))
]

raw_dir = pathlib.Path('raw')
icons_dir = pathlib.Path('icons')


def make_img(img, c):
    rc = c[0]
    gc = c[1]
    for row in img:
        for i in range(len(row)):
            pix = row[i]
            rv = pix[0] / 255
            gv = pix[1] / 255
            row[i] = rv * rc + gv * gc + (1 - rv - gv) * bg

    return cv2.flip(img, 0)


class Im(ButtonBehavior, Image):
    def __init__(self, color):
        ButtonBehavior.__init__(self)
        Image.__init__(self, size=(256, 256), size_hint=(256, 256))
        self.name = None
        self.mc = color

    def update(self, img, name):
        self.name = name
        tex: Texture = Texture.create(size=(img.shape[1], img.shape[0]), colorfmt='rgb')
        tex.blit_buffer(img.tobytes(), colorfmt='rgb', bufferfmt='ubyte')
        self.texture = tex

    def on_press(self):
        self.texture.save(f'icons/{self.name}')
        app.update()


class MainApp(App):
    def build(self):
        self.imgs = pathlib.Path('raw').glob('*.png')
        self.img: pathlib.Path = None
        self.label = Label(font_size=48)
        self.im = [Im(c) for c in colors]
        self.pool = multiprocessing.Pool(4)
        gl = GridLayout(cols=2)
        for i in self.im:
            gl.add_widget(i)
        bl = BoxLayout(orientation='vertical')
        bl.add_widget(self.label)
        bl.add_widget(gl)
        self.update()
        return bl

    def update(self):
        self.img: pathlib.Path = next(self.imgs)
        if self.img is None:
            exit(0)

        if (icons_dir / self.img.name).exists():
            self.update()
            return

        self.label.text = str(self.img.name)[:-4]

        i = cv2.imread(str(self.img))
        i = cv2.cvtColor(i, cv2.COLOR_BGR2RGB)

        print('updating')
        imgs = self.pool.starmap(make_img, [
            (i, colors[0]),
            (i, colors[1]),
            (i, colors[2]),
            (i, colors[3])
        ])

        for j in range(4):
            self.im[j].update(imgs[j], self.img.name)


app = MainApp()

if __name__ == '__main__':
    icons_dir.mkdir(exist_ok=True)
    app.run()

