from giara.constants import RESOURCE_PREFIX
from giara.confManager import ConfManager
from giara.path_utils import is_image
from giara.accel_manager import add_accelerators
from os.path import isfile
from gi.repository import Gtk, GLib, Gio
from giara.common_functions import show_hide_gallery_btns


class ImageViewer(Gtk.Window):
    WINSIZE_KEY = 'imgviewer_windowsize'
    STYLE = '''
        .image_viewer {
            background-color: rgba(0, 0, 0, .7);
            color: white;
        }

        .image_viewer button {
            color: white;
            background-color: rgba(0, 0, 0, .3);
            transition: background-color .2s ease-in-out;
        }

        .image_viewer button:hover {
            background-color: rgba(0, 0, 0, .6);
        }

        .image_viewer, .image_viewer button {
            background-image: none;
            border: none;
            box-shadow: none;
        }

        .image_viewer windowhandle {
            background-color: rgba(0, 0, 0, 0);
        }

        .image_viewer .close_btn {
            background-color: rgba(0, 0, 0, .3);
        }

        .image_viewer .close_btn image {
            padding: 25px;
        }

        .image_viewer .nav_btn {
            border-radius: 0;
        }
    '''
    style_loaded = False

    def __init__(self, parent_win, pictures=[]):
        super().__init__(fullscreened=True)
        self.parent_win = parent_win
        self.pictures = pictures
        self.children = list()
        self.confman = ConfManager()
        self.builder = Gtk.Builder.new_from_resource(
            f'{RESOURCE_PREFIX}/ui/image_viewer_window.ui'
        )
        self.main_box = self.builder.get_object('main_box')
        self.carousel = self.builder.get_object('carousel')
        self.close_btn = self.builder.get_object('close_btn')
        self.prev_btn = self.builder.get_object('prev_btn')
        self.next_btn = self.builder.get_object('next_btn')

        self.prev_btn.connect('clicked', self.go_prev)
        self.next_btn.connect('clicked', self.go_next)
        self.carousel.connect(
            'page-changed', lambda *args: self.show_hide_gallery_btns()
        )

        if len(self.pictures) <= 1:
            for b in (self.prev_btn, self.next_btn):
                b.set_visible(False)

        self.open_externally_btn = self.builder.get_object(
            'open_externally_btn'
        )

        for pic in self.pictures:
            if not (is_image(pic) and isfile(pic)):
                print(f'Error showing picture {pic}')
                continue
            picture_w = Gtk.Picture(vexpand=True, hexpand=True)
            picture_w.set_filename(pic)
            self.carousel.append(picture_w)
            self.children.append(picture_w)
        self.show_hide_gallery_btns()

        self.close_btn.connect('clicked', lambda *args: self.close())
        self.connect('close-request', self.on_destroy)
        self.set_title('')

        self.open_externally_btn.connect('clicked', self.open_externally)

        self.set_child(self.main_box)
        self.load_style()

        add_accelerators(self, [{
            'combo': 'Escape',
            'cb': lambda *args: self.close()
        }])

    def can_navigate(self):
        pos = self.carousel.get_position()
        return pos - int(pos) <= 0

    def go_prev(self, *args):
        if self.can_navigate():
            pos = self.carousel.get_position()
            if pos <= 0:
                return
            self.carousel.scroll_to(self.children[int(pos)-1], True)
            self.show_hide_gallery_btns(int(self.carousel.get_position()) - 1)

    def go_next(self, *args):
        if self.can_navigate():
            pos = self.carousel.get_position()
            if pos+1 >= len(self.children):
                return
            self.carousel.scroll_to(self.children[int(pos)+1], True)
            self.show_hide_gallery_btns(int(self.carousel.get_position()) + 1)

    def show_hide_gallery_btns(self, pos=None):
        if pos is None:
            pos = int(self.carousel.get_position())
        show_hide_gallery_btns(
            pos,
            len(self.pictures),
            self.prev_btn,
            self.next_btn
        )

    def open_externally(self, *args):
        pic = self.pictures[int(self.carousel.get_position())]
        Gio.AppInfo.launch_default_for_uri(
            GLib.filename_to_uri(pic)
        )
        self.close()

    def load_style(self):
        # Why not global style? As of writing this, some selectors don't work,
        # namely button:hover. This is a hack but it works.
        if not ImageViewer.style_loaded:
            provider = Gtk.CssProvider()
            provider.load_from_data(self.STYLE.encode())
            Gtk.StyleContext().add_provider_for_display(
                self.parent_win.get_display(), provider,
                Gtk.STYLE_PROVIDER_PRIORITY_USER
            )
            ImageViewer.style_loaded = True
        self.get_style_context().add_class('image_viewer')

    def on_destroy(self, *args):
        alloc = self.get_allocation()
        self.confman.conf[self.WINSIZE_KEY] = {
            'width': alloc.width,
            'height': alloc.height
        }
        self.hide()
        self.confman.save_conf()
