"""I provide a simple bit viewer specialized for AMMOS files."""

import tkinter as tk
from PIL import Image, ImageTk
# from random import randbytes
import bitstring

from ammosreader.AmmosAudioReader import AmmosAudioReader


class MainApplication(tk.Frame):
    """I implement a simple bit viewer specialized for AMMOS files."""

    def __init__(self, parent):
        """I create the application window."""
        super().__init__(parent)

        self.parent = parent
        self.file_name = "../sample_data/audio_data_sample.bin"
        self.ammos_container = AmmosAudioReader(self.file_name).read_all_frames_left()
        self.file = open(self.file_name, 'rb')
        self.bytes = self.file.read(-1)
        self.cycle = tk.IntVar()
        self.cycle.set(self.ammos_container.unique_frame_sizes()[0])
        self.cache = tk.IntVar()
        self.cache.set(500)
        self.canvas_size = (800, 600)
        self.offset = tk.IntVar()
        self.offset.set(0)
        self.buildup()

    def buildup(self):
        """I build up the initial user interface."""
        self.parent.title("File name:" + self.file_name + " Size:" + str(len(self.bytes)))
        self.pack(fill="both", expand=True)
        self.default_button_width = 10
        image_frame = tk.Frame(self)
        image_frame.pack(side=tk.LEFT)
        self.canvas = tk.Canvas(image_frame, bg="#000000", width=self.canvas_size[0], height=self.canvas_size[1])
        self.canvas.pack()
        pil_image = Image.frombytes("1", self.canvas_size, self.current_bytes())
        self.image = ImageTk.PhotoImage(pil_image)
        # pil_image.show()
        button_frame = tk.Frame(self)
        self.image_id = self.canvas.create_image(0, 0, anchor='nw', image=self.image)
        button_frame.pack(side="right")

        tk.Label(button_frame, text='Cycle in bytes').pack(side=tk.TOP)
        self.cycle_entry = tk.Entry(button_frame, text=self.cycle)
        self.cycle_entry.pack(side=tk.TOP)

        tk.Label(button_frame, text='Cache in Megabytes').pack(side=tk.TOP)
        self.cache_entry = tk.Entry(button_frame, text=self.cache)
        self.cache_entry.pack(side=tk.TOP)

        tk.Label(button_frame, text='Offset in bytes').pack(side=tk.TOP)
        self.offset_entry = tk.Entry(button_frame, text=self.offset)
        self.offset_entry.pack(side=tk.TOP)

        tk.Button(button_frame,
                  text="Update",
                  width=self.default_button_width,
                  command=self.update_canvas).pack(side=tk.TOP, fill=tk.BOTH, expand=True)

        tk.Button(
            button_frame,
            text="Load file",
            width=self.default_button_width,
            command=self.load_file).pack(side="top", fill="both", expand=True)

        tk.Button(
            button_frame,
            text="Quit",
            width=self.default_button_width,
            command=self.quit).pack(side="top", fill="both", expand=True)

    def current_bytes(self):
        """I return the current bytes to display in the canvas."""
        if self.offset.get() % 8 == 0:
            return b"".join([self.bytes[each: each+self.canvas_size[0]] for each in range(self.offset.get(),
                                                                                          len(self.bytes),
                                                                                          self.cycle.get())])
        bits = bitstring.BitArray(self.bytes)
        new_bytes = bits[self.offset.get()*8:].tobytes()
        return b"".join([new_bytes[each: each+self.canvas_size[0]] for each in range(0,
                                                                                     len(new_bytes),
                                                                                     self.cycle.get())])

    def update_canvas(self):
        """I update the canvas."""
        self.image = ImageTk.PhotoImage(Image.frombytes("L", self.canvas_size, self.current_bytes()))
        self.canvas.itemconfig(self.image_id, image=self.image)

    def load_file(self):
        """I load a binary ammos file."""
        pass

    def quit(self):
        """I quit the application."""
        self.parent.destroy()


if __name__ == '__main__':
    root = tk.Tk()
    root.geometry("1920x1200")

    app = MainApplication(root)

    root.mainloop()
