#!/usr/bin/env python
import sys
if sys.version_info[0] >= 3:
    import PySimpleGUI as sg
else:
    import PySimpleGUI27 as sg
import os
from sys import exit as exit
from  PIL import Image
import io
import numpy as np


thumbnails = {}

ROWS = 8
COLUMNS = 8
sg.SetOptions(border_width=0)

# Get the folder containing the images from the user
# folder = 'A:/TEMP/pdfs'

folder = sg.PopupGetFolder('Image folder to open')
if folder is None:
    sg.PopupCancel('Cancelling')
    exit(0)
def image_file_to_bytes(filename, size):
    try:
        image = Image.open(filename)
        image.thumbnail(size, Image.ANTIALIAS)
        bio = io.BytesIO()  # a binary memory resident stream
        image.save(bio, format='PNG')  # save image as png to it
        imgbytes = bio.getvalue()
    except:
        imgbytes = None
    return imgbytes

def set_image_to_blank(key):
    img = Image.new('RGB', (100, 100), (255, 255, 255))
    img.thumbnail((1, 1), Image.ANTIALIAS)
    bio = io.BytesIO()
    img.save(bio, format='PNG')
    imgbytes = bio.getvalue()
    window.FindElement(key).Update(image_data=imgbytes)

# get list of PNG files in folder

png_files = [os.path.join(folder, f) for f in os.listdir(folder) if '.png' in f]
filenames_only = [f for f in os.listdir(folder) if '.png' in f]

if len(png_files) == 0:
    sg.Popup('No PNG images in folder')
    exit(0)

# define menu layout
menu = [['&File', ['&Open Folder', 'E&xit']], ['&Help', ['&About',]]]

buttons = []
for display_index in range(ROWS):
    row = []
    for j in range(COLUMNS):
        row.append(sg.Button('',border_width=0,button_color=sg.COLOR_SYSTEM_DEFAULT, key=(display_index, j)))
    buttons.append(row)

col_buttons = [[]]

# define layout, show and read the window
col = [[sg.Text(png_files[0], size=(80, 3), key='filename')],
          [sg.Image(data=image_file_to_bytes(png_files[0], (500,500)), key='image')],]

layout = [[sg.Menu(menu)], [sg.Column(buttons), sg.Column([[sg.Slider((len(png_files),0),default_value=0,size=(38,20),orientation='v', key='_slider_', change_submits=True)]]), sg.Column(col)]]
window = sg.Window('Image Browser',
                   return_keyboard_events=True,
                   use_default_focus=False ).Layout(layout).Finalize()

# -------========= Event Loop =========--------
display_index=0
while True:
    for x in range(ROWS):               # update thumbnails
        for y in range(COLUMNS):
            cur_index = display_index + (x * 4) + y
            if cur_index < len(png_files):
                filename = png_files[cur_index]
                if filename not in thumbnails:
                    imgbytes = image_file_to_bytes(filename, (100,100))
                    thumbnails[filename] = imgbytes
                else:
                    imgbytes = thumbnails[filename]
                button_elem = window.FindElement(key=(x,y))
                button_elem.Update(image_data=imgbytes)
            else:
                set_image_to_blank((x,y))

    event, values = window.Read()
    display_index = values['_slider_']
    # --------------------- Button & Keyboard ---------------------
    if event in (None, 'Exit'):
        break
    elif event in ('MouseWheel:Down', 'Down:40',) and display_index < len(png_files)-1:
        display_index += 4
    elif event in ('MouseWheel:Up', 'Up:38',) and display_index > 0:
        display_index -= 4
    elif event in ('Prior:33', 'Prev'):
        display_index -= 16
    elif event in ('Next:34', 'Next'):
        display_index += 16

    window.FindElement('_slider_').Update(display_index)
    # ----------------- Menu choices -----------------
    if event == 'Open Folder':
        newfolder = sg.PopupGetFolder('New folder', no_window=True)
        if newfolder is None:
            continue
        folder = newfolder
        png_files = [os.path.join(folder, f) for f in os.listdir(folder) if '.png' in f]
        filenames_only = [f for f in os.listdir(folder) if '.png' in f]
        display_index = 0
        thumbnail = {}
        for j in range(ROWS):
            for i in range(COLUMNS):
                set_image_to_blank((i,j))
    elif event == 'About':
        sg.Popup('Demo PNG Viewer Program', 'Please give PySimpleGUI a try!')
    elif type(event) is tuple:
        x, y = event
        image_index = display_index + (x * 4) + y
        if image_index < len(png_files):
            filename = png_files[image_index]
            imgbytes = image_file_to_bytes(filename, (500, 500))
            window.FindElement('image').Update(data=imgbytes)
            window.FindElement('filename').Update(filename)
