# This file is part of Gajim.
#
# Gajim is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation; version 3 only.
#
# Gajim is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.

import logging

from gi.repository import GLib

from gajim.common import app
from gajim.common.i18n import _

from . import gstreamer
from .util import get_builder

try:
    from gi.repository import Gst  # pylint: disable=ungrouped-imports
except Exception:
    pass


log = logging.getLogger('gajim.gui.preview')


class VideoPreview:
    def __init__(self):

        self._ui = get_builder('video_preview.ui')

        self._active = False

        self._av_pipeline = None
        self._av_src = None
        self._av_sink = None
        self._av_widget = None

    @property
    def widget(self):
        return self._ui.video_preview_box

    @property
    def is_active(self):
        return self._active

    def toggle_preview(self, value):
        self._active = value
        if value:
            return self._enable_preview()
        return self._disable_preview()

    def _enable_preview(self):
        src_name = app.settings.get('video_input_device')
        try:
            self._av_src = Gst.parse_bin_from_description(src_name, True)
        except GLib.Error as error:
            log.error(error)
            log.error('Failed to parse "%s" as Gstreamer element', src_name)
            self._set_error_text()
            return

        sink, widget, name = gstreamer.create_gtk_widget()
        if sink is None:
            log.error('Failed to obtain a working Gstreamer GTK+ sink, '
                      'video support will be disabled')
            self._set_error_text()
            return

        self._set_sink_text(name)

        if self._av_pipeline is None:
            self._av_pipeline = Gst.Pipeline.new('preferences-pipeline')
        else:
            self._av_pipeline.set_state(Gst.State.NULL)

        self._av_pipeline.add(sink)
        self._av_sink = sink

        if self._av_widget is not None:
            self._ui.video_preview_box.remove(self._av_widget)

        self._ui.video_preview_placeholder.set_visible(False)
        self._ui.video_preview_box.pack_end(widget, True, True, 0)
        self._av_widget = widget

        self._av_pipeline.add(self._av_src)
        self._av_src.link(self._av_sink)
        self._av_pipeline.set_state(Gst.State.PLAYING)

    def _disable_preview(self):
        if self._av_pipeline is not None:
            self._av_pipeline.set_state(Gst.State.NULL)
            if self._av_src is not None:
                self._av_pipeline.remove(self._av_src)
            if self._av_sink is not None:
                self._av_pipeline.remove(self._av_sink)

        self._av_src = None
        self._av_sink = None

        if self._av_widget is not None:
            self._ui.video_preview_box.remove(self._av_widget)
            self._ui.video_preview_placeholder.set_visible(True)
            self._av_widget = None
        self._av_pipeline = None

    def _set_sink_text(self, sink_name):
        text = ''
        if sink_name == 'gtkglsink':
            text = _('<span color="green" font-weight="bold">'
                     'OpenGL</span> accelerated')

        elif sink_name == 'gtksink':
            text = _('<span color="yellow" font-weight="bold">'
                     'Not accelerated</span>')

        self._ui.video_source_label.set_markup(text)

    def _set_error_text(self):
        self._ui.video_source_label.set_text(
            _('Something went wrong. Video feature disabled.'))

    def refresh(self):
        self.toggle_preview(False)
        self.toggle_preview(True)
