#Image Viewer
#Shift+U: Open Image Viewer
#2016 1/22 v6.99

screen _image_selecter(default=""):
    default filter_string = default
    default filter_string_cache = default
    key "game_menu" action Return("")
    zorder 20
    frame:
        style_group "image_selecter"
        vbox:
            label _("Type a image name") style "image_selecter_input"
            label _("Tab: completion") style "image_selecter_input"
            input value ScreenVariableInputValue("filter_string", default=True, returnable=True) copypaste True style "image_selecter_input" id "input_filter_strings"
            $filtered_list = _viewers.filter_image_name(filter_string)
            viewport:
                mousewheel True
                scrollbars "vertical"
                vbox:
                    for image_name in filtered_list:
                        textbutton image_name action _viewers.Add_tag_or_Return(tuple(image_name.split())) hovered _viewers.ShowImage(tuple(image_name.split())) unhovered Function(renpy.hide, "preview", layer="screens")
            textbutton _("clipboard") action [SensitiveIf(filter_string), Function(_viewers.put_clipboard_text, filter_string)] xalign 1.0 idle_background None insensitive_background None
    if filter_string_cache != filter_string:
        if len(filtered_list) == 1:
            if "preview" not in renpy.get_showing_tags("screens"):
                $filter_string_cache = filter_string
                $_viewers.ShowImage(tuple(filtered_list[0].split()))()
        elif "preview" in renpy.get_showing_tags("screens"):
            $filter_string_cache = filter_string
            $_viewers._image_viewer_hide()
    key "K_TAB" action Function(_viewers.tag_completion, filter_string, filtered_list)

init:
    style image_selecter_frame:
        background "#0006"
        xmaximum 400
        yfill True
    style image_selecter_viewport:
        ymaximum 600
    style image_selecter_input:
        outlines [ (absolute(1), "#000", absolute(0), absolute(0)) ]
    style image_selecter_button:
        size_group "image_selecter"
        idle_background None
    style image_selecter_button_text:
        color "#CCC"
        hover_underline True
        selected_color "#FFF"
        insensitive_color "#888"
        outlines [ (absolute(1), "#000", absolute(0), absolute(0)) ]
        xalign .0

init -999 python in _viewers:
    def open_image_viewer():
        if not renpy.config.developer:
            return
        _skipping_org = renpy.store._skipping
        renpy.store._skipping = False
        renpy.invoke_in_new_context(renpy.call_screen, "_image_selecter")
        renpy.store._skipping = _skipping_org

    def filter_image_name(filter_string):
        filtered_list = []
        filter_elements = filter_string.split()
        if filter_elements:
            for name in get_image_name_candidates():
                if name[0].startswith(filter_elements[0]):
                    if len(filter_elements) == 1:
                        filtered_list.append(" ".join(name))
                    else:
                        for e in filter_elements[1:]:
                            if e in name:
                                continue
                            else:
                                for e2 in name[1:]:
                                    if e2.startswith(e):
                                        break
                                else:
                                    break
                                continue
                        else:
                            filtered_list.append(" ".join(name))
        else:
            filtered_list = list({name[0] for name in renpy.display.image.images})
        return filtered_list

    def put_clipboard_text(s):
        from pygame import scrap, locals
        scrap.put(locals.SCRAP_TEXT, s.encode("utf-8"))
        renpy.notify("'{}'\nis copied to clipboard".format(s))

    def tag_completion(filter_string, filtered_list):
        if filter_string and filter_string[-1] != " ":
            completed_string = filter_string.split()[-1]
            candidate = []
            if len(filter_string.split()) == 1:
                for es in filtered_list:
                    candidate.append(es.split()[0])
            else:
                for es in filtered_list:
                    for e in es.split()[1:]:
                        if e.startswith(completed_string):
                            candidate.append(e)

            if candidate:
                cs = renpy.current_screen()
                if len(candidate) > 1:
                    completed_candidate = candidate[0]
                    for c in candidate[1:]:
                        for i in range(len(completed_candidate)):
                            if i < len(c) and completed_candidate[i] != c[i]:
                                completed_candidate = completed_candidate[0:i]
                                break
                    cs.scope["filter_string"] += completed_candidate[len(completed_string):]
                else:
                    completed_candidate = candidate[0]
                    cs.scope["filter_string"] += completed_candidate[len(completed_string):] + " "
                input = renpy.get_displayable("_image_selecter", "input_filter_strings")
                input.caret_pos = len(cs.scope["filter_string"])

    def _image_viewer_hide():
        renpy.hide("preview", layer="screens")
        renpy.restart_interaction()

init -1 python in _viewers:
    @renpy.pure
    class ShowImage(renpy.store.Action, renpy.store.DictEquality):
        def __init__(self, image_name_tuple):
            self.string = " ".join(image_name_tuple)
            self.check = None

        def __call__(self):
            if self.check is None:
                for n in get_image_name_candidates():
                    if set(n) == set(self.string.split()) and n[0] == self.string.split()[0]:
                        self.string = " ".join(n)
                        try:
                            for fn in renpy.display.image.images[n].predict_files():
                                if not renpy.loader.loadable(fn):
                                    self.check = False
                                    break
                            else:
                                self.check = True
                        except:
                            self.check = True #text displayable or Live2D
            try:
                if self.check:
                    renpy.show(self.string, at_list=[renpy.store.truecenter], layer="screens", tag="preview")
                else:
                    renpy.show("preview", what=renpy.text.text.Text("No files", color="#F00"), at_list=[renpy.store.truecenter], layer="screens")
            except:
                renpy.show("preview", what=renpy.text.text.Text("No files", color="#F00"), at_list=[renpy.store.truecenter], layer="screens")
            renpy.restart_interaction()


    @renpy.pure
    class Add_tag_or_Return(renpy.store.Action, renpy.store.DictEquality):
        def __init__(self, image_name_tuple):
            self.image_name_tuple = image_name_tuple
            self.string = " ".join(image_name_tuple)
            self.check = None

        def __call__(self):
            if self.check is None:
                for n in get_image_name_candidates():
                    if set(n) == set(self.string.split()) and n[0] == self.string.split()[0]:
                        self.string = " ".join(n)
                        try:
                            for fn in renpy.display.image.images[n].predict_files():
                                if not renpy.loader.loadable(fn):
                                    self.check = False
                                    break
                            else:
                                self.check = True
                        except:
                            self.check = False #text displayable or Live2D
            if self.check:
                if in_editor:
                    return self.image_name_tuple
                else:
                    put_clipboard_text(self.string)

            else:
                cs = renpy.current_screen()
                cs.scope["filter_string"] = self.string + " "
                input = renpy.get_displayable("_image_selecter", "input_filter_strings")
                input.caret_pos = len(cs.scope["filter_string"])
                renpy.restart_interaction()
