#!/usr/bin/env python3

import setproctitle
import sys
from functools import lru_cache
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GLib, GdkPixbuf, Gio

class Main(object):

    def __init__(self):

        self.window_x = 0
        self.window_y = 0
        self.w = Gtk.Window.new(Gtk.WindowType.TOPLEVEL)
        self.w.set_size_request(300, 300)
        self.w.set_title("Magnus")
        self.w.set_decorated(False)
        self.w.connect("destroy", lambda a: Gtk.main_quit())
        self.w.connect("configure-event", self.window_configure)
        self.img = Gtk.Image()
        scrolled_window = Gtk.ScrolledWindow()
        scrolled_window.add(self.img)
        self.w.add(scrolled_window)
        self.w.show_all()
        sys.stdout.write('%d\n' % self.w.get_window().get_xid())
        sys.stdout.flush()
        GLib.timeout_add(250, self.poll)
        Gtk.main()

    def poll(self, *args):

        loc = self.w.get_size()
        width = loc.width
        height = loc.height
        (screen, x, y) = Gdk.Display.get_default().get_default_seat().get_pointer().get_position()

        if (x > self.window_x and x <= (self.window_x + width + 0) and y > self.window_y and y <= (self.window_y + height + 0)):

            white = self.get_white_pixbuf(width, height)
            self.img.set_from_pixbuf(white)

        else:

            root = Gdk.get_default_root_window()
            scaled_width = width // 2
            scaled_height = height // 2
            scaled_xoff = scaled_width // 2
            scaled_yoff = scaled_height // 2
            screenshot = Gdk.pixbuf_get_from_window(root, x - scaled_xoff, y - scaled_yoff, scaled_width, scaled_height)
            scaled_pb = screenshot.scale_simple(width, height, GdkPixbuf.InterpType.NEAREST)
            self.img.set_from_pixbuf(scaled_pb)

        return True

    @lru_cache()
    def makesquares(self, overall_width, overall_height, square_size, value_on, value_off):

        on_sq = list(value_on) * square_size
        off_sq = list(value_off) * square_size
        on_row = []
        off_row = []

        while len(on_row) < overall_width * len(value_on):

            on_row += on_sq
            on_row += off_sq
            off_row += off_sq
            off_row += on_sq

        on_row = on_row[:overall_width * len(value_on)]
        off_row = off_row[:overall_width * len(value_on)]
        on_sq_row = on_row * square_size
        off_sq_row = off_row * square_size
        overall = []
        count = 0

        while len(overall) < overall_width * overall_height * len(value_on):

            overall += on_sq_row
            overall += off_sq_row
            count += 2

        overall = overall[:overall_width * overall_height * len(value_on)]

        return overall

    @lru_cache()
    def get_white_pixbuf(self, width, height):

        square_size = 16
        light = (153, 153, 153, 255)
        dark = (102, 102, 102, 255)
        whole = self.makesquares(width, height, square_size, light, dark)
        arr = GLib.Bytes.new(whole)

        return GdkPixbuf.Pixbuf.new_from_bytes(arr, GdkPixbuf.Colorspace.RGB, True, 8, width, height, width * len(light))

    def window_configure(self, window, ev):

        self.window_x = ev.x
        self.window_y = ev.y

if __name__ == "__main__":

    setproctitle.setproctitle('magnus')
    Main()
